001// --- BEGIN LICENSE BLOCK ---
002/* 
003 * Copyright (c) 2009, Mikio L. Braun
004 * All rights reserved.
005 * 
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are
008 * met:
009 * 
010 *     * Redistributions of source code must retain the above copyright
011 *       notice, this list of conditions and the following disclaimer.
012 * 
013 *     * Redistributions in binary form must reproduce the above
014 *       copyright notice, this list of conditions and the following
015 *       disclaimer in the documentation and/or other materials provided
016 *       with the distribution.
017 * 
018 *     * Neither the name of the Technische Universität Berlin nor the
019 *       names of its contributors may be used to endorse or promote
020 *       products derived from this software without specific prior
021 *       written permission.
022 * 
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034 */
035// --- END LICENSE BLOCK ---
036
037package org.jblas;
038
039import org.jblas.exceptions.SizeException;
040
041import java.io.DataInputStream;
042import java.io.DataOutputStream;
043import java.io.FileInputStream;
044import java.io.FileOutputStream;
045import java.io.IOException;
046import java.util.Arrays;
047
048public class ComplexFloatMatrix {
049        
050        public int rows;
051        public int columns;
052        public int length;
053        public float[] data = null; // rows are contiguous
054
055        /**************************************************************************
056         * 
057         * Constructors and factory functions
058         * 
059         **************************************************************************/
060
061        /**
062   * Create a new matrix with <i>newRows</i> rows, <i>newColumns</i> columns
063         * using <i>newData></i> as the data.
064         */
065        public ComplexFloatMatrix(int newRows, int newColumns, float... newData) {
066                rows = newRows;
067                columns = newColumns;
068                length = rows * columns;
069
070    if (newData.length != 2 * newRows * newColumns)
071                        throw new IllegalArgumentException(
072                                        "Passed data must match matrix dimensions.");
073                data = newData;
074        }
075        
076        /**
077         * Creates a new <i>n</i> times <i>m</i> <tt>ComplexFloatMatrix</tt>.
078         * @param newRows the number of rows (<i>n</i>) of the new matrix.
079         * @param newColumns the number of columns (<i>m</i>) of the new matrix.
080         */
081        public ComplexFloatMatrix(int newRows, int newColumns) {
082                this(newRows, newColumns, new float[2 * newRows * newColumns]);
083        }
084        
085        /**
086         * Creates a new <tt>ComplexFloatMatrix</tt> of size 0 times 0.
087         */
088        public ComplexFloatMatrix() {
089                this(0, 0, null);
090        }
091
092        /**
093         * Create a Matrix of length <tt>len</tt>. By default, this creates a row vector.
094         * @param len
095         */
096        public ComplexFloatMatrix(int len) {
097                this(len, 1, new float[2 * len]);
098        }
099        
100        public ComplexFloatMatrix(float[] newData) {
101                this(newData.length/2, 1, newData);
102        }
103
104        public ComplexFloatMatrix(ComplexFloat[] newData) {
105                this(newData.length);
106                                
107                for (int i = 0; i < newData.length; i++)
108                        put(i, newData[i]);
109        }
110                
111        
112  /** Construct a complex matrix from a real matrix. */
113  public ComplexFloatMatrix(FloatMatrix m) {
114    this(m.rows, m.columns);
115
116    NativeBlas.scopy(m.length, m.data, 0, 1, data, 0, 2);
117  }
118
119  /** Construct a complex matrix from separate real and imaginary parts. Either
120   * part can be set to null in which case it will be ignored.
121   */
122  public ComplexFloatMatrix(FloatMatrix real, FloatMatrix imag) {
123      this(real.rows, real.columns);
124      real.assertSameSize(imag);
125
126      if (real != null)
127          NativeBlas.scopy(length, real.data, 0, 1, data, 0, 2);
128      if (imag != null)
129          NativeBlas.scopy(length, imag.data, 0, 1, data, 1, 2);
130  }
131        
132        /**
133         * Creates a new matrix by reading it from a file.
134         * @param filename the path and name of the file to read the matrix from
135         * @throws IOException 
136         */
137        public ComplexFloatMatrix(String filename) throws IOException {
138                load(filename);
139        }
140        
141        /**
142         * Creates a new <i>n</i> times <i>m</i> <tt>ComplexFloatMatrix</tt> from
143         * the given <i>n</i> times <i>m</i> 2D data array. The first dimension of the array makes the
144         * rows (<i>n</i>) and the second dimension the columns (<i>m</i>). For example, the
145         * given code <br/><br/>
146         * <code>new ComplexFloatMatrix(new float[][]{{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}).print();</code><br/><br/>
147         * will constructs the following matrix:
148         * <pre>
149         * 1.0f 2.0f    3.0f
150         * 4.0f 5.0f    6.0f
151         * 7.0f 8.0f    9.0f
152         * </pre>.
153         * @param data <i>n</i> times <i>m</i> data array
154         */ 
155        public ComplexFloatMatrix(float[][] data) {
156                this(data.length, data[0].length);
157                                                
158                for (int r = 0; r < rows; r++)
159                        assert(data[r].length == columns);
160                
161                for (int r = 0; r < rows; r++)
162                        for (int c = 0; c < columns; c++)
163                                put(r, c, data[r][c]);
164        }
165        
166        /**
167         * Creates a new matrix in which all values are equal 0.
168         * @param rows number of rows
169         * @param columns number of columns
170         * @return new matrix
171         */
172        public static ComplexFloatMatrix zeros(int rows, int columns) {
173                return new ComplexFloatMatrix(rows, columns);
174        }
175        
176        public static ComplexFloatMatrix zeros(int length) {
177                return zeros(length, 1);
178        }
179
180        /**
181         * Creates a new matrix in which all values are equal 1.
182         * @param rows number of rows
183         * @param columns number of columns
184         * @return new matrix
185         */
186        public static ComplexFloatMatrix ones(int rows, int columns) {
187                ComplexFloatMatrix m = new ComplexFloatMatrix(rows, columns);
188                
189                for (int i = 0; i < rows * columns; i++)
190                        m.put(i, 1.0f);
191                
192                return m;
193        }
194        
195        public static ComplexFloatMatrix ones(int length) {
196                return ones(length, 1);
197        }
198        
199        /**
200         * Creates a new matrix where the values of the given vector are the diagonal values of
201         * the matrix.
202         * @param x the diagonal values
203         * @return new matrix
204         */
205        public static ComplexFloatMatrix diag(ComplexFloatMatrix x) {
206                ComplexFloatMatrix m = new ComplexFloatMatrix(x.length, x.length);
207                
208                for (int i = 0; i < x.length; i++)
209                        m.put(i, i, x.get(i));
210                
211                return m;
212        }
213
214  /**
215   * Construct a matrix of arbitrary shape and set the diagonal according
216   * to a passed vector.
217   *
218   * length of needs to be smaller than rows or columns.
219   *
220   * @param x vector to fill the diagonal with
221   * @param rows number of rows of the resulting matrix
222   * @param columns number of columns of the resulting matrix
223   * @return a matrix with dimensions rows * columns whose diagonal elements are filled by x
224   */
225  public static ComplexFloatMatrix diag(ComplexFloatMatrix x, int rows, int columns) {
226    if (x.length > rows || x.length > columns) {
227      throw new SizeException("Length of diagonal matrix must be larger than both rows and columns.");
228    }
229    
230    ComplexFloatMatrix m = new ComplexFloatMatrix(rows, columns);
231
232    for (int i = 0; i < x.length; i++)
233      m.put(i, i, x.get(i));
234
235    return m;
236  }
237        
238        /**
239         * Create a 1 * 1 - matrix. For many operations, this matrix functions like a
240         * normal float
241         * @param s value of the matrix
242         * @return the constructed ComplexFloatMatrix 
243         */
244        public static ComplexFloatMatrix scalar(float s) {
245                ComplexFloatMatrix m = new ComplexFloatMatrix(1, 1);
246                m.put(0, 0, s);
247                return m;
248        }
249        
250        /** Test whether a matrix is scalar */
251        public boolean isScalar() {
252                return length == 1;
253        }
254        
255        /** Return the first element of the matrix */
256        public ComplexFloat scalar() {
257                return get(0);
258        }
259        
260        public static ComplexFloatMatrix concatHorizontally(ComplexFloatMatrix A, ComplexFloatMatrix B) {
261                if (A.rows != B.rows)
262                        throw new SizeException("Matrices don't have same number of rows.");
263                
264                ComplexFloatMatrix result = new ComplexFloatMatrix(A.rows, A.columns + B.columns);
265                SimpleBlas.copy(A, result);
266                NativeBlas.ccopy(B.length, B.data, 0, 1, result.data, A.length, 1);
267                return result;
268        }
269
270        public static ComplexFloatMatrix concatVertically(ComplexFloatMatrix A, ComplexFloatMatrix B) {
271                if (A.columns != B.columns)
272                        throw new SizeException("Matrices don't have same number of columns.");
273                
274                ComplexFloatMatrix result = new ComplexFloatMatrix(A.rows + B.rows, A.columns);
275
276                for (int i = 0; i < A.columns; i++) {
277                        NativeBlas.ccopy(A.rows, A.data, A.index(0, i), 1, result.data, result.index(0, i), 1);
278                        NativeBlas.ccopy(B.rows, B.data, B.index(0, i), 1, result.data, result.index(A.rows, i), 1);
279                }
280                
281                return result;
282        }
283        
284        /**************************************************************************
285         * Working with slices (Man! 30+ methods just to make this a bit flexible...) 
286         */
287
288        public ComplexFloatMatrix get(int[] indices) {
289                ComplexFloatMatrix result = new ComplexFloatMatrix(indices.length);
290                
291                for (int i = 0; i < indices.length; i++)
292                        result.put(i, get(indices[i]));
293                
294                return result;
295        }
296        
297        public ComplexFloatMatrix get(int r, int[] indices) {
298                ComplexFloatMatrix result = new ComplexFloatMatrix(1, indices.length);
299                
300                for (int i = 0; i < indices.length; i++)
301                        result.put(i, get(r, indices[i]));
302                
303                return result;
304        }
305        
306        public ComplexFloatMatrix get(int[] indices, int c) {
307                ComplexFloatMatrix result = new ComplexFloatMatrix(indices.length, 1);
308                
309                for (int i = 0; i < indices.length; i++)
310                        result.put(i, get(indices[i], c));
311                
312                return result;
313        }
314        
315        public ComplexFloatMatrix get(int[] rindices, int[] cindices) {
316                ComplexFloatMatrix result = new ComplexFloatMatrix(rindices.length, cindices.length);
317                
318                for (int i = 0; i < rindices.length; i++)
319                        for (int j = 0; j < cindices.length; j++)
320                                result.put(i, j, get(rindices[i], cindices[j]));
321                
322                return result;
323        }
324        
325        public ComplexFloatMatrix get(ComplexFloatMatrix indices) {
326                return get(indices.findIndices());
327        }
328
329        public ComplexFloatMatrix get(int r, ComplexFloatMatrix indices) {
330                return get(r, indices.findIndices());
331        }
332        
333        public ComplexFloatMatrix get(ComplexFloatMatrix indices, int c) {
334                return get(indices.findIndices(), c);
335        }
336
337        public ComplexFloatMatrix get(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices) {
338                return get(rindices.findIndices(), cindices.findIndices());
339        }
340        
341        private void checkLength(int l) {
342                if (length != l)
343                        throw new SizeException("Matrix does not have the necessary length (" + length + " != " + l + ").");
344        }
345
346        private void checkRows(int r) {
347                if (rows != r)
348                        throw new SizeException("Matrix does not have the necessary length (" + length + " != " + r + ").");
349        }
350        
351        private void checkColumns(int c) {
352                if (columns != c)
353                        throw new SizeException("Matrix does not have the necessary length (" + length + " != " + c + ").");
354        }
355
356        public ComplexFloatMatrix put(int[] indices, ComplexFloatMatrix x) {
357                if (x.isScalar())
358                        return put(indices, x.scalar());
359                x.checkLength(indices.length);
360                
361                for (int i = 0; i < indices.length; i++)
362                        put(indices[i], x.get(i));
363                
364                return this;
365        }
366        
367        public ComplexFloatMatrix put(int r, int[] indices, ComplexFloatMatrix x) {
368                if (x.isScalar())
369                        return put(r, indices, x.scalar());
370                x.checkColumns(indices.length);
371                
372                for (int i = 0; i < indices.length; i++)
373                        put(r, indices[i], x.get(i));
374                
375                return this;
376        }
377        
378        public ComplexFloatMatrix put(int[] indices, int c, ComplexFloatMatrix x) {
379                if (x.isScalar())
380                        return put(indices, c, x.scalar());             
381                x.checkRows(indices.length);
382                
383                for (int i = 0; i < indices.length; i++)
384                        put(indices[i], c, x.get(i));
385                
386                return this;
387        }
388        
389        public ComplexFloatMatrix put(int[] rindices, int[] cindices, ComplexFloatMatrix x) {
390                if (x.isScalar())
391                        return put(rindices, cindices, x.scalar());             
392                x.checkRows(rindices.length);
393                x.checkColumns(cindices.length);
394                
395                for (int i = 0; i < rindices.length; i++)
396                        for (int j = 0; j < cindices.length; j++)
397                                put(rindices[i], cindices[j], x.get(i,j));
398                
399                return this;
400        }
401        
402        public ComplexFloatMatrix put(int[] indices, float v) {
403                for (int i = 0; i < indices.length; i++)
404                        put(indices[i], v);
405                
406                return this;
407        }
408
409        public ComplexFloatMatrix putReal(int[] indices, float v) {
410                return put(indices, v);
411        }
412
413        public ComplexFloatMatrix putImag(int[] indices, float v) {
414                for (int i = 0; i < indices.length; i++)
415                        putImag(indices[i], v);
416                
417                return this;
418        }
419
420        public ComplexFloatMatrix put(int[] indices, ComplexFloat v) {
421                for (int i = 0; i < indices.length; i++)
422                        put(indices[i], v);
423                
424                return this;
425        }
426
427        public ComplexFloatMatrix put(int r, int[] indices, float v) {
428                for (int i = 0; i < indices.length; i++)
429                        put(r, indices[i], v);
430                
431                return this;
432        }
433
434        public ComplexFloatMatrix putReal(int r, int[] indices, float v) {
435                return put(r, indices, v);
436        }
437
438        public ComplexFloatMatrix putImag(int r, int[] indices, float v) {
439                for (int i = 0; i < indices.length; i++)
440                        putImag(r, indices[i], v);
441                
442                return this;
443        }
444
445        public ComplexFloatMatrix put(int r, int[] indices, ComplexFloat v) {
446                for (int i = 0; i < indices.length; i++)
447                        put(r, indices[i], v);
448                
449                return this;
450        }
451
452        public ComplexFloatMatrix put(int[] indices, int c, float v) {
453                for (int i = 0; i < indices.length; i++)
454                        put(indices[i], c, v);
455                
456                return this;
457        }
458        
459        public ComplexFloatMatrix putReal(int[] indices, int c, float v) {
460                return put(indices, c, v);
461        }
462        
463        public ComplexFloatMatrix putImag(int[] indices, int c, float v) {
464                for (int i = 0; i < indices.length; i++)
465                        putImag(indices[i], c, v);
466                
467                return this;
468        }
469        
470        public ComplexFloatMatrix put(int[] indices, int c, ComplexFloat v) {
471                for (int i = 0; i < indices.length; i++)
472                        put(indices[i], c, v);
473                
474                return this;
475        }
476        
477        public ComplexFloatMatrix put(int[] rindices, int[] cindices, float v) {
478                for (int i = 0; i < rindices.length; i++)
479                        for (int j = 0; j < cindices.length; j++)
480                                put(rindices[i], cindices[j], v);
481                
482                return this;
483        }
484        
485        public ComplexFloatMatrix putReal(int[] rindices, int[] cindices, float v) {
486                return put(rindices, cindices, v);
487        }
488        
489        public ComplexFloatMatrix putImag(int[] rindices, int[] cindices, float v) {
490                for (int i = 0; i < rindices.length; i++)
491                        for (int j = 0; j < cindices.length; j++)
492                                put(rindices[i], cindices[j], v);
493                
494                return this;
495        }
496
497        public ComplexFloatMatrix put(int[] rindices, int[] cindices, ComplexFloat v) {
498                for (int i = 0; i < rindices.length; i++)
499                        for (int j = 0; j < cindices.length; j++)
500                                put(rindices[i], cindices[j], v);
501                
502                return this;
503        }
504
505        public ComplexFloatMatrix put(ComplexFloatMatrix indices, ComplexFloatMatrix v) {
506                return put(indices.findIndices(), v);
507        }
508
509        public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, ComplexFloatMatrix v) {
510                return put(r, indices.findIndices(), v);
511        }
512        
513        public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, ComplexFloatMatrix v) {
514                return put(indices.findIndices(), c, v);
515        }
516
517        public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, ComplexFloatMatrix v) {
518                return put(rindices.findIndices(), cindices.findIndices(), v);
519        }
520
521        public ComplexFloatMatrix put(ComplexFloatMatrix indices, float v) {
522                return put(indices.findIndices(), v);
523        }
524
525        public ComplexFloatMatrix putReal(ComplexFloatMatrix indices, float v) {
526                return put(indices, v);
527        }
528
529        public ComplexFloatMatrix putImag(ComplexFloatMatrix indices, float v) {
530                return putImag(indices.findIndices(), v);
531        }
532
533        public ComplexFloatMatrix put(ComplexFloatMatrix indices, ComplexFloat v) {
534                return put(indices.findIndices(), v);
535        }
536        
537        public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, float v) {
538                return put(r, indices.findIndices(), v);
539        }
540        
541        public ComplexFloatMatrix putReal(int r, ComplexFloatMatrix indices, float v) {
542                return put(r, indices, v);
543        }
544
545        public ComplexFloatMatrix putImag(int r, ComplexFloatMatrix indices, float v) {
546                return putImag(r, indices.findIndices(), v);
547        }
548
549        public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, ComplexFloat v) {
550                return put(r, indices.findIndices(), v);
551        }
552
553        public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, float v) {
554                return put(indices.findIndices(), c, v);
555        }
556
557        public ComplexFloatMatrix putReal(ComplexFloatMatrix indices, int c, float v) {
558                return put(indices, c, v);
559        }
560
561        public ComplexFloatMatrix putImag(ComplexFloatMatrix indices, int c, float v) {
562                return putImag(indices.findIndices(), c, v);
563        }
564
565        public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, ComplexFloat v) {
566                return put(indices.findIndices(), c, v);
567        }
568
569        public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
570                return put(rindices.findIndices(), cindices.findIndices(), v);
571        }
572
573        public ComplexFloatMatrix putReal(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
574                return putReal(rindices.findIndices(), cindices.findIndices(), v);
575        }
576
577        public ComplexFloatMatrix putImag(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
578                return putImag(rindices.findIndices(), cindices.findIndices(), v);
579        }
580
581        public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, ComplexFloat v) {
582                return put(rindices.findIndices(), cindices.findIndices(), v);
583        }
584
585        
586        public int[] findIndices() {
587                int len = 0;
588                for (int i = 0; i < length; i++)
589                        if (!get(i).isZero())
590                                len++;
591                
592                int[] indices = new int[len];
593                int c = 0;
594                
595                for (int i = 0; i < length; i++)
596                        if (!get(i).isZero())
597                                indices[c++] = i;
598                
599                return indices;
600        }
601        
602        /**************************************************************************
603         * Basic operations (copying, resizing, element access)
604         */
605        
606        /** Return transposed copy of this matrix */
607        public ComplexFloatMatrix transpose() {
608                ComplexFloatMatrix result = new ComplexFloatMatrix(columns, rows);
609
610                ComplexFloat c = new ComplexFloat(0);
611
612                for (int i = 0; i < rows; i++)
613                        for (int j = 0; j < columns; j++)
614                                result.put(j, i, get(i, j, c));
615                
616                return result;
617        }
618
619        public ComplexFloatMatrix hermitian() {
620            ComplexFloatMatrix result = new ComplexFloatMatrix(columns, rows);
621
622            ComplexFloat c = new ComplexFloat(0);
623
624            for (int i = 0; i < rows; i++)
625                for (int j = 0; j < columns; j++)
626                    result.put(j, i, get(i, j, c).conji());
627            return result;
628        }
629
630        /**
631         * Compute complex conjugate (in-place).
632         */
633        public ComplexFloatMatrix conji() {
634            ComplexFloat c = new ComplexFloat(0.0f);
635            for (int i = 0; i < length; i++)
636                put(i, get(i, c).conji());
637            return this;
638        }
639
640        /**
641         * Compute complex conjugate.
642         */
643        public ComplexFloatMatrix conj() {
644            return dup().conji();
645        }
646
647                
648        /** Compare two matrices.
649         * @param o Object to compare to
650         * @return true if and only if other is also a ComplexFloatMatrix which has the same size and the
651         * maximal absolute difference in matrix elements is smaller thatn 1e-6.  */
652        public boolean equals(Object o) {
653                if (!(o instanceof ComplexFloatMatrix))
654                        return false;
655
656                ComplexFloatMatrix other = (ComplexFloatMatrix) o;
657
658                if (!sameSize(other))
659                        return false;
660
661    return Arrays.equals(data, other.data);
662        }
663  
664  public int hashCode() {
665    return rows ^ columns ^ Arrays.hashCode(data);
666  }
667
668        
669        /** Resize the matrix. All elements will be set to zero. */
670        public void resize(int newRows, int newColumns) {
671                rows = newRows;
672                columns = newColumns;
673                length = newRows * newColumns;
674                data = new float[2 * rows * columns];
675        }
676
677        
678        /** Reshape the matrix. Number of elements must not change. */
679        public ComplexFloatMatrix reshape(int newRows, int newColumns) {
680                if (length != newRows * newColumns)
681                        throw new IllegalArgumentException(
682                                        "Number of elements must not change.");
683
684                rows = newRows;
685                columns = newColumns;
686                
687                return this;
688        }
689
690        /** Checks whether two matrices have the same size. */
691        public boolean sameSize(ComplexFloatMatrix a) {
692                return rows == a.rows && columns == a.columns;
693        }
694
695        /** 
696         * Assert that two matrices have the same size.
697         * 
698         * @param a the other matrix
699         * @throws SizeException if matrix sizes don't match. 
700         * */
701        public void assertSameSize(ComplexFloatMatrix a) {
702                if (!sameSize(a))
703                        throw new SizeException("Matrices must have the same size.");
704        }
705        
706        /** 
707         * Check whether this can be multiplied with a. 
708         * 
709         * @param a right-hand-side of the multiplication.
710         * @return true iff <tt>this.columns == a.rows</tt>
711         */
712        public boolean multipliesWith(ComplexFloatMatrix a) {
713                return columns == a.rows;
714        }
715        
716        public void assertMultipliesWith(ComplexFloatMatrix a) {
717                if (!multipliesWith(a))
718                        throw new SizeException("Number of columns of left matrix must be equal to number of rows of right matrix.");
719        }
720        
721        public boolean sameLength(ComplexFloatMatrix a) {
722                return length == a.length;
723        }
724        
725        public void assertSameLength(ComplexFloatMatrix a) {
726                if (!sameLength(a))
727                        throw new SizeException("Matrices must have same length (is: " + length + " and " + a.length + ")");
728        }
729        
730        /** Copy ComplexFloatMatrix a to this. this a is resized if necessary. */
731        public ComplexFloatMatrix copy(ComplexFloatMatrix a) {
732                if (!sameSize(a))
733                        resize(a.rows, a.columns);
734                
735                SimpleBlas.copy(a, this);
736                return a;
737        }
738        
739        /** Returns a duplicate of this matrix. Geometry is the same (including offsets, transpose, etc.),
740         * but the buffer is not shared.
741         */
742        public ComplexFloatMatrix dup() {
743                ComplexFloatMatrix out = new ComplexFloatMatrix(rows, columns);
744
745                JavaBlas.rcopy(2*length, data, 0, 1, out.data, 0, 1);
746                
747                return out;
748        }
749        
750        public ComplexFloatMatrix swapColumns(int i, int j) {
751                NativeBlas.cswap(rows, data, index(0, i), 1, data, index(0, j), 1);
752                return this;
753        }
754        
755        public ComplexFloatMatrix swapRows(int i, int j) {
756                NativeBlas.cswap(columns, data, index(i, 0), rows, data, index(j, 0), rows);
757                return this;
758        }
759                
760        /** Set matrix element */
761        public ComplexFloatMatrix put(int rowIndex, int columnIndex, float value) {
762                data[2*index(rowIndex, columnIndex)] =  value;
763                return this;
764        }
765
766        public ComplexFloatMatrix put(int rowIndex, int columnIndex, float realValue, float complexValue) {
767                data[2*index(rowIndex, columnIndex)] =  realValue;
768                data[2*index(rowIndex, columnIndex)+1] =  complexValue;
769                return this;
770        }
771
772        public ComplexFloatMatrix put(int rowIndex, int columnIndex, ComplexFloat value) {
773                int i = 2*index(rowIndex, columnIndex);
774                data[i] = value.real(); data[i+1] = value.imag();
775                return this;
776        }
777
778        public ComplexFloatMatrix putReal(int rowIndex, int columnIndex, float value) {
779                data[2*index(rowIndex, columnIndex)] = value;
780                return this;
781        }
782
783        public ComplexFloatMatrix putImag(int rowIndex, int columnIndex, float value) {
784                data[2*index(rowIndex, columnIndex)+1] = value;
785                return this;
786        }
787        
788        /** Retrieve matrix element */
789        public ComplexFloat get(int rowIndex, int columnIndex) {
790            int i = 2*index(rowIndex, columnIndex);
791            return new ComplexFloat(data[i], data[i+1]);
792        }
793
794        /** Get matrix element, passing the variable to store the result. */
795        public ComplexFloat get(int rowIndex, int columnIndex, ComplexFloat result) {
796            return get(index(rowIndex, columnIndex), result);
797        }
798        
799        public FloatMatrix getReal() {
800                FloatMatrix result = new FloatMatrix(rows, columns);
801                
802                NativeBlas.scopy(length, data, 0, 2, result.data, 0, 1);
803                
804                return result;
805        }
806
807        /** Get index of an element */
808        public int index(int rowIndex, int columnIndex) {
809                return rows * columnIndex + rowIndex;
810        }
811
812  /** Compute the row index of a linear index. */
813  public int indexRows(int i) {
814    return i - indexColumns(i) * rows;
815  }
816
817  /** Compute the column index of a linear index. */
818  public int indexColumns(int i) {
819    return i / rows;
820  }
821
822
823        public ComplexFloat get(int i) {
824                return new ComplexFloat(data[i * 2], data[i * 2 + 1]);
825        }
826        
827        public ComplexFloat get(int i, ComplexFloat result) {
828            return result.set(data[i * 2], data[i*2+1]);
829        }
830        
831        public float getReal(int i) {
832                return data[2*i];
833        }
834        
835        public float getImag(int i) {
836                return data[2*i + 1]; 
837        }
838
839        public ComplexFloatMatrix put(int i, float v) {
840                data[2*i] = v;
841                return this;
842        }
843
844        public ComplexFloatMatrix put(int i, float r, float c) {
845            data[2*i] = r;
846            data[2*i+1] = c;
847            return this;
848        }
849        
850        public ComplexFloatMatrix put(int i, ComplexFloat v) {
851                data[2*i] = v.real();
852                data[2*i+1] = v.imag();
853                return this;
854        }
855        
856        public ComplexFloatMatrix putReal(int i, float v) {
857                return put(i, v);
858        }
859        
860        public ComplexFloatMatrix putImag(int i, float v) {
861                data[2*i+1] = v;
862                return this;
863        }
864
865        public int getRows() {
866                return rows;
867        }
868        
869        public int getColumns() {
870                return columns;
871        }
872        
873        public int getLength() {
874                return length;
875        }
876        
877        /** Checks whether the matrix is empty. */
878        public boolean isEmpty() {
879                return columns == 0 || rows == 0;
880        }
881        
882        /** Checks whether the matrix is square. */
883        public boolean isSquare() {
884                return columns == rows;
885        }
886        
887        public void assertSquare() {
888                if (!isSquare())
889                        throw new SizeException("Matrix must be square!");
890        }
891        
892        /** Checks whether the matrix is a vector. */
893        public boolean isVector() {
894                return columns == 1 || rows == 1;
895        }
896        
897        public boolean isRowVector() {
898                return columns == 1;
899        }
900        
901        public boolean isColumnVector() {
902                return rows == 1;
903        }
904                
905        /** Get diagonal of the matrix. */
906        public ComplexFloatMatrix diag() {
907                ComplexFloatMatrix d = new ComplexFloatMatrix(rows);
908                NativeBlas.ccopy(rows, data, 0, rows + 1, d.data, 0, 1);
909                return d;
910        }
911        
912        /** Get real part of the matrix. */
913        public FloatMatrix real() {
914            FloatMatrix result = new FloatMatrix(rows, columns);
915            NativeBlas.scopy(length, data, 0, 2, result.data, 0, 1);
916            return result;
917        }
918        
919        /** Get imaginary part of the matrix. */
920        public FloatMatrix imag() {
921            FloatMatrix result = new FloatMatrix(rows, columns);
922            NativeBlas.scopy(length, data, 1, 2, result.data, 0, 1);
923            return result;            
924        }
925
926        
927        /** 
928         * Pretty-print this matrix to <tt>System.out</tt>. 
929         * */
930        public void print() {
931                System.out.println(toString());
932        }
933
934        /** 
935         * Generate string representation of this matrix 
936         * (multi-line).
937         * */
938        public String toString() {
939                StringBuilder s = new StringBuilder();
940
941                s.append("[");
942                
943                for (int i = 0; i < rows; i++) {
944                        for (int j = 0; j < columns; j++) {
945                                s.append(get(i, j));
946                                if (j < columns - 1)
947                                        s.append(", ");
948                        }
949                        if (i < rows - 1)
950                                s.append("; ");
951                }
952
953                s.append("]");
954                
955                return s.toString();
956        }
957
958        public float[] toDoubleArray() {
959                return data.clone();
960        }
961        
962        public ComplexFloat[] toArray() {
963                ComplexFloat[] array = new ComplexFloat[length];
964                
965                for (int i = 0; i < length; i++)
966                        array[i] = get(i);
967                
968                return array;           
969        }
970        
971        public ComplexFloat[][] toArray2() {
972                ComplexFloat[][] array = new ComplexFloat[rows][columns];
973                
974                for (int r = 0; r < rows; r++)
975                        for (int c = 0; c < columns; c++)
976                                array[r][c] = get(r, c);
977                                
978                return array;
979        }
980        
981        public boolean[] toBooleanArray() {
982                boolean[] array = new boolean[length];
983                
984                for (int i = 0; i < length; i++)
985                        array[i] = !get(i).isZero();
986                
987                return array;
988        }
989        
990        public boolean[][] toBooleanArray2() {
991                boolean[][] array = new boolean[rows][columns];
992                
993                for (int r = 0; r < rows; r++)
994                        for (int c = 0; c < columns; c++)
995                                array[r][c] = !get(r, c).isZero();
996                                
997                return array;
998        }
999
1000        /**************************************************************************
1001         * Arithmetic Operations
1002         */
1003
1004        /** 
1005         * Ensures that the result vector has the same length as this. If not,
1006         * resizing result is tried, which fails if result == this or result == other.
1007         */
1008        private void ensureResultLength(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1009                if (!sameLength(result)) {
1010                        if (result == this || result == other)
1011                                throw new SizeException("Cannot resize result matrix because it is used in-place.");
1012                        result.resize(rows, columns);
1013                }
1014        }
1015
1016        /** Add two matrices. */
1017        public ComplexFloatMatrix addi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1018                if (other.isScalar())
1019                        return addi(other.scalar(), result);
1020                
1021                assertSameLength(other);
1022                ensureResultLength(other, result);
1023                
1024                if (result == this)
1025                        SimpleBlas.axpy(ComplexFloat.UNIT, other, result);
1026                else if (result == other)
1027                        SimpleBlas.axpy(ComplexFloat.UNIT, this, result);
1028                else {
1029                        SimpleBlas.copy(this, result);
1030                        SimpleBlas.axpy(ComplexFloat.UNIT, other, result);
1031                }
1032
1033                return result;
1034        }
1035        
1036        /** Add a scalar to a matrix. */
1037        public ComplexFloatMatrix addi(ComplexFloat v, ComplexFloatMatrix result) {
1038                ensureResultLength(null, result);
1039                
1040                for (int i = 0; i < length; i++)
1041                        result.put(i, get(i).add(v));
1042                return result;
1043        }
1044        
1045        public ComplexFloatMatrix addi(float v, ComplexFloatMatrix result) {
1046                return addi(new ComplexFloat(v), result);
1047        }
1048
1049        /** Subtract two matrices. */
1050        public ComplexFloatMatrix subi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1051                if (other.isScalar())
1052                        return subi(other.scalar(), result);
1053                
1054                assertSameLength(other);
1055                ensureResultLength(other, result);
1056                
1057                if (result == this)
1058                        SimpleBlas.axpy(ComplexFloat.NEG_UNIT, other, result);
1059                else if (result == other) {
1060                        SimpleBlas.scal(ComplexFloat.NEG_UNIT, result);
1061                        SimpleBlas.axpy(ComplexFloat.UNIT, this, result);
1062                }
1063                else {
1064                        SimpleBlas.copy(this, result);
1065                        SimpleBlas.axpy(ComplexFloat.NEG_UNIT, other, result);
1066                }
1067                return result;
1068        }
1069        
1070        /** Subtract a scalar from a matrix */
1071        public ComplexFloatMatrix subi(ComplexFloat v, ComplexFloatMatrix result) {
1072                ensureResultLength(null, result);
1073                
1074                for (int i = 0; i < length; i++)
1075                        result.put(i, get(i).sub(v));
1076                return result;
1077        }
1078        
1079        public ComplexFloatMatrix subi(float v, ComplexFloatMatrix result) {
1080                return subi(new ComplexFloat(v), result);
1081        }
1082
1083        /** 
1084         * Subtract two matrices, but subtract first from second matrix, that is, 
1085         * compute <em>result = other - this</em>. 
1086         * */
1087        public ComplexFloatMatrix rsubi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1088                return other.subi(this, result);
1089        }
1090        
1091        /** Subtract a matrix from a scalar */
1092        public ComplexFloatMatrix rsubi(ComplexFloat a, ComplexFloatMatrix result) {
1093                ensureResultLength(null, result);
1094                
1095                for (int i = 0; i < length; i++)
1096                        result.put(i, a.sub(get(i)));
1097                return result;
1098        }
1099
1100        public ComplexFloatMatrix rsubi(float a, ComplexFloatMatrix result) {
1101                return rsubi(new ComplexFloat(a), result);
1102        }
1103
1104        /** (Elementwise) Multiplication */ 
1105        public ComplexFloatMatrix muli(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1106                if (other.isScalar())
1107                        return muli(other.scalar(), result);
1108                
1109                assertSameLength(other);
1110                ensureResultLength(other, result);
1111                
1112                ComplexFloat c = new ComplexFloat(0.0f);
1113                ComplexFloat d = new ComplexFloat(0.0f);
1114                
1115                for (int i = 0; i < length; i++)
1116                        result.put(i, get(i, c).muli(other.get(i, d)));
1117                return result;
1118        }
1119        
1120        /** (Elementwise) Multiplication with a scalar */
1121        public ComplexFloatMatrix muli(ComplexFloat v, ComplexFloatMatrix result) {
1122                ensureResultLength(null, result);
1123                
1124                ComplexFloat c = new ComplexFloat(0.0f);
1125                
1126                for (int i = 0; i < length; i++)
1127                        result.put(i, get(i, c).muli(v));
1128                return result;
1129        }
1130
1131        public ComplexFloatMatrix muli(float v, ComplexFloatMatrix result) {
1132                return muli(new ComplexFloat(v), result);
1133        }
1134
1135        /** Matrix-Matrix Multiplication */
1136        public ComplexFloatMatrix mmuli(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1137                if (other.isScalar())
1138                        return muli(other.scalar(), result);
1139
1140                /* check sizes and resize if necessary */
1141                assertMultipliesWith(other);
1142                if (result.rows != rows || result.columns != other.columns) {
1143                        if (result != this && result != other)
1144                                result.resize(rows, other.columns);
1145                        else
1146                                throw new SizeException("Cannot resize result matrix because it is used in-place.");
1147                }
1148                
1149                if (result == this || result == other) {
1150                        /* actually, blas cannot do multiplications in-place. Therefore, we will fake by
1151                         * allocating a temporary object on the side and copy the result later.
1152                         */
1153                        ComplexFloatMatrix temp = new ComplexFloatMatrix(result.rows, result.columns);
1154                        SimpleBlas.gemm(ComplexFloat.UNIT, this, other, ComplexFloat.ZERO, temp);
1155                        SimpleBlas.copy(temp, result);
1156                }
1157                else {
1158                        SimpleBlas.gemm(ComplexFloat.UNIT, this, other, ComplexFloat.ZERO, result);
1159                }               
1160                return result;
1161        }
1162        
1163        /** Matrix-Matrix Multiplication with a scalar (for symmetry, does the
1164         * same as muli(scalar)
1165         */
1166        public ComplexFloatMatrix mmuli(ComplexFloat v, ComplexFloatMatrix result) {
1167                return muli(v, result);
1168        }
1169
1170        public ComplexFloatMatrix mmuli(float v, ComplexFloatMatrix result) {
1171                return muli(v, result);
1172        }
1173        
1174        /** (Elementwise) division */
1175        public ComplexFloatMatrix divi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1176                if (other.isScalar())
1177                        return divi(other.scalar(), result);
1178                
1179                assertSameLength(other);
1180                ensureResultLength(other, result);
1181                
1182                ComplexFloat c1 = new ComplexFloat(0.0f);
1183                ComplexFloat c2 = new ComplexFloat(0.0f);
1184                
1185                for (int i = 0; i < length; i++)
1186                        result.put(i, get(i, c1).divi(other.get(i, c2)));
1187                return result;
1188        }
1189                
1190        /** (Elementwise) division with a scalar */
1191        public ComplexFloatMatrix divi(ComplexFloat a, ComplexFloatMatrix result) {
1192                ensureResultLength(null, result);
1193                
1194                ComplexFloat c = new ComplexFloat(0.0f);
1195                
1196                for (int i = 0; i < length; i++)
1197                        result.put(i, get(i, c).divi(a));
1198                return result;
1199        }       
1200
1201        public ComplexFloatMatrix divi(float a, ComplexFloatMatrix result) {
1202                return divi(new ComplexFloat(a), result);
1203        }
1204
1205        /** 
1206         * (Elementwise) division, with operands switched. Computes
1207         * <em>result = other / this</em>. */
1208        public ComplexFloatMatrix rdivi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1209                if (other.isScalar())
1210                        return divi(other.scalar(), result);
1211                
1212                assertSameLength(other);
1213                ensureResultLength(other, result);
1214
1215                ComplexFloat c1 = new ComplexFloat(0.0f);
1216                ComplexFloat c2 = new ComplexFloat(0.0f);
1217
1218                for (int i = 0; i < length; i++)
1219                        result.put(i, other.get(i, c1).divi(get(i, c2)));
1220                return result;
1221        }
1222                
1223        /** (Elementwise) division with a scalar, with operands switched. Computes
1224         * <em>result = a / this</em>.*/
1225        public ComplexFloatMatrix rdivi(ComplexFloat a, ComplexFloatMatrix result) {
1226                ensureResultLength(null, result);
1227
1228                ComplexFloat c1 = new ComplexFloat(0.0f);
1229                ComplexFloat c2 = new ComplexFloat(0.0f);
1230
1231                for (int i = 0; i < length; i++) {
1232                    c1.copy(a);
1233                    result.put(i, c1.divi(get(i, c2)));                    
1234                }
1235                return result;
1236        }
1237
1238        public ComplexFloatMatrix rdivi(float a, ComplexFloatMatrix result) {
1239                return rdivi(new ComplexFloat(a), result);
1240        }
1241        
1242        public ComplexFloatMatrix negi() {
1243                ComplexFloat c = new ComplexFloat(0.0f);
1244                for (int i = 0; i < length; i++)
1245                        put(i, get(i, c).negi());
1246                return this;
1247        }
1248        
1249        public ComplexFloatMatrix neg() {
1250                return dup().negi();
1251        }
1252
1253        public ComplexFloatMatrix noti() {
1254                ComplexFloat c = new ComplexFloat(0.0f);
1255                for (int i = 0; i < length; i++)
1256                        put(i, get(i, c).isZero() ? 1.0f : 0.0f);
1257                return this;
1258        }
1259        
1260        public ComplexFloatMatrix not() {
1261                return dup().noti();
1262        }
1263        
1264        public ComplexFloatMatrix truthi() {
1265                ComplexFloat c = new ComplexFloat(0.0f);
1266                for (int i = 0; i < length; i++)
1267                        put(i, get(i, c).isZero() ? 0.0f : 1.0f);
1268                return this;
1269        }
1270        
1271        public ComplexFloatMatrix truth() {
1272                return dup().truthi();
1273        }
1274
1275        /****************************************************************
1276         * Rank one-updates
1277         */
1278        
1279        /** Computes a rank-1-update A = A + alpha * x * y'. */ 
1280        public ComplexFloatMatrix rankOneUpdate(ComplexFloat alpha, ComplexFloatMatrix x, ComplexFloatMatrix y) {
1281                if (rows != x.length)
1282                        throw new SizeException("Vector x has wrong length (" + x.length + " != " + rows + ").");
1283                if (columns != y.length)
1284                        throw new SizeException("Vector y has wrong length (" + x.length + " != " + columns + ").");                    
1285                
1286                SimpleBlas.gerc(alpha, x, y, this);
1287                return this;
1288        }
1289
1290        public ComplexFloatMatrix rankOneUpdate(float alpha, ComplexFloatMatrix x, ComplexFloatMatrix y) {
1291                return rankOneUpdate(new ComplexFloat(alpha), x, y);
1292        }
1293
1294        /** Computes a rank-1-update A = A + alpha * x * x'. */ 
1295        public ComplexFloatMatrix rankOneUpdate(float alpha, ComplexFloatMatrix x) {
1296                return rankOneUpdate(new ComplexFloat(alpha), x, x);
1297        }
1298
1299        /** Computes a rank-1-update A = A + alpha * x * x'. */ 
1300        public ComplexFloatMatrix rankOneUpdate(ComplexFloat alpha, ComplexFloatMatrix x) {
1301                return rankOneUpdate(alpha, x, x);
1302        }
1303
1304        /** Computes a rank-1-update A = A + x * x'. */ 
1305        public ComplexFloatMatrix rankOneUpdate(ComplexFloatMatrix x) {
1306                return rankOneUpdate(1.0f, x, x);
1307        }
1308
1309        /** Computes a rank-1-update A = A + x * y'. */ 
1310        public ComplexFloatMatrix rankOneUpdate(ComplexFloatMatrix x, ComplexFloatMatrix y) {
1311                return rankOneUpdate(1.0f, x, y);
1312        }
1313
1314        /****************************************************************
1315         * Logical operations
1316         */
1317        
1318        public ComplexFloat sum() {
1319                ComplexFloat s = new ComplexFloat(0.0f);
1320                ComplexFloat c = new ComplexFloat(0.0f);
1321                for (int i = 0; i < length; i++)
1322                        s.addi(get(i, c));
1323                return s;
1324        }
1325        
1326        public ComplexFloat mean() {
1327                return sum().div((float)length);
1328        }
1329        
1330        /** Computes this^T * other */
1331        public ComplexFloat dotc(ComplexFloatMatrix other) {
1332                return SimpleBlas.dotc(this, other);
1333        }
1334        
1335        /** Computes this^H * other */
1336        public ComplexFloat dotu(ComplexFloatMatrix other) {
1337                return SimpleBlas.dotu(this, other);
1338        }
1339
1340        public float norm2() {
1341                return SimpleBlas.nrm2(this);
1342        }
1343        
1344        public float normmax() {
1345                int i = SimpleBlas.iamax(this);
1346                return get(i).abs();
1347        }
1348
1349        public float norm1() {
1350                return SimpleBlas.asum(this);
1351        }
1352                
1353        /** Return a vector containing the sums of the columns (having number of columns many entries) */
1354        public ComplexFloatMatrix columnSums() {
1355                ComplexFloatMatrix v =
1356                        new ComplexFloatMatrix(1, columns);
1357
1358                for (int c = 0; c < columns; c++)
1359                        v.put(c, getColumn(c).sum());
1360
1361                return v;
1362        }
1363
1364        public ComplexFloatMatrix columnMeans() {
1365                return columnSums().divi(rows);
1366        }
1367        
1368        public ComplexFloatMatrix rowSums() {
1369                ComplexFloatMatrix v = new ComplexFloatMatrix(rows);
1370
1371                for (int r = 0; r < rows; r++)
1372                        v.put(r, getRow(r).sum());
1373
1374                return v;
1375        }
1376
1377        public ComplexFloatMatrix rowMeans() {
1378                return rowSums().divi(columns);
1379        }
1380
1381        public ComplexFloatMatrix getColumn(int c) {
1382                ComplexFloatMatrix result = new ComplexFloatMatrix(rows, 1);
1383                NativeBlas.ccopy(rows, data, index(0, c), 1, result.data, 0, 1);
1384                return result;
1385        }
1386        
1387        public void putColumn(int c, ComplexFloatMatrix v) {
1388                NativeBlas.ccopy(rows, v.data, 0, 1, data, index(0, c), 1);
1389        }
1390
1391        public ComplexFloatMatrix getRow(int r) {
1392                ComplexFloatMatrix result = new ComplexFloatMatrix(1, columns);
1393                NativeBlas.ccopy(columns, data, index(r, 0), rows, result.data, 0, 1);
1394                return result;
1395        }
1396        
1397        public void putRow(int r, ComplexFloatMatrix v) {
1398                NativeBlas.ccopy(columns, v.data, 0, 1, data, index(r, 0), rows);
1399        }
1400
1401        /**************************************************************************
1402         * Elementwise Functions
1403         */
1404
1405        /** Add a row vector to all rows of the matrix */
1406        public void addRowVector(ComplexFloatMatrix x) {
1407                for (int r = 0; r < rows; r++) {
1408                        NativeBlas.caxpy(columns, ComplexFloat.UNIT, x.data, 0, 1, data, index(r, 0), rows);
1409                }
1410        }
1411
1412        /** Add a vector to all columns of the matrix */
1413        public void addColumnVector(ComplexFloatMatrix x) {
1414                for (int c = 0; c < columns; c++) {
1415                        NativeBlas.caxpy(rows, ComplexFloat.UNIT, x.data, 0, 1, data, index(0, c), 1);
1416                }
1417        }
1418
1419        /** Add a row vector to all rows of the matrix */
1420        public void subRowVector(ComplexFloatMatrix x) {
1421                for (int r = 0; r < rows; r++) {
1422                        NativeBlas.caxpy(columns, ComplexFloat.NEG_UNIT, x.data, 0, 1, data, index(r, 0), rows);
1423                }
1424        }
1425
1426        /** Add a vector to all columns of the matrix */
1427        public void subColumnVector(ComplexFloatMatrix x) {
1428                for (int c = 0; c < columns; c++) {
1429                        NativeBlas.caxpy(rows, ComplexFloat.NEG_UNIT, x.data, 0, 1, data, index(0, c), 1);
1430                }
1431        }
1432
1433        /**
1434         * Writes out this matrix to the given data stream.
1435         * @param dos the data output stream to write to.
1436         * @throws IOException 
1437         */
1438        public void out(DataOutputStream dos) throws IOException {
1439                dos.writeUTF("float");
1440                dos.writeInt(columns);
1441                dos.writeInt(rows);
1442                
1443                dos.writeInt(data.length);
1444                for(int i=0; i < data.length;i++)
1445                        dos.writeFloat(data[i]);
1446        }
1447        
1448        /**
1449         * Reads in a matrix from the given data stream. Note
1450         * that the old data of this matrix will be discarded.
1451         * @param dis the data input stream to read from.
1452         * @throws IOException 
1453         */
1454        public void in(DataInputStream dis) throws IOException {
1455                if(!dis.readUTF().equals("float")) 
1456                        throw new IllegalStateException("The matrix in the specified file is not of the correct type!");
1457                
1458                this.columns    = dis.readInt();
1459                this.rows               = dis.readInt();
1460
1461                final int MAX = dis.readInt();
1462                data = new float[MAX];
1463                for(int i=0; i < MAX;i++)
1464                        data[i] = dis.readFloat();
1465        }       
1466        
1467        /**
1468         * Saves this matrix to the specified file.
1469         * @param filename the file to write the matrix in.
1470         * @throws IOException thrown on errors while writing the matrix to the file
1471         */
1472        public void save(String filename) throws IOException {
1473                DataOutputStream dos = new DataOutputStream(new FileOutputStream(filename, false));
1474                this.out(dos);
1475        }
1476        
1477        /**
1478         * Loads a matrix from a file into this matrix. Note that the old data
1479         * of this matrix will be discarded.
1480         * @param filename the file to read the matrix from
1481         * @throws IOException thrown on errors while reading the matrix
1482         */
1483        public void load(String filename) throws IOException {
1484                DataInputStream dis = new DataInputStream(new FileInputStream(filename));
1485                this.in(dis);
1486        }
1487
1488        /****************************************************************
1489         * Autogenerated code
1490         */
1491        
1492        /***** Code for operators ***************************************/ 
1493
1494        /* Overloads for the usual arithmetic operations */
1495        /*#
1496         def gen_overloads(base, result_rows, result_cols); <<-EOS
1497        public ComplexFloatMatrix #{base}i(ComplexFloatMatrix other) {
1498                return #{base}i(other, this);
1499        }
1500                
1501        public ComplexFloatMatrix #{base}(ComplexFloatMatrix other) {
1502                return #{base}i(other, new ComplexFloatMatrix(#{result_rows}, #{result_cols}));
1503        }
1504
1505        public ComplexFloatMatrix #{base}i(ComplexFloat v) {
1506                return #{base}i(v, this);
1507        }
1508        
1509        public ComplexFloatMatrix #{base}i(float v) {
1510                return #{base}i(new ComplexFloat(v), this);
1511        }
1512
1513        public ComplexFloatMatrix #{base}(ComplexFloat v) {
1514                return #{base}i(v, new ComplexFloatMatrix(rows, columns));
1515        }       
1516
1517        public ComplexFloatMatrix #{base}(float v) {
1518                return #{base}i(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1519        }       
1520                
1521                EOS
1522          end
1523        #*/
1524
1525        /* Generating code for logical operators. This not only generates the stubs 
1526         * but really all of the code.
1527         */
1528        
1529        /*#
1530         def gen_compare(name, op); <<-EOS
1531         public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1532            if (other.isScalar())
1533               return #{name}i(other.scalar(), result);
1534               
1535                assertSameLength(other);
1536                ensureResultLength(other, result);
1537                
1538                ComplexFloat c1 = new ComplexFloat(0.0f);
1539                ComplexFloat c2 = new ComplexFloat(0.0f);
1540          
1541                for (int i = 0; i < length; i++)
1542                    result.put(i, get(i, c1).#{op}(other.get(i, c2)) ? 1.0f : 0.0f);
1543           return result;
1544         }
1545         
1546         public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other) {
1547           return #{name}i(other, this);
1548         }
1549         
1550         public ComplexFloatMatrix #{name}(ComplexFloatMatrix other) {
1551           return #{name}i(other, new ComplexFloatMatrix(rows, columns));
1552         }
1553         
1554         public ComplexFloatMatrix #{name}i(ComplexFloat value, ComplexFloatMatrix result) {
1555           ensureResultLength(null, result);
1556           ComplexFloat c = new ComplexFloat(0.0f);
1557           for (int i = 0; i < length; i++)
1558             result.put(i, get(i, c).#{op}(value) ? 1.0f : 0.0f);
1559           return result;
1560         }
1561
1562         public ComplexFloatMatrix #{name}i(float value, ComplexFloatMatrix result) {
1563           return #{name}i(new ComplexFloat(value), result);
1564         }
1565
1566         public ComplexFloatMatrix #{name}i(ComplexFloat value) {
1567           return #{name}i(value, this);
1568         }
1569         
1570         public ComplexFloatMatrix #{name}i(float value) {
1571           return #{name}i(new ComplexFloat(value));
1572         }
1573         
1574         public ComplexFloatMatrix #{name}(ComplexFloat value) {
1575           return #{name}i(value, new ComplexFloatMatrix(rows, columns));
1576         }
1577         
1578         public ComplexFloatMatrix #{name}(float value) {
1579           return #{name}i(new ComplexFloat(value));
1580         }
1581
1582         EOS
1583         end
1584         #*/
1585        
1586        /*#
1587         def gen_logical(name, op); <<-EOS
1588         public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1589                assertSameLength(other);
1590                ensureResultLength(other, result);
1591                
1592                ComplexFloat t1 = new ComplexFloat(0.0f);
1593                ComplexFloat t2 = new ComplexFloat(0.0f);
1594         
1595               for (int i = 0; i < length; i++)
1596                  result.put(i, (!get(i, t1).isZero()) #{op} (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1597           return result;
1598         }
1599         
1600         public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other) {
1601           return #{name}i(other, this);
1602         }
1603         
1604         public ComplexFloatMatrix #{name}(ComplexFloatMatrix other) {
1605           return #{name}i(other, new ComplexFloatMatrix(rows, columns));
1606         }
1607         
1608         public ComplexFloatMatrix #{name}i(ComplexFloat value, ComplexFloatMatrix result) {
1609                ensureResultLength(null, result);
1610                boolean val = !value.isZero();
1611                ComplexFloat t = new ComplexFloat(0.0f);
1612                for (int i = 0; i < length; i++)
1613                     result.put(i, !get(i, t).isZero() #{op} val ? 1.0f : 0.0f);
1614           return result;
1615         }
1616
1617         public ComplexFloatMatrix #{name}i(float value, ComplexFloatMatrix result) {
1618           return #{name}i(new ComplexFloat(value), result);
1619         }
1620
1621         public ComplexFloatMatrix #{name}i(ComplexFloat value) {
1622           return #{name}i(value, this);
1623         }
1624
1625         public ComplexFloatMatrix #{name}i(float value) {
1626           return #{name}i(new ComplexFloat(value), this);
1627         }
1628
1629         public ComplexFloatMatrix #{name}(ComplexFloat value) {
1630           return #{name}i(value, new ComplexFloatMatrix(rows, columns));
1631         }
1632         
1633         public ComplexFloatMatrix #{name}(float value) {
1634           return #{name}i(new ComplexFloat(value));
1635         }
1636         EOS
1637         end
1638         #*/
1639
1640        /*# collect(gen_overloads('add', 'rows', 'columns'),
1641          gen_overloads('sub', 'rows', 'columns'),
1642          gen_overloads('rsub', 'rows', 'columns'),
1643          gen_overloads('div', 'rows', 'columns'),
1644          gen_overloads('rdiv', 'rows', 'columns'),
1645          gen_overloads('mul', 'rows', 'columns'),
1646          gen_overloads('mmul', 'rows', 'other.columns'),
1647          gen_compare('eq', 'eq'),
1648          gen_compare('ne', 'eq'),
1649          gen_logical('and', '&'),
1650          gen_logical('or', '|'),
1651          gen_logical('xor', '^'))
1652         #*/
1653//RJPP-BEGIN------------------------------------------------------------
1654        public ComplexFloatMatrix addi(ComplexFloatMatrix other) {
1655                return addi(other, this);
1656        }
1657                
1658        public ComplexFloatMatrix add(ComplexFloatMatrix other) {
1659                return addi(other, new ComplexFloatMatrix(rows, columns));
1660        }
1661
1662        public ComplexFloatMatrix addi(ComplexFloat v) {
1663                return addi(v, this);
1664        }
1665        
1666        public ComplexFloatMatrix addi(float v) {
1667                return addi(new ComplexFloat(v), this);
1668        }
1669
1670        public ComplexFloatMatrix add(ComplexFloat v) {
1671                return addi(v, new ComplexFloatMatrix(rows, columns));
1672        }       
1673
1674        public ComplexFloatMatrix add(float v) {
1675                return addi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1676        }       
1677                
1678
1679        public ComplexFloatMatrix subi(ComplexFloatMatrix other) {
1680                return subi(other, this);
1681        }
1682                
1683        public ComplexFloatMatrix sub(ComplexFloatMatrix other) {
1684                return subi(other, new ComplexFloatMatrix(rows, columns));
1685        }
1686
1687        public ComplexFloatMatrix subi(ComplexFloat v) {
1688                return subi(v, this);
1689        }
1690        
1691        public ComplexFloatMatrix subi(float v) {
1692                return subi(new ComplexFloat(v), this);
1693        }
1694
1695        public ComplexFloatMatrix sub(ComplexFloat v) {
1696                return subi(v, new ComplexFloatMatrix(rows, columns));
1697        }       
1698
1699        public ComplexFloatMatrix sub(float v) {
1700                return subi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1701        }       
1702                
1703
1704        public ComplexFloatMatrix rsubi(ComplexFloatMatrix other) {
1705                return rsubi(other, this);
1706        }
1707                
1708        public ComplexFloatMatrix rsub(ComplexFloatMatrix other) {
1709                return rsubi(other, new ComplexFloatMatrix(rows, columns));
1710        }
1711
1712        public ComplexFloatMatrix rsubi(ComplexFloat v) {
1713                return rsubi(v, this);
1714        }
1715        
1716        public ComplexFloatMatrix rsubi(float v) {
1717                return rsubi(new ComplexFloat(v), this);
1718        }
1719
1720        public ComplexFloatMatrix rsub(ComplexFloat v) {
1721                return rsubi(v, new ComplexFloatMatrix(rows, columns));
1722        }       
1723
1724        public ComplexFloatMatrix rsub(float v) {
1725                return rsubi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1726        }       
1727                
1728
1729        public ComplexFloatMatrix divi(ComplexFloatMatrix other) {
1730                return divi(other, this);
1731        }
1732                
1733        public ComplexFloatMatrix div(ComplexFloatMatrix other) {
1734                return divi(other, new ComplexFloatMatrix(rows, columns));
1735        }
1736
1737        public ComplexFloatMatrix divi(ComplexFloat v) {
1738                return divi(v, this);
1739        }
1740        
1741        public ComplexFloatMatrix divi(float v) {
1742                return divi(new ComplexFloat(v), this);
1743        }
1744
1745        public ComplexFloatMatrix div(ComplexFloat v) {
1746                return divi(v, new ComplexFloatMatrix(rows, columns));
1747        }       
1748
1749        public ComplexFloatMatrix div(float v) {
1750                return divi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1751        }       
1752                
1753
1754        public ComplexFloatMatrix rdivi(ComplexFloatMatrix other) {
1755                return rdivi(other, this);
1756        }
1757                
1758        public ComplexFloatMatrix rdiv(ComplexFloatMatrix other) {
1759                return rdivi(other, new ComplexFloatMatrix(rows, columns));
1760        }
1761
1762        public ComplexFloatMatrix rdivi(ComplexFloat v) {
1763                return rdivi(v, this);
1764        }
1765        
1766        public ComplexFloatMatrix rdivi(float v) {
1767                return rdivi(new ComplexFloat(v), this);
1768        }
1769
1770        public ComplexFloatMatrix rdiv(ComplexFloat v) {
1771                return rdivi(v, new ComplexFloatMatrix(rows, columns));
1772        }       
1773
1774        public ComplexFloatMatrix rdiv(float v) {
1775                return rdivi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1776        }       
1777                
1778
1779        public ComplexFloatMatrix muli(ComplexFloatMatrix other) {
1780                return muli(other, this);
1781        }
1782                
1783        public ComplexFloatMatrix mul(ComplexFloatMatrix other) {
1784                return muli(other, new ComplexFloatMatrix(rows, columns));
1785        }
1786
1787        public ComplexFloatMatrix muli(ComplexFloat v) {
1788                return muli(v, this);
1789        }
1790        
1791        public ComplexFloatMatrix muli(float v) {
1792                return muli(new ComplexFloat(v), this);
1793        }
1794
1795        public ComplexFloatMatrix mul(ComplexFloat v) {
1796                return muli(v, new ComplexFloatMatrix(rows, columns));
1797        }       
1798
1799        public ComplexFloatMatrix mul(float v) {
1800                return muli(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1801        }       
1802                
1803
1804        public ComplexFloatMatrix mmuli(ComplexFloatMatrix other) {
1805                return mmuli(other, this);
1806        }
1807                
1808        public ComplexFloatMatrix mmul(ComplexFloatMatrix other) {
1809                return mmuli(other, new ComplexFloatMatrix(rows, other.columns));
1810        }
1811
1812        public ComplexFloatMatrix mmuli(ComplexFloat v) {
1813                return mmuli(v, this);
1814        }
1815        
1816        public ComplexFloatMatrix mmuli(float v) {
1817                return mmuli(new ComplexFloat(v), this);
1818        }
1819
1820        public ComplexFloatMatrix mmul(ComplexFloat v) {
1821                return mmuli(v, new ComplexFloatMatrix(rows, columns));
1822        }       
1823
1824        public ComplexFloatMatrix mmul(float v) {
1825                return mmuli(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1826        }       
1827                
1828
1829         public ComplexFloatMatrix eqi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1830            if (other.isScalar())
1831               return eqi(other.scalar(), result);
1832               
1833                assertSameLength(other);
1834                ensureResultLength(other, result);
1835                
1836                ComplexFloat c1 = new ComplexFloat(0.0f);
1837                ComplexFloat c2 = new ComplexFloat(0.0f);
1838          
1839                for (int i = 0; i < length; i++)
1840                    result.put(i, get(i, c1).eq(other.get(i, c2)) ? 1.0f : 0.0f);
1841           return result;
1842         }
1843         
1844         public ComplexFloatMatrix eqi(ComplexFloatMatrix other) {
1845           return eqi(other, this);
1846         }
1847         
1848         public ComplexFloatMatrix eq(ComplexFloatMatrix other) {
1849           return eqi(other, new ComplexFloatMatrix(rows, columns));
1850         }
1851         
1852         public ComplexFloatMatrix eqi(ComplexFloat value, ComplexFloatMatrix result) {
1853           ensureResultLength(null, result);
1854           ComplexFloat c = new ComplexFloat(0.0f);
1855           for (int i = 0; i < length; i++)
1856             result.put(i, get(i, c).eq(value) ? 1.0f : 0.0f);
1857           return result;
1858         }
1859
1860         public ComplexFloatMatrix eqi(float value, ComplexFloatMatrix result) {
1861           return eqi(new ComplexFloat(value), result);
1862         }
1863
1864         public ComplexFloatMatrix eqi(ComplexFloat value) {
1865           return eqi(value, this);
1866         }
1867         
1868         public ComplexFloatMatrix eqi(float value) {
1869           return eqi(new ComplexFloat(value));
1870         }
1871         
1872         public ComplexFloatMatrix eq(ComplexFloat value) {
1873           return eqi(value, new ComplexFloatMatrix(rows, columns));
1874         }
1875         
1876         public ComplexFloatMatrix eq(float value) {
1877           return eqi(new ComplexFloat(value));
1878         }
1879
1880
1881         public ComplexFloatMatrix nei(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1882            if (other.isScalar())
1883               return nei(other.scalar(), result);
1884               
1885                assertSameLength(other);
1886                ensureResultLength(other, result);
1887                
1888                ComplexFloat c1 = new ComplexFloat(0.0f);
1889                ComplexFloat c2 = new ComplexFloat(0.0f);
1890          
1891                for (int i = 0; i < length; i++)
1892                    result.put(i, get(i, c1).eq(other.get(i, c2)) ? 1.0f : 0.0f);
1893           return result;
1894         }
1895         
1896         public ComplexFloatMatrix nei(ComplexFloatMatrix other) {
1897           return nei(other, this);
1898         }
1899         
1900         public ComplexFloatMatrix ne(ComplexFloatMatrix other) {
1901           return nei(other, new ComplexFloatMatrix(rows, columns));
1902         }
1903         
1904         public ComplexFloatMatrix nei(ComplexFloat value, ComplexFloatMatrix result) {
1905           ensureResultLength(null, result);
1906           ComplexFloat c = new ComplexFloat(0.0f);
1907           for (int i = 0; i < length; i++)
1908             result.put(i, get(i, c).eq(value) ? 1.0f : 0.0f);
1909           return result;
1910         }
1911
1912         public ComplexFloatMatrix nei(float value, ComplexFloatMatrix result) {
1913           return nei(new ComplexFloat(value), result);
1914         }
1915
1916         public ComplexFloatMatrix nei(ComplexFloat value) {
1917           return nei(value, this);
1918         }
1919         
1920         public ComplexFloatMatrix nei(float value) {
1921           return nei(new ComplexFloat(value));
1922         }
1923         
1924         public ComplexFloatMatrix ne(ComplexFloat value) {
1925           return nei(value, new ComplexFloatMatrix(rows, columns));
1926         }
1927         
1928         public ComplexFloatMatrix ne(float value) {
1929           return nei(new ComplexFloat(value));
1930         }
1931
1932
1933         public ComplexFloatMatrix andi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1934                assertSameLength(other);
1935                ensureResultLength(other, result);
1936                
1937                ComplexFloat t1 = new ComplexFloat(0.0f);
1938                ComplexFloat t2 = new ComplexFloat(0.0f);
1939         
1940               for (int i = 0; i < length; i++)
1941                  result.put(i, (!get(i, t1).isZero()) & (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1942           return result;
1943         }
1944         
1945         public ComplexFloatMatrix andi(ComplexFloatMatrix other) {
1946           return andi(other, this);
1947         }
1948         
1949         public ComplexFloatMatrix and(ComplexFloatMatrix other) {
1950           return andi(other, new ComplexFloatMatrix(rows, columns));
1951         }
1952         
1953         public ComplexFloatMatrix andi(ComplexFloat value, ComplexFloatMatrix result) {
1954                ensureResultLength(null, result);
1955                boolean val = !value.isZero();
1956                ComplexFloat t = new ComplexFloat(0.0f);
1957                for (int i = 0; i < length; i++)
1958                     result.put(i, !get(i, t).isZero() & val ? 1.0f : 0.0f);
1959           return result;
1960         }
1961
1962         public ComplexFloatMatrix andi(float value, ComplexFloatMatrix result) {
1963           return andi(new ComplexFloat(value), result);
1964         }
1965
1966         public ComplexFloatMatrix andi(ComplexFloat value) {
1967           return andi(value, this);
1968         }
1969
1970         public ComplexFloatMatrix andi(float value) {
1971           return andi(new ComplexFloat(value), this);
1972         }
1973
1974         public ComplexFloatMatrix and(ComplexFloat value) {
1975           return andi(value, new ComplexFloatMatrix(rows, columns));
1976         }
1977         
1978         public ComplexFloatMatrix and(float value) {
1979           return andi(new ComplexFloat(value));
1980         }
1981
1982         public ComplexFloatMatrix ori(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1983                assertSameLength(other);
1984                ensureResultLength(other, result);
1985                
1986                ComplexFloat t1 = new ComplexFloat(0.0f);
1987                ComplexFloat t2 = new ComplexFloat(0.0f);
1988         
1989               for (int i = 0; i < length; i++)
1990                  result.put(i, (!get(i, t1).isZero()) | (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1991           return result;
1992         }
1993         
1994         public ComplexFloatMatrix ori(ComplexFloatMatrix other) {
1995           return ori(other, this);
1996         }
1997         
1998         public ComplexFloatMatrix or(ComplexFloatMatrix other) {
1999           return ori(other, new ComplexFloatMatrix(rows, columns));
2000         }
2001         
2002         public ComplexFloatMatrix ori(ComplexFloat value, ComplexFloatMatrix result) {
2003                ensureResultLength(null, result);
2004                boolean val = !value.isZero();
2005                ComplexFloat t = new ComplexFloat(0.0f);
2006                for (int i = 0; i < length; i++)
2007                     result.put(i, !get(i, t).isZero() | val ? 1.0f : 0.0f);
2008           return result;
2009         }
2010
2011         public ComplexFloatMatrix ori(float value, ComplexFloatMatrix result) {
2012           return ori(new ComplexFloat(value), result);
2013         }
2014
2015         public ComplexFloatMatrix ori(ComplexFloat value) {
2016           return ori(value, this);
2017         }
2018
2019         public ComplexFloatMatrix ori(float value) {
2020           return ori(new ComplexFloat(value), this);
2021         }
2022
2023         public ComplexFloatMatrix or(ComplexFloat value) {
2024           return ori(value, new ComplexFloatMatrix(rows, columns));
2025         }
2026         
2027         public ComplexFloatMatrix or(float value) {
2028           return ori(new ComplexFloat(value));
2029         }
2030
2031         public ComplexFloatMatrix xori(ComplexFloatMatrix other, ComplexFloatMatrix result) {
2032                assertSameLength(other);
2033                ensureResultLength(other, result);
2034                
2035                ComplexFloat t1 = new ComplexFloat(0.0f);
2036                ComplexFloat t2 = new ComplexFloat(0.0f);
2037         
2038               for (int i = 0; i < length; i++)
2039                  result.put(i, (!get(i, t1).isZero()) ^ (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
2040           return result;
2041         }
2042         
2043         public ComplexFloatMatrix xori(ComplexFloatMatrix other) {
2044           return xori(other, this);
2045         }
2046         
2047         public ComplexFloatMatrix xor(ComplexFloatMatrix other) {
2048           return xori(other, new ComplexFloatMatrix(rows, columns));
2049         }
2050         
2051         public ComplexFloatMatrix xori(ComplexFloat value, ComplexFloatMatrix result) {
2052                ensureResultLength(null, result);
2053                boolean val = !value.isZero();
2054                ComplexFloat t = new ComplexFloat(0.0f);
2055                for (int i = 0; i < length; i++)
2056                     result.put(i, !get(i, t).isZero() ^ val ? 1.0f : 0.0f);
2057           return result;
2058         }
2059
2060         public ComplexFloatMatrix xori(float value, ComplexFloatMatrix result) {
2061           return xori(new ComplexFloat(value), result);
2062         }
2063
2064         public ComplexFloatMatrix xori(ComplexFloat value) {
2065           return xori(value, this);
2066         }
2067
2068         public ComplexFloatMatrix xori(float value) {
2069           return xori(new ComplexFloat(value), this);
2070         }
2071
2072         public ComplexFloatMatrix xor(ComplexFloat value) {
2073           return xori(value, new ComplexFloatMatrix(rows, columns));
2074         }
2075         
2076         public ComplexFloatMatrix xor(float value) {
2077           return xori(new ComplexFloat(value));
2078         }
2079//RJPP-END--------------------------------------------------------------
2080}