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