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 }