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