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 }