001 // --- BEGIN LICENSE BLOCK ---
002 /*
003 * Copyright (c) 2009, Mikio L. Braun
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are
008 * met:
009 *
010 * * Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * * Redistributions in binary form must reproduce the above
014 * copyright notice, this list of conditions and the following
015 * disclaimer in the documentation and/or other materials provided
016 * with the distribution.
017 *
018 * * Neither the name of the Technische Universit?t Berlin nor the
019 * names of its contributors may be used to endorse or promote
020 * products derived from this software without specific prior
021 * written permission.
022 *
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034 */
035 // --- END LICENSE BLOCK ---
036
037 package org.jblas;
038
039 import org.jblas.exceptions.SizeException;
040
041 import java.io.DataInputStream;
042 import java.io.DataOutputStream;
043 import java.io.FileInputStream;
044 import java.io.FileOutputStream;
045 import java.io.IOException;
046
047 public class ComplexFloatMatrix {
048
049 public int rows;
050 public int columns;
051 public int length;
052 public float[] data = null; // rows are contiguous
053
054 /**************************************************************************
055 *
056 * Constructors and factory functions
057 *
058 **************************************************************************/
059
060 /** Create a new matrix with <i>newRows</i> rows, <i>newColumns</i> columns
061 * using <i>newData></i> as the data. The length of the data is not checked!
062 */
063 public ComplexFloatMatrix(int newRows, int newColumns, float... newData) {
064 rows = newRows;
065 columns = newColumns;
066 length = rows * columns;
067
068 if (newData.length != 2 * newRows * newColumns)
069 throw new IllegalArgumentException(
070 "Passed data must match matrix dimensions.");
071
072 data = newData;
073 }
074
075 /**
076 * Creates a new <i>n</i> times <i>m</i> <tt>ComplexFloatMatrix</tt>.
077 * @param newRows the number of rows (<i>n</i>) of the new matrix.
078 * @param newColumns the number of columns (<i>m</i>) of the new matrix.
079 */
080 public ComplexFloatMatrix(int newRows, int newColumns) {
081 this(newRows, newColumns, new float[2 * newRows * newColumns]);
082 }
083
084 /**
085 * Creates a new <tt>ComplexFloatMatrix</tt> of size 0 times 0.
086 */
087 public ComplexFloatMatrix() {
088 this(0, 0, null);
089 }
090
091 /**
092 * Create a Matrix of length <tt>len</tt>. By default, this creates a row vector.
093 * @param len
094 */
095 public ComplexFloatMatrix(int len) {
096 this(len, 1, new float[2 * len]);
097 }
098
099 public ComplexFloatMatrix(float[] newData) {
100 this(newData.length/2);
101
102 data = newData;
103 }
104
105 public ComplexFloatMatrix(ComplexFloat[] newData) {
106 this(newData.length);
107
108 for (int i = 0; i < newData.length; i++)
109 put(i, newData[i]);
110 }
111
112
113 /** Construct a complex matrix from a real matrix. */
114 public ComplexFloatMatrix(FloatMatrix m) {
115 this(m.rows, m.columns);
116
117 NativeBlas.scopy(m.length, m.data, 0, 1, data, 0, 2);
118 }
119
120 /** Construct a complex matrix from separate real and imaginary parts. Either
121 * part can be set to null in which case it will be ignored.
122 */
123 public ComplexFloatMatrix(FloatMatrix real, FloatMatrix imag) {
124 this(real.rows, real.columns);
125 real.assertSameSize(imag);
126
127 if (real != null)
128 NativeBlas.scopy(length, real.data, 0, 1, data, 0, 2);
129 if (imag != null)
130 NativeBlas.scopy(length, imag.data, 0, 1, data, 1, 2);
131 }
132
133 /**
134 * Creates a new matrix by reading it from a file.
135 * @param filename the path and name of the file to read the matrix from
136 * @throws IOException
137 */
138 public ComplexFloatMatrix(String filename) throws IOException {
139 load(filename);
140 }
141
142 /**
143 * Creates a new <i>n</i> times <i>m</i> <tt>ComplexFloatMatrix</tt> from
144 * the given <i>n</i> times <i>m</i> 2D data array. The first dimension of the array makes the
145 * rows (<i>n</i>) and the second dimension the columns (<i>m</i>). For example, the
146 * given code <br/><br/>
147 * <code>new ComplexFloatMatrix(new float[][]{{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}).print();</code><br/><br/>
148 * will constructs the following matrix:
149 * <pre>
150 * 1.0f 2.0f 3.0f
151 * 4.0f 5.0f 6.0f
152 * 7.0f 8.0f 9.0f
153 * </pre>.
154 * @param data <i>n</i> times <i>m</i> data array
155 */
156 public ComplexFloatMatrix(float[][] data) {
157 this(data.length, data[0].length);
158
159 for (int r = 0; r < rows; r++)
160 assert(data[r].length == columns);
161
162 for (int r = 0; r < rows; r++)
163 for (int c = 0; c < columns; c++)
164 put(r, c, data[r][c]);
165 }
166
167 /**
168 * Creates a new matrix in which all values are equal 0.
169 * @param rows number of rows
170 * @param columns number of columns
171 * @return new matrix
172 */
173 public static ComplexFloatMatrix zeros(int rows, int columns) {
174 return new ComplexFloatMatrix(rows, columns);
175 }
176
177 public static ComplexFloatMatrix zeros(int length) {
178 return zeros(length, 1);
179 }
180
181 /**
182 * Creates a new matrix in which all values are equal 1.
183 * @param rows number of rows
184 * @param columns number of columns
185 * @return new matrix
186 */
187 public static ComplexFloatMatrix ones(int rows, int columns) {
188 ComplexFloatMatrix m = new ComplexFloatMatrix(rows, columns);
189
190 for (int i = 0; i < rows * columns; i++)
191 m.put(i, 1.0f);
192
193 return m;
194 }
195
196 public static ComplexFloatMatrix ones(int length) {
197 return ones(length, 1);
198 }
199
200 /**
201 * Creates a new matrix where the values of the given vector are the diagonal values of
202 * the matrix.
203 * @param x the diagonal values
204 * @return new matrix
205 */
206 public static ComplexFloatMatrix diag(ComplexFloatMatrix x) {
207 ComplexFloatMatrix m = new ComplexFloatMatrix(x.length, x.length);
208
209 for (int i = 0; i < x.length; i++)
210 m.put(i, i, x.get(i));
211
212 return m;
213 }
214
215 /**
216 * Create a 1 * 1 - matrix. For many operations, this matrix functions like a
217 * normal float
218 * @param s value of the matrix
219 * @return the constructed ComplexFloatMatrix
220 */
221 public static ComplexFloatMatrix scalar(float s) {
222 ComplexFloatMatrix m = new ComplexFloatMatrix(1, 1);
223 m.put(0, 0, s);
224 return m;
225 }
226
227 /** Test whether a matrix is scalar */
228 public boolean isScalar() {
229 return length == 1;
230 }
231
232 /** Return the first element of the matrix */
233 public ComplexFloat scalar() {
234 return get(0);
235 }
236
237 public static ComplexFloatMatrix concatHorizontally(ComplexFloatMatrix A, ComplexFloatMatrix B) {
238 if (A.rows != B.rows)
239 throw new SizeException("Matrices don't have same number of rows.");
240
241 ComplexFloatMatrix result = new ComplexFloatMatrix(A.rows, A.columns + B.columns);
242 SimpleBlas.copy(A, result);
243 NativeBlas.ccopy(B.length, B.data, 0, 1, result.data, A.length, 1);
244 return result;
245 }
246
247 public static ComplexFloatMatrix concatVertically(ComplexFloatMatrix A, ComplexFloatMatrix B) {
248 if (A.columns != B.columns)
249 throw new SizeException("Matrices don't have same number of columns.");
250
251 ComplexFloatMatrix result = new ComplexFloatMatrix(A.rows + B.rows, A.columns);
252
253 for (int i = 0; i < A.columns; i++) {
254 NativeBlas.ccopy(A.rows, A.data, A.index(0, i), 1, result.data, result.index(0, i), 1);
255 NativeBlas.ccopy(B.rows, B.data, B.index(0, i), 1, result.data, result.index(A.rows, i), 1);
256 }
257
258 return result;
259 }
260
261 /**************************************************************************
262 * Working with slices (Man! 30+ methods just to make this a bit flexible...)
263 */
264
265 public ComplexFloatMatrix get(int[] indices) {
266 ComplexFloatMatrix result = new ComplexFloatMatrix(indices.length);
267
268 for (int i = 0; i < indices.length; i++)
269 result.put(i, get(indices[i]));
270
271 return result;
272 }
273
274 public ComplexFloatMatrix get(int r, int[] indices) {
275 ComplexFloatMatrix result = new ComplexFloatMatrix(1, indices.length);
276
277 for (int i = 0; i < indices.length; i++)
278 result.put(i, get(r, indices[i]));
279
280 return result;
281 }
282
283 public ComplexFloatMatrix get(int[] indices, int c) {
284 ComplexFloatMatrix result = new ComplexFloatMatrix(indices.length, c);
285
286 for (int i = 0; i < indices.length; i++)
287 result.put(i, get(indices[i], c));
288
289 return result;
290 }
291
292 public ComplexFloatMatrix get(int[] rindices, int[] cindices) {
293 ComplexFloatMatrix result = new ComplexFloatMatrix(rindices.length, cindices.length);
294
295 for (int i = 0; i < rindices.length; i++)
296 for (int j = 0; j < cindices.length; j++)
297 result.put(i, j, get(rindices[i], cindices[j]));
298
299 return result;
300 }
301
302 public ComplexFloatMatrix get(ComplexFloatMatrix indices) {
303 return get(indices.findIndices());
304 }
305
306 public ComplexFloatMatrix get(int r, ComplexFloatMatrix indices) {
307 return get(r, indices.findIndices());
308 }
309
310 public ComplexFloatMatrix get(ComplexFloatMatrix indices, int c) {
311 return get(indices.findIndices(), c);
312 }
313
314 public ComplexFloatMatrix get(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices) {
315 return get(rindices.findIndices(), cindices.findIndices());
316 }
317
318 private void checkLength(int l) {
319 if (length != l)
320 throw new SizeException("Matrix does not have the necessary length (" + length + " != " + l + ").");
321 }
322
323 private void checkRows(int r) {
324 if (rows != r)
325 throw new SizeException("Matrix does not have the necessary length (" + length + " != " + r + ").");
326 }
327
328 private void checkColumns(int c) {
329 if (columns != c)
330 throw new SizeException("Matrix does not have the necessary length (" + length + " != " + c + ").");
331 }
332
333 public ComplexFloatMatrix put(int[] indices, ComplexFloatMatrix x) {
334 if (x.isScalar())
335 return put(indices, x.scalar());
336 x.checkLength(indices.length);
337
338 for (int i = 0; i < indices.length; i++)
339 put(indices[i], x.get(i));
340
341 return this;
342 }
343
344 public ComplexFloatMatrix put(int r, int[] indices, ComplexFloatMatrix x) {
345 if (x.isScalar())
346 return put(r, indices, x.scalar());
347 x.checkColumns(indices.length);
348
349 for (int i = 0; i < indices.length; i++)
350 put(r, indices[i], x.get(i));
351
352 return this;
353 }
354
355 public ComplexFloatMatrix put(int[] indices, int c, ComplexFloatMatrix x) {
356 if (x.isScalar())
357 return put(indices, c, x.scalar());
358 x.checkRows(indices.length);
359
360 for (int i = 0; i < indices.length; i++)
361 put(indices[i], c, x.get(i));
362
363 return this;
364 }
365
366 public ComplexFloatMatrix put(int[] rindices, int[] cindices, ComplexFloatMatrix x) {
367 if (x.isScalar())
368 return put(rindices, cindices, x.scalar());
369 x.checkRows(rindices.length);
370 x.checkColumns(cindices.length);
371
372 for (int i = 0; i < rindices.length; i++)
373 for (int j = 0; j < cindices.length; j++)
374 put(rindices[i], cindices[j], x.get(i,j));
375
376 return this;
377 }
378
379 public ComplexFloatMatrix put(int[] indices, float v) {
380 for (int i = 0; i < indices.length; i++)
381 put(indices[i], v);
382
383 return this;
384 }
385
386 public ComplexFloatMatrix putReal(int[] indices, float v) {
387 return put(indices, v);
388 }
389
390 public ComplexFloatMatrix putImag(int[] indices, float v) {
391 for (int i = 0; i < indices.length; i++)
392 putImag(indices[i], v);
393
394 return this;
395 }
396
397 public ComplexFloatMatrix put(int[] indices, ComplexFloat v) {
398 for (int i = 0; i < indices.length; i++)
399 put(indices[i], v);
400
401 return this;
402 }
403
404 public ComplexFloatMatrix put(int r, int[] indices, float v) {
405 for (int i = 0; i < indices.length; i++)
406 put(r, indices[i], v);
407
408 return this;
409 }
410
411 public ComplexFloatMatrix putReal(int r, int[] indices, float v) {
412 return put(r, indices, v);
413 }
414
415 public ComplexFloatMatrix putImag(int r, int[] indices, float v) {
416 for (int i = 0; i < indices.length; i++)
417 putImag(r, indices[i], v);
418
419 return this;
420 }
421
422 public ComplexFloatMatrix put(int r, int[] indices, ComplexFloat v) {
423 for (int i = 0; i < indices.length; i++)
424 put(r, indices[i], v);
425
426 return this;
427 }
428
429 public ComplexFloatMatrix put(int[] indices, int c, float v) {
430 for (int i = 0; i < indices.length; i++)
431 put(indices[i], c, v);
432
433 return this;
434 }
435
436 public ComplexFloatMatrix putReal(int[] indices, int c, float v) {
437 return put(indices, c, v);
438 }
439
440 public ComplexFloatMatrix putImag(int[] indices, int c, float v) {
441 for (int i = 0; i < indices.length; i++)
442 putImag(indices[i], c, v);
443
444 return this;
445 }
446
447 public ComplexFloatMatrix put(int[] indices, int c, ComplexFloat v) {
448 for (int i = 0; i < indices.length; i++)
449 put(indices[i], c, v);
450
451 return this;
452 }
453
454 public ComplexFloatMatrix put(int[] rindices, int[] cindices, float v) {
455 for (int i = 0; i < rindices.length; i++)
456 for (int j = 0; j < cindices.length; j++)
457 put(rindices[i], cindices[j], v);
458
459 return this;
460 }
461
462 public ComplexFloatMatrix putReal(int[] rindices, int[] cindices, float v) {
463 return put(rindices, cindices, v);
464 }
465
466 public ComplexFloatMatrix putImag(int[] rindices, int[] cindices, float v) {
467 for (int i = 0; i < rindices.length; i++)
468 for (int j = 0; j < cindices.length; j++)
469 put(rindices[i], cindices[j], v);
470
471 return this;
472 }
473
474 public ComplexFloatMatrix put(int[] rindices, int[] cindices, ComplexFloat v) {
475 for (int i = 0; i < rindices.length; i++)
476 for (int j = 0; j < cindices.length; j++)
477 put(rindices[i], cindices[j], v);
478
479 return this;
480 }
481
482 public ComplexFloatMatrix put(ComplexFloatMatrix indices, ComplexFloatMatrix v) {
483 return put(indices.findIndices(), v);
484 }
485
486 public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, ComplexFloatMatrix v) {
487 return put(r, indices.findIndices(), v);
488 }
489
490 public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, ComplexFloatMatrix v) {
491 return put(indices.findIndices(), c, v);
492 }
493
494 public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, ComplexFloatMatrix v) {
495 return put(rindices.findIndices(), cindices.findIndices(), v);
496 }
497
498 public ComplexFloatMatrix put(ComplexFloatMatrix indices, float v) {
499 return put(indices.findIndices(), v);
500 }
501
502 public ComplexFloatMatrix putReal(ComplexFloatMatrix indices, float v) {
503 return put(indices, v);
504 }
505
506 public ComplexFloatMatrix putImag(ComplexFloatMatrix indices, float v) {
507 return putImag(indices.findIndices(), v);
508 }
509
510 public ComplexFloatMatrix put(ComplexFloatMatrix indices, ComplexFloat v) {
511 return put(indices.findIndices(), v);
512 }
513
514 public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, float v) {
515 return put(r, indices.findIndices(), v);
516 }
517
518 public ComplexFloatMatrix putReal(int r, ComplexFloatMatrix indices, float v) {
519 return put(r, indices, v);
520 }
521
522 public ComplexFloatMatrix putImag(int r, ComplexFloatMatrix indices, float v) {
523 return putImag(r, indices.findIndices(), v);
524 }
525
526 public ComplexFloatMatrix put(int r, ComplexFloatMatrix indices, ComplexFloat v) {
527 return put(r, indices.findIndices(), v);
528 }
529
530 public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, float v) {
531 return put(indices.findIndices(), c, v);
532 }
533
534 public ComplexFloatMatrix putReal(ComplexFloatMatrix indices, int c, float v) {
535 return put(indices, c, v);
536 }
537
538 public ComplexFloatMatrix putImag(ComplexFloatMatrix indices, int c, float v) {
539 return putImag(indices.findIndices(), c, v);
540 }
541
542 public ComplexFloatMatrix put(ComplexFloatMatrix indices, int c, ComplexFloat v) {
543 return put(indices.findIndices(), c, v);
544 }
545
546 public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
547 return put(rindices.findIndices(), cindices.findIndices(), v);
548 }
549
550 public ComplexFloatMatrix putReal(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
551 return putReal(rindices, cindices, v);
552 }
553
554 public ComplexFloatMatrix putImag(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, float v) {
555 return putImag(rindices.findIndices(), cindices.findIndices(), v);
556 }
557
558 public ComplexFloatMatrix put(ComplexFloatMatrix rindices, ComplexFloatMatrix cindices, ComplexFloat v) {
559 return put(rindices.findIndices(), cindices.findIndices(), v);
560 }
561
562
563 public int[] findIndices() {
564 int len = 0;
565 for (int i = 0; i < length; i++)
566 if (!get(i).isZero())
567 len++;
568
569 int[] indices = new int[len];
570 int c = 0;
571
572 for (int i = 0; i < length; i++)
573 if (!get(i).isZero())
574 indices[c++] = i;
575
576 return indices;
577 }
578
579 /**************************************************************************
580 * Basic operations (copying, resizing, element access)
581 */
582
583 /** Return transposed copy of this matrix */
584 public ComplexFloatMatrix transpose() {
585 ComplexFloatMatrix result = new ComplexFloatMatrix(columns, rows);
586
587 ComplexFloat c = new ComplexFloat(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 ComplexFloatMatrix hermitian() {
597 ComplexFloatMatrix result = new ComplexFloatMatrix(columns, rows);
598
599 ComplexFloat c = new ComplexFloat(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 ComplexFloatMatrix conji() {
611 ComplexFloat c = new ComplexFloat(0.0f);
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 ComplexFloatMatrix 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 ComplexFloatMatrix 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 ComplexFloatMatrix))
631 return false;
632
633 ComplexFloatMatrix other = (ComplexFloatMatrix) o;
634
635 if (!sameSize(other))
636 return false;
637
638 FloatMatrix 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 float[2 * rows * columns];
650 }
651
652
653 /** Reshape the matrix. Number of elements must not change. */
654 public ComplexFloatMatrix 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(ComplexFloatMatrix 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(ComplexFloatMatrix 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(ComplexFloatMatrix a) {
688 return columns == a.rows;
689 }
690
691 public void assertMultipliesWith(ComplexFloatMatrix 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(ComplexFloatMatrix a) {
697 return length == a.length;
698 }
699
700 public void assertSameLength(ComplexFloatMatrix a) {
701 if (!sameLength(a))
702 throw new SizeException("Matrices must have same length (is: " + length + " and " + a.length + ")");
703 }
704
705 /** Copy ComplexFloatMatrix a to this. this a is resized if necessary. */
706 public ComplexFloatMatrix copy(ComplexFloatMatrix 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 ComplexFloatMatrix dup() {
718 ComplexFloatMatrix out = new ComplexFloatMatrix(rows, columns);
719
720 JavaBlas.rcopy(2*length, data, 0, 1, out.data, 0, 1);
721
722 return out;
723 }
724
725 public ComplexFloatMatrix swapColumns(int i, int j) {
726 NativeBlas.cswap(rows, data, index(0, i), 1, data, index(0, j), 1);
727 return this;
728 }
729
730 public ComplexFloatMatrix swapRows(int i, int j) {
731 NativeBlas.cswap(columns, data, index(i, 0), rows, data, index(j, 0), rows);
732 return this;
733 }
734
735 /** Set matrix element */
736 public ComplexFloatMatrix put(int rowIndex, int columnIndex, float value) {
737 data[2*index(rowIndex, columnIndex)] = value;
738 return this;
739 }
740
741 public ComplexFloatMatrix put(int rowIndex, int columnIndex, float realValue, float complexValue) {
742 data[2*index(rowIndex, columnIndex)] = realValue;
743 data[2*index(rowIndex, columnIndex)+1] = complexValue;
744 return this;
745 }
746
747 public ComplexFloatMatrix put(int rowIndex, int columnIndex, ComplexFloat 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 ComplexFloatMatrix putReal(int rowIndex, int columnIndex, float value) {
754 data[2*index(rowIndex, columnIndex)] = value;
755 return this;
756 }
757
758 public ComplexFloatMatrix putImag(int rowIndex, int columnIndex, float value) {
759 data[2*index(rowIndex, columnIndex)+1] = value;
760 return this;
761 }
762
763 /** Retrieve matrix element */
764 public ComplexFloat get(int rowIndex, int columnIndex) {
765 int i = 2*index(rowIndex, columnIndex);
766 return new ComplexFloat(data[i], data[i+1]);
767 }
768
769 /** Get matrix element, passing the variable to store the result. */
770 public ComplexFloat get(int rowIndex, int columnIndex, ComplexFloat result) {
771 return get(index(rowIndex, columnIndex), result);
772 }
773
774 public FloatMatrix getReal() {
775 FloatMatrix result = new FloatMatrix(rows, columns);
776
777 NativeBlas.scopy(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 ComplexFloat get(int i) {
789 return new ComplexFloat(data[i * 2], data[i * 2 + 1]);
790 }
791
792 public ComplexFloat get(int i, ComplexFloat result) {
793 return result.set(data[i * 2], data[i*2+1]);
794 }
795
796 public float getReal(int i) {
797 return data[2*i];
798 }
799
800 public float getImag(int i) {
801 return data[2*i + 1];
802 }
803
804 public ComplexFloatMatrix put(int i, float v) {
805 data[2*i] = v;
806 return this;
807 }
808
809 public ComplexFloatMatrix put(int i, float r, float c) {
810 data[2*i] = r;
811 data[2*i+1] = c;
812 return this;
813 }
814
815 public ComplexFloatMatrix put(int i, ComplexFloat v) {
816 data[2*i] = v.real();
817 data[2*i+1] = v.imag();
818 return this;
819 }
820
821 public ComplexFloatMatrix putReal(int i, float v) {
822 return put(i, v);
823 }
824
825 public ComplexFloatMatrix putImag(int i, float 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 ComplexFloatMatrix diag() {
872 ComplexFloatMatrix d = new ComplexFloatMatrix(rows);
873 NativeBlas.ccopy(rows, data, 0, rows + 1, d.data, 0, 1);
874 return d;
875 }
876
877 /** Get real part of the matrix. */
878 public FloatMatrix real() {
879 FloatMatrix result = new FloatMatrix(rows, columns);
880 NativeBlas.scopy(length, data, 0, 2, result.data, 0, 1);
881 return result;
882 }
883
884 /** Get imaginary part of the matrix. */
885 public FloatMatrix imag() {
886 FloatMatrix result = new FloatMatrix(rows, columns);
887 NativeBlas.scopy(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 float[] toDoubleArray() {
924 float[] array = new float[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 ComplexFloat[] toArray() {
933 ComplexFloat[] array = new ComplexFloat[length];
934
935 for (int i = 0; i < length; i++)
936 array[i] = get(i);
937
938 return array;
939 }
940
941 public ComplexFloat[][] toArray2() {
942 ComplexFloat[][] array = new ComplexFloat[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(ComplexFloatMatrix other, ComplexFloatMatrix 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 ComplexFloatMatrix addi(ComplexFloatMatrix other, ComplexFloatMatrix 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(ComplexFloat.UNIT, other, result);
996 else if (result == other)
997 SimpleBlas.axpy(ComplexFloat.UNIT, this, result);
998 else {
999 SimpleBlas.copy(this, result);
1000 SimpleBlas.axpy(ComplexFloat.UNIT, other, result);
1001 }
1002
1003 return result;
1004 }
1005
1006 /** Add a scalar to a matrix. */
1007 public ComplexFloatMatrix addi(ComplexFloat v, ComplexFloatMatrix 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 ComplexFloatMatrix addi(float v, ComplexFloatMatrix result) {
1016 return addi(new ComplexFloat(v), result);
1017 }
1018
1019 /** Subtract two matrices. */
1020 public ComplexFloatMatrix subi(ComplexFloatMatrix other, ComplexFloatMatrix 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(ComplexFloat.NEG_UNIT, other, result);
1029 else if (result == other) {
1030 SimpleBlas.scal(ComplexFloat.NEG_UNIT, result);
1031 SimpleBlas.axpy(ComplexFloat.UNIT, this, result);
1032 }
1033 else {
1034 SimpleBlas.copy(this, result);
1035 SimpleBlas.axpy(ComplexFloat.NEG_UNIT, other, result);
1036 }
1037 return result;
1038 }
1039
1040 /** Subtract a scalar from a matrix */
1041 public ComplexFloatMatrix subi(ComplexFloat v, ComplexFloatMatrix 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 ComplexFloatMatrix subi(float v, ComplexFloatMatrix result) {
1050 return subi(new ComplexFloat(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 ComplexFloatMatrix rsubi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1058 return other.subi(this, result);
1059 }
1060
1061 /** Subtract a matrix from a scalar */
1062 public ComplexFloatMatrix rsubi(ComplexFloat a, ComplexFloatMatrix 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 ComplexFloatMatrix rsubi(float a, ComplexFloatMatrix result) {
1071 return rsubi(new ComplexFloat(a), result);
1072 }
1073
1074 /** (Elementwise) Multiplication */
1075 public ComplexFloatMatrix muli(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1076 if (other.isScalar())
1077 return muli(other.scalar(), result);
1078
1079 assertSameLength(other);
1080 ensureResultLength(other, result);
1081
1082 ComplexFloat c = new ComplexFloat(0.0f);
1083 ComplexFloat d = new ComplexFloat(0.0f);
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 ComplexFloatMatrix muli(ComplexFloat v, ComplexFloatMatrix result) {
1092 ensureResultLength(null, result);
1093
1094 ComplexFloat c = new ComplexFloat(0.0f);
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 ComplexFloatMatrix muli(float v, ComplexFloatMatrix result) {
1102 return muli(new ComplexFloat(v), result);
1103 }
1104
1105 /** Matrix-Matrix Multiplication */
1106 public ComplexFloatMatrix mmuli(ComplexFloatMatrix other, ComplexFloatMatrix 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 ComplexFloatMatrix temp = new ComplexFloatMatrix(result.rows, result.columns);
1124 SimpleBlas.gemm(ComplexFloat.UNIT, this, other, ComplexFloat.ZERO, temp);
1125 SimpleBlas.copy(temp, result);
1126 }
1127 else {
1128 SimpleBlas.gemm(ComplexFloat.UNIT, this, other, ComplexFloat.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 ComplexFloatMatrix mmuli(ComplexFloat v, ComplexFloatMatrix result) {
1137 return muli(v, result);
1138 }
1139
1140 public ComplexFloatMatrix mmuli(float v, ComplexFloatMatrix result) {
1141 return muli(v, result);
1142 }
1143
1144 /** (Elementwise) division */
1145 public ComplexFloatMatrix divi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1146 if (other.isScalar())
1147 return divi(other.scalar(), result);
1148
1149 assertSameLength(other);
1150 ensureResultLength(other, result);
1151
1152 ComplexFloat c1 = new ComplexFloat(0.0f);
1153 ComplexFloat c2 = new ComplexFloat(0.0f);
1154
1155 for (int i = 0; i < length; i++)
1156 result.put(i, get(i, c1).divi(other.get(i, c2)));
1157 return result;
1158 }
1159
1160 /** (Elementwise) division with a scalar */
1161 public ComplexFloatMatrix divi(ComplexFloat a, ComplexFloatMatrix result) {
1162 ensureResultLength(null, result);
1163
1164 ComplexFloat c = new ComplexFloat(0.0f);
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 ComplexFloatMatrix divi(float a, ComplexFloatMatrix result) {
1172 return divi(new ComplexFloat(a), result);
1173 }
1174
1175 /**
1176 * (Elementwise) division, with operands switched. Computes
1177 * <em>result = other / this</em>. */
1178 public ComplexFloatMatrix rdivi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1179 if (other.isScalar())
1180 return divi(other.scalar(), result);
1181
1182 assertSameLength(other);
1183 ensureResultLength(other, result);
1184
1185 ComplexFloat c1 = new ComplexFloat(0.0f);
1186 ComplexFloat c2 = new ComplexFloat(0.0f);
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 ComplexFloatMatrix rdivi(ComplexFloat a, ComplexFloatMatrix result) {
1196 ensureResultLength(null, result);
1197
1198 ComplexFloat c1 = new ComplexFloat(0.0f);
1199 ComplexFloat c2 = new ComplexFloat(0.0f);
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 ComplexFloatMatrix rdivi(float a, ComplexFloatMatrix result) {
1209 return rdivi(new ComplexFloat(a), result);
1210 }
1211
1212 public ComplexFloatMatrix negi() {
1213 ComplexFloat c = new ComplexFloat(0.0f);
1214 for (int i = 0; i < length; i++)
1215 put(i, get(i, c).negi());
1216 return this;
1217 }
1218
1219 public ComplexFloatMatrix neg() {
1220 return dup().negi();
1221 }
1222
1223 public ComplexFloatMatrix noti() {
1224 ComplexFloat c = new ComplexFloat(0.0f);
1225 for (int i = 0; i < length; i++)
1226 put(i, get(i, c).isZero() ? 1.0f : 0.0f);
1227 return this;
1228 }
1229
1230 public ComplexFloatMatrix not() {
1231 return dup().noti();
1232 }
1233
1234 public ComplexFloatMatrix truthi() {
1235 ComplexFloat c = new ComplexFloat(0.0f);
1236 for (int i = 0; i < length; i++)
1237 put(i, get(i, c).isZero() ? 0.0f : 1.0f);
1238 return this;
1239 }
1240
1241 public ComplexFloatMatrix 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 ComplexFloatMatrix rankOneUpdate(ComplexFloat alpha, ComplexFloatMatrix x, ComplexFloatMatrix 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 ComplexFloatMatrix rankOneUpdate(float alpha, ComplexFloatMatrix x, ComplexFloatMatrix y) {
1261 return rankOneUpdate(new ComplexFloat(alpha), x, y);
1262 }
1263
1264 /** Computes a rank-1-update A = A + alpha * x * x'. */
1265 public ComplexFloatMatrix rankOneUpdate(float alpha, ComplexFloatMatrix x) {
1266 return rankOneUpdate(new ComplexFloat(alpha), x, x);
1267 }
1268
1269 /** Computes a rank-1-update A = A + alpha * x * x'. */
1270 public ComplexFloatMatrix rankOneUpdate(ComplexFloat alpha, ComplexFloatMatrix x) {
1271 return rankOneUpdate(alpha, x, x);
1272 }
1273
1274 /** Computes a rank-1-update A = A + x * x'. */
1275 public ComplexFloatMatrix rankOneUpdate(ComplexFloatMatrix x) {
1276 return rankOneUpdate(1.0f, x, x);
1277 }
1278
1279 /** Computes a rank-1-update A = A + x * y'. */
1280 public ComplexFloatMatrix rankOneUpdate(ComplexFloatMatrix x, ComplexFloatMatrix y) {
1281 return rankOneUpdate(1.0f, x, y);
1282 }
1283
1284 /****************************************************************
1285 * Logical operations
1286 */
1287
1288 public ComplexFloat sum() {
1289 ComplexFloat s = new ComplexFloat(0.0f);
1290 ComplexFloat c = new ComplexFloat(0.0f);
1291 for (int i = 0; i < length; i++)
1292 s.addi(get(i, c));
1293 return s;
1294 }
1295
1296 public ComplexFloat mean() {
1297 return sum().div((float)length);
1298 }
1299
1300 /** Computes this^T * other */
1301 public ComplexFloat dotc(ComplexFloatMatrix other) {
1302 return SimpleBlas.dotc(this, other);
1303 }
1304
1305 /** Computes this^H * other */
1306 public ComplexFloat dotu(ComplexFloatMatrix other) {
1307 return SimpleBlas.dotu(this, other);
1308 }
1309
1310 public float norm2() {
1311 return SimpleBlas.nrm2(this);
1312 }
1313
1314 public float normmax() {
1315 int i = SimpleBlas.iamax(this);
1316 return get(i).abs();
1317 }
1318
1319 public float 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 ComplexFloatMatrix columnSums() {
1325 ComplexFloatMatrix v =
1326 new ComplexFloatMatrix(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 ComplexFloatMatrix columnMeans() {
1335 return columnSums().divi(rows);
1336 }
1337
1338 public ComplexFloatMatrix rowSums() {
1339 ComplexFloatMatrix v = new ComplexFloatMatrix(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 ComplexFloatMatrix rowMeans() {
1348 return rowSums().divi(columns);
1349 }
1350
1351 public ComplexFloatMatrix getColumn(int c) {
1352 ComplexFloatMatrix result = new ComplexFloatMatrix(rows, 1);
1353 NativeBlas.ccopy(rows, data, index(0, c), 1, result.data, 0, 1);
1354 return result;
1355 }
1356
1357 public void putColumn(int c, ComplexFloatMatrix v) {
1358 NativeBlas.ccopy(rows, v.data, 0, 1, data, index(0, c), 1);
1359 }
1360
1361 public ComplexFloatMatrix getRow(int r) {
1362 ComplexFloatMatrix result = new ComplexFloatMatrix(1, columns);
1363 NativeBlas.ccopy(columns, data, index(r, 0), rows, result.data, 0, 1);
1364 return result;
1365 }
1366
1367 public void putRow(int r, ComplexFloatMatrix v) {
1368 NativeBlas.ccopy(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(ComplexFloatMatrix x) {
1377 for (int r = 0; r < rows; r++) {
1378 NativeBlas.caxpy(columns, ComplexFloat.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(ComplexFloatMatrix x) {
1384 for (int c = 0; c < columns; c++) {
1385 NativeBlas.caxpy(rows, ComplexFloat.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(ComplexFloatMatrix x) {
1391 for (int r = 0; r < rows; r++) {
1392 NativeBlas.caxpy(columns, ComplexFloat.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(ComplexFloatMatrix x) {
1398 for (int c = 0; c < columns; c++) {
1399 NativeBlas.caxpy(rows, ComplexFloat.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("float");
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("float"))
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 float[MAX];
1433 for(int i=0; i < MAX;i++)
1434 data[i] = dis.readFloat();
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 ComplexFloatMatrix #{base}i(ComplexFloatMatrix other) {
1468 return #{base}i(other, this);
1469 }
1470
1471 public ComplexFloatMatrix #{base}(ComplexFloatMatrix other) {
1472 return #{base}i(other, new ComplexFloatMatrix(#{result_rows}, #{result_cols}));
1473 }
1474
1475 public ComplexFloatMatrix #{base}i(ComplexFloat v) {
1476 return #{base}i(v, this);
1477 }
1478
1479 public ComplexFloatMatrix #{base}i(float v) {
1480 return #{base}i(new ComplexFloat(v), this);
1481 }
1482
1483 public ComplexFloatMatrix #{base}(ComplexFloat v) {
1484 return #{base}i(v, new ComplexFloatMatrix(rows, columns));
1485 }
1486
1487 public ComplexFloatMatrix #{base}(float v) {
1488 return #{base}i(new ComplexFloat(v), new ComplexFloatMatrix(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 ComplexFloatMatrix #{name}i(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1502 if (other.isScalar())
1503 return #{name}i(other.scalar(), result);
1504
1505 assertSameLength(other);
1506 ensureResultLength(other, result);
1507
1508 ComplexFloat c1 = new ComplexFloat(0.0f);
1509 ComplexFloat c2 = new ComplexFloat(0.0f);
1510
1511 for (int i = 0; i < length; i++)
1512 result.put(i, get(i, c1).#{op}(other.get(i, c2)) ? 1.0f : 0.0f);
1513 return result;
1514 }
1515
1516 public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other) {
1517 return #{name}i(other, this);
1518 }
1519
1520 public ComplexFloatMatrix #{name}(ComplexFloatMatrix other) {
1521 return #{name}i(other, new ComplexFloatMatrix(rows, columns));
1522 }
1523
1524 public ComplexFloatMatrix #{name}i(ComplexFloat value, ComplexFloatMatrix result) {
1525 ensureResultLength(null, result);
1526 ComplexFloat c = new ComplexFloat(0.0f);
1527 for (int i = 0; i < length; i++)
1528 result.put(i, get(i, c).#{op}(value) ? 1.0f : 0.0f);
1529 return result;
1530 }
1531
1532 public ComplexFloatMatrix #{name}i(float value, ComplexFloatMatrix result) {
1533 return #{name}i(new ComplexFloat(value), result);
1534 }
1535
1536 public ComplexFloatMatrix #{name}i(ComplexFloat value) {
1537 return #{name}i(value, this);
1538 }
1539
1540 public ComplexFloatMatrix #{name}i(float value) {
1541 return #{name}i(new ComplexFloat(value));
1542 }
1543
1544 public ComplexFloatMatrix #{name}(ComplexFloat value) {
1545 return #{name}i(value, new ComplexFloatMatrix(rows, columns));
1546 }
1547
1548 public ComplexFloatMatrix #{name}(float value) {
1549 return #{name}i(new ComplexFloat(value));
1550 }
1551
1552 EOS
1553 end
1554 #*/
1555
1556 /*#
1557 def gen_logical(name, op); <<-EOS
1558 public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1559 assertSameLength(other);
1560 ensureResultLength(other, result);
1561
1562 ComplexFloat t1 = new ComplexFloat(0.0f);
1563 ComplexFloat t2 = new ComplexFloat(0.0f);
1564
1565 for (int i = 0; i < length; i++)
1566 result.put(i, (!get(i, t1).isZero()) #{op} (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1567 return result;
1568 }
1569
1570 public ComplexFloatMatrix #{name}i(ComplexFloatMatrix other) {
1571 return #{name}i(other, this);
1572 }
1573
1574 public ComplexFloatMatrix #{name}(ComplexFloatMatrix other) {
1575 return #{name}i(other, new ComplexFloatMatrix(rows, columns));
1576 }
1577
1578 public ComplexFloatMatrix #{name}i(ComplexFloat value, ComplexFloatMatrix result) {
1579 ensureResultLength(null, result);
1580 boolean val = !value.isZero();
1581 ComplexFloat t = new ComplexFloat(0.0f);
1582 for (int i = 0; i < length; i++)
1583 result.put(i, !get(i, t).isZero() #{op} val ? 1.0f : 0.0f);
1584 return result;
1585 }
1586
1587 public ComplexFloatMatrix #{name}i(float value, ComplexFloatMatrix result) {
1588 return #{name}i(new ComplexFloat(value), result);
1589 }
1590
1591 public ComplexFloatMatrix #{name}i(ComplexFloat value) {
1592 return #{name}i(value, this);
1593 }
1594
1595 public ComplexFloatMatrix #{name}i(float value) {
1596 return #{name}i(new ComplexFloat(value), this);
1597 }
1598
1599 public ComplexFloatMatrix #{name}(ComplexFloat value) {
1600 return #{name}i(value, new ComplexFloatMatrix(rows, columns));
1601 }
1602
1603 public ComplexFloatMatrix #{name}(float value) {
1604 return #{name}i(new ComplexFloat(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 ComplexFloatMatrix addi(ComplexFloatMatrix other) {
1625 return addi(other, this);
1626 }
1627
1628 public ComplexFloatMatrix add(ComplexFloatMatrix other) {
1629 return addi(other, new ComplexFloatMatrix(rows, columns));
1630 }
1631
1632 public ComplexFloatMatrix addi(ComplexFloat v) {
1633 return addi(v, this);
1634 }
1635
1636 public ComplexFloatMatrix addi(float v) {
1637 return addi(new ComplexFloat(v), this);
1638 }
1639
1640 public ComplexFloatMatrix add(ComplexFloat v) {
1641 return addi(v, new ComplexFloatMatrix(rows, columns));
1642 }
1643
1644 public ComplexFloatMatrix add(float v) {
1645 return addi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1646 }
1647
1648
1649 public ComplexFloatMatrix subi(ComplexFloatMatrix other) {
1650 return subi(other, this);
1651 }
1652
1653 public ComplexFloatMatrix sub(ComplexFloatMatrix other) {
1654 return subi(other, new ComplexFloatMatrix(rows, columns));
1655 }
1656
1657 public ComplexFloatMatrix subi(ComplexFloat v) {
1658 return subi(v, this);
1659 }
1660
1661 public ComplexFloatMatrix subi(float v) {
1662 return subi(new ComplexFloat(v), this);
1663 }
1664
1665 public ComplexFloatMatrix sub(ComplexFloat v) {
1666 return subi(v, new ComplexFloatMatrix(rows, columns));
1667 }
1668
1669 public ComplexFloatMatrix sub(float v) {
1670 return subi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1671 }
1672
1673
1674 public ComplexFloatMatrix rsubi(ComplexFloatMatrix other) {
1675 return rsubi(other, this);
1676 }
1677
1678 public ComplexFloatMatrix rsub(ComplexFloatMatrix other) {
1679 return rsubi(other, new ComplexFloatMatrix(rows, columns));
1680 }
1681
1682 public ComplexFloatMatrix rsubi(ComplexFloat v) {
1683 return rsubi(v, this);
1684 }
1685
1686 public ComplexFloatMatrix rsubi(float v) {
1687 return rsubi(new ComplexFloat(v), this);
1688 }
1689
1690 public ComplexFloatMatrix rsub(ComplexFloat v) {
1691 return rsubi(v, new ComplexFloatMatrix(rows, columns));
1692 }
1693
1694 public ComplexFloatMatrix rsub(float v) {
1695 return rsubi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1696 }
1697
1698
1699 public ComplexFloatMatrix divi(ComplexFloatMatrix other) {
1700 return divi(other, this);
1701 }
1702
1703 public ComplexFloatMatrix div(ComplexFloatMatrix other) {
1704 return divi(other, new ComplexFloatMatrix(rows, columns));
1705 }
1706
1707 public ComplexFloatMatrix divi(ComplexFloat v) {
1708 return divi(v, this);
1709 }
1710
1711 public ComplexFloatMatrix divi(float v) {
1712 return divi(new ComplexFloat(v), this);
1713 }
1714
1715 public ComplexFloatMatrix div(ComplexFloat v) {
1716 return divi(v, new ComplexFloatMatrix(rows, columns));
1717 }
1718
1719 public ComplexFloatMatrix div(float v) {
1720 return divi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1721 }
1722
1723
1724 public ComplexFloatMatrix rdivi(ComplexFloatMatrix other) {
1725 return rdivi(other, this);
1726 }
1727
1728 public ComplexFloatMatrix rdiv(ComplexFloatMatrix other) {
1729 return rdivi(other, new ComplexFloatMatrix(rows, columns));
1730 }
1731
1732 public ComplexFloatMatrix rdivi(ComplexFloat v) {
1733 return rdivi(v, this);
1734 }
1735
1736 public ComplexFloatMatrix rdivi(float v) {
1737 return rdivi(new ComplexFloat(v), this);
1738 }
1739
1740 public ComplexFloatMatrix rdiv(ComplexFloat v) {
1741 return rdivi(v, new ComplexFloatMatrix(rows, columns));
1742 }
1743
1744 public ComplexFloatMatrix rdiv(float v) {
1745 return rdivi(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1746 }
1747
1748
1749 public ComplexFloatMatrix muli(ComplexFloatMatrix other) {
1750 return muli(other, this);
1751 }
1752
1753 public ComplexFloatMatrix mul(ComplexFloatMatrix other) {
1754 return muli(other, new ComplexFloatMatrix(rows, columns));
1755 }
1756
1757 public ComplexFloatMatrix muli(ComplexFloat v) {
1758 return muli(v, this);
1759 }
1760
1761 public ComplexFloatMatrix muli(float v) {
1762 return muli(new ComplexFloat(v), this);
1763 }
1764
1765 public ComplexFloatMatrix mul(ComplexFloat v) {
1766 return muli(v, new ComplexFloatMatrix(rows, columns));
1767 }
1768
1769 public ComplexFloatMatrix mul(float v) {
1770 return muli(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1771 }
1772
1773
1774 public ComplexFloatMatrix mmuli(ComplexFloatMatrix other) {
1775 return mmuli(other, this);
1776 }
1777
1778 public ComplexFloatMatrix mmul(ComplexFloatMatrix other) {
1779 return mmuli(other, new ComplexFloatMatrix(rows, other.columns));
1780 }
1781
1782 public ComplexFloatMatrix mmuli(ComplexFloat v) {
1783 return mmuli(v, this);
1784 }
1785
1786 public ComplexFloatMatrix mmuli(float v) {
1787 return mmuli(new ComplexFloat(v), this);
1788 }
1789
1790 public ComplexFloatMatrix mmul(ComplexFloat v) {
1791 return mmuli(v, new ComplexFloatMatrix(rows, columns));
1792 }
1793
1794 public ComplexFloatMatrix mmul(float v) {
1795 return mmuli(new ComplexFloat(v), new ComplexFloatMatrix(rows, columns));
1796 }
1797
1798
1799 public ComplexFloatMatrix eqi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1800 if (other.isScalar())
1801 return eqi(other.scalar(), result);
1802
1803 assertSameLength(other);
1804 ensureResultLength(other, result);
1805
1806 ComplexFloat c1 = new ComplexFloat(0.0f);
1807 ComplexFloat c2 = new ComplexFloat(0.0f);
1808
1809 for (int i = 0; i < length; i++)
1810 result.put(i, get(i, c1).eq(other.get(i, c2)) ? 1.0f : 0.0f);
1811 return result;
1812 }
1813
1814 public ComplexFloatMatrix eqi(ComplexFloatMatrix other) {
1815 return eqi(other, this);
1816 }
1817
1818 public ComplexFloatMatrix eq(ComplexFloatMatrix other) {
1819 return eqi(other, new ComplexFloatMatrix(rows, columns));
1820 }
1821
1822 public ComplexFloatMatrix eqi(ComplexFloat value, ComplexFloatMatrix result) {
1823 ensureResultLength(null, result);
1824 ComplexFloat c = new ComplexFloat(0.0f);
1825 for (int i = 0; i < length; i++)
1826 result.put(i, get(i, c).eq(value) ? 1.0f : 0.0f);
1827 return result;
1828 }
1829
1830 public ComplexFloatMatrix eqi(float value, ComplexFloatMatrix result) {
1831 return eqi(new ComplexFloat(value), result);
1832 }
1833
1834 public ComplexFloatMatrix eqi(ComplexFloat value) {
1835 return eqi(value, this);
1836 }
1837
1838 public ComplexFloatMatrix eqi(float value) {
1839 return eqi(new ComplexFloat(value));
1840 }
1841
1842 public ComplexFloatMatrix eq(ComplexFloat value) {
1843 return eqi(value, new ComplexFloatMatrix(rows, columns));
1844 }
1845
1846 public ComplexFloatMatrix eq(float value) {
1847 return eqi(new ComplexFloat(value));
1848 }
1849
1850
1851 public ComplexFloatMatrix nei(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1852 if (other.isScalar())
1853 return nei(other.scalar(), result);
1854
1855 assertSameLength(other);
1856 ensureResultLength(other, result);
1857
1858 ComplexFloat c1 = new ComplexFloat(0.0f);
1859 ComplexFloat c2 = new ComplexFloat(0.0f);
1860
1861 for (int i = 0; i < length; i++)
1862 result.put(i, get(i, c1).eq(other.get(i, c2)) ? 1.0f : 0.0f);
1863 return result;
1864 }
1865
1866 public ComplexFloatMatrix nei(ComplexFloatMatrix other) {
1867 return nei(other, this);
1868 }
1869
1870 public ComplexFloatMatrix ne(ComplexFloatMatrix other) {
1871 return nei(other, new ComplexFloatMatrix(rows, columns));
1872 }
1873
1874 public ComplexFloatMatrix nei(ComplexFloat value, ComplexFloatMatrix result) {
1875 ensureResultLength(null, result);
1876 ComplexFloat c = new ComplexFloat(0.0f);
1877 for (int i = 0; i < length; i++)
1878 result.put(i, get(i, c).eq(value) ? 1.0f : 0.0f);
1879 return result;
1880 }
1881
1882 public ComplexFloatMatrix nei(float value, ComplexFloatMatrix result) {
1883 return nei(new ComplexFloat(value), result);
1884 }
1885
1886 public ComplexFloatMatrix nei(ComplexFloat value) {
1887 return nei(value, this);
1888 }
1889
1890 public ComplexFloatMatrix nei(float value) {
1891 return nei(new ComplexFloat(value));
1892 }
1893
1894 public ComplexFloatMatrix ne(ComplexFloat value) {
1895 return nei(value, new ComplexFloatMatrix(rows, columns));
1896 }
1897
1898 public ComplexFloatMatrix ne(float value) {
1899 return nei(new ComplexFloat(value));
1900 }
1901
1902
1903 public ComplexFloatMatrix andi(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1904 assertSameLength(other);
1905 ensureResultLength(other, result);
1906
1907 ComplexFloat t1 = new ComplexFloat(0.0f);
1908 ComplexFloat t2 = new ComplexFloat(0.0f);
1909
1910 for (int i = 0; i < length; i++)
1911 result.put(i, (!get(i, t1).isZero()) & (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1912 return result;
1913 }
1914
1915 public ComplexFloatMatrix andi(ComplexFloatMatrix other) {
1916 return andi(other, this);
1917 }
1918
1919 public ComplexFloatMatrix and(ComplexFloatMatrix other) {
1920 return andi(other, new ComplexFloatMatrix(rows, columns));
1921 }
1922
1923 public ComplexFloatMatrix andi(ComplexFloat value, ComplexFloatMatrix result) {
1924 ensureResultLength(null, result);
1925 boolean val = !value.isZero();
1926 ComplexFloat t = new ComplexFloat(0.0f);
1927 for (int i = 0; i < length; i++)
1928 result.put(i, !get(i, t).isZero() & val ? 1.0f : 0.0f);
1929 return result;
1930 }
1931
1932 public ComplexFloatMatrix andi(float value, ComplexFloatMatrix result) {
1933 return andi(new ComplexFloat(value), result);
1934 }
1935
1936 public ComplexFloatMatrix andi(ComplexFloat value) {
1937 return andi(value, this);
1938 }
1939
1940 public ComplexFloatMatrix andi(float value) {
1941 return andi(new ComplexFloat(value), this);
1942 }
1943
1944 public ComplexFloatMatrix and(ComplexFloat value) {
1945 return andi(value, new ComplexFloatMatrix(rows, columns));
1946 }
1947
1948 public ComplexFloatMatrix and(float value) {
1949 return andi(new ComplexFloat(value));
1950 }
1951
1952 public ComplexFloatMatrix ori(ComplexFloatMatrix other, ComplexFloatMatrix result) {
1953 assertSameLength(other);
1954 ensureResultLength(other, result);
1955
1956 ComplexFloat t1 = new ComplexFloat(0.0f);
1957 ComplexFloat t2 = new ComplexFloat(0.0f);
1958
1959 for (int i = 0; i < length; i++)
1960 result.put(i, (!get(i, t1).isZero()) | (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
1961 return result;
1962 }
1963
1964 public ComplexFloatMatrix ori(ComplexFloatMatrix other) {
1965 return ori(other, this);
1966 }
1967
1968 public ComplexFloatMatrix or(ComplexFloatMatrix other) {
1969 return ori(other, new ComplexFloatMatrix(rows, columns));
1970 }
1971
1972 public ComplexFloatMatrix ori(ComplexFloat value, ComplexFloatMatrix result) {
1973 ensureResultLength(null, result);
1974 boolean val = !value.isZero();
1975 ComplexFloat t = new ComplexFloat(0.0f);
1976 for (int i = 0; i < length; i++)
1977 result.put(i, !get(i, t).isZero() | val ? 1.0f : 0.0f);
1978 return result;
1979 }
1980
1981 public ComplexFloatMatrix ori(float value, ComplexFloatMatrix result) {
1982 return ori(new ComplexFloat(value), result);
1983 }
1984
1985 public ComplexFloatMatrix ori(ComplexFloat value) {
1986 return ori(value, this);
1987 }
1988
1989 public ComplexFloatMatrix ori(float value) {
1990 return ori(new ComplexFloat(value), this);
1991 }
1992
1993 public ComplexFloatMatrix or(ComplexFloat value) {
1994 return ori(value, new ComplexFloatMatrix(rows, columns));
1995 }
1996
1997 public ComplexFloatMatrix or(float value) {
1998 return ori(new ComplexFloat(value));
1999 }
2000
2001 public ComplexFloatMatrix xori(ComplexFloatMatrix other, ComplexFloatMatrix result) {
2002 assertSameLength(other);
2003 ensureResultLength(other, result);
2004
2005 ComplexFloat t1 = new ComplexFloat(0.0f);
2006 ComplexFloat t2 = new ComplexFloat(0.0f);
2007
2008 for (int i = 0; i < length; i++)
2009 result.put(i, (!get(i, t1).isZero()) ^ (!other.get(i, t2).isZero()) ? 1.0f : 0.0f);
2010 return result;
2011 }
2012
2013 public ComplexFloatMatrix xori(ComplexFloatMatrix other) {
2014 return xori(other, this);
2015 }
2016
2017 public ComplexFloatMatrix xor(ComplexFloatMatrix other) {
2018 return xori(other, new ComplexFloatMatrix(rows, columns));
2019 }
2020
2021 public ComplexFloatMatrix xori(ComplexFloat value, ComplexFloatMatrix result) {
2022 ensureResultLength(null, result);
2023 boolean val = !value.isZero();
2024 ComplexFloat t = new ComplexFloat(0.0f);
2025 for (int i = 0; i < length; i++)
2026 result.put(i, !get(i, t).isZero() ^ val ? 1.0f : 0.0f);
2027 return result;
2028 }
2029
2030 public ComplexFloatMatrix xori(float value, ComplexFloatMatrix result) {
2031 return xori(new ComplexFloat(value), result);
2032 }
2033
2034 public ComplexFloatMatrix xori(ComplexFloat value) {
2035 return xori(value, this);
2036 }
2037
2038 public ComplexFloatMatrix xori(float value) {
2039 return xori(new ComplexFloat(value), this);
2040 }
2041
2042 public ComplexFloatMatrix xor(ComplexFloat value) {
2043 return xori(value, new ComplexFloatMatrix(rows, columns));
2044 }
2045
2046 public ComplexFloatMatrix xor(float value) {
2047 return xori(new ComplexFloat(value));
2048 }
2049 //RJPP-END--------------------------------------------------------------
2050 }