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 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    }