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