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