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