001/* A token that contains a 2-D Complex matrix. 002 003 Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.data; 029 030import ptolemy.data.expr.ASTPtRootNode; 031import ptolemy.data.expr.ParseTreeEvaluator; 032import ptolemy.data.expr.PtParser; 033import ptolemy.data.type.BaseType; 034import ptolemy.data.type.Type; 035import ptolemy.data.type.TypeLattice; 036import ptolemy.graph.CPO; 037import ptolemy.kernel.util.IllegalActionException; 038import ptolemy.kernel.util.InternalErrorException; 039import ptolemy.math.Complex; 040import ptolemy.math.ComplexMatrixMath; 041 042/////////////////////////////////////////////////////////////////// 043//// ComplexMatrixToken 044 045/** 046 A token that contains a 2-D Complex matrix. 047 048 @see ptolemy.math.Complex 049 @author Yuhong Xiong, Christopher Hylands, Steve Neuendorffer 050 @version $Id$ 051 @since Ptolemy II 0.2 052 @Pt.ProposedRating Green (neuendor) 053 @Pt.AcceptedRating Yellow (cxh) 054 */ 055public class ComplexMatrixToken extends MatrixToken { 056 /** Construct an ComplexMatrixToken with a one by one matrix. The 057 * only element in the matrix has value 0.0 058 */ 059 public ComplexMatrixToken() { 060 _rowCount = 1; 061 _columnCount = 1; 062 _value = new Complex[1][1]; 063 _value[0][0] = Complex.ZERO; 064 } 065 066 /** Construct a ComplexMatrixToken with the specified 2-D matrix. 067 * Make a copy of the matrix and store the copy, 068 * so that changes on the specified matrix after this token is 069 * constructed will not affect the content of this token. 070 * This constructor also ensures that the matrix is initialized 071 * with zeros if any of the specifies values is null. 072 * @param value The 2-D Complex matrix. 073 * @exception IllegalActionException If the specified matrix 074 * is null. 075 */ 076 public ComplexMatrixToken(final Complex[][] value) 077 throws IllegalActionException { 078 if (value == null) { 079 throw new IllegalActionException( 080 "ComplexMatrixToken: The " + "specified matrix is null."); 081 } 082 083 _initialize(value, DO_COPY); 084 } 085 086 /** Construct a ComplexMatrixToken with the specified 2-D matrix. 087 * If copy is DO_COPY, make a copy of the matrix and store the copy, 088 * so that changes on the specified matrix after this token is 089 * constructed will not affect the content of this token. 090 * If copy is DO_NOT_COPY, just reference the matrix (do not copy 091 * its contents). This saves some time and memory. 092 * The argument matrix should NOT be modified after this constructor 093 * is called to preserve immutability. 094 * <p> 095 * Since the DO_NOT_COPY option requires some care, this constructor 096 * is protected. 097 * @param value The 2-D Complex matrix. 098 * @param copy If {@link ptolemy.data.MatrixToken#DO_COPY}, the the 099 * value matrix is copied, If {@link 100 * ptolemy.data.MatrixToken#DO_NOT_COPY}, then the value matrix 101 * is not copied. 102 * @exception IllegalActionException If the specified matrix 103 * is null. 104 */ 105 public ComplexMatrixToken(final Complex[][] value, int copy) 106 throws IllegalActionException { 107 if (value == null) { 108 throw new IllegalActionException( 109 "ComplexMatrixToken: The " + "specified matrix is null."); 110 } 111 112 _initialize(value, copy); 113 } 114 115 /** Construct an ComplexMatrixToken from the specified string. 116 * @param init A string expression of a 2-D complex matrix. 117 * @exception IllegalActionException If the string does 118 * not contain a parsable 2-D complex matrix. 119 */ 120 public ComplexMatrixToken(String init) throws IllegalActionException { 121 PtParser parser = new PtParser(); 122 ASTPtRootNode tree = parser.generateParseTree(init); 123 Token token = new ParseTreeEvaluator().evaluateParseTree(tree); 124 125 if (token instanceof ComplexMatrixToken) { 126 Complex[][] value = ((ComplexMatrixToken) token).complexMatrix(); 127 _initialize(value, DO_COPY); 128 } else { 129 throw new IllegalActionException("A ComplexMatrixToken cannot be" 130 + " created from the expression '" + init + "'"); 131 } 132 } 133 134 /** Construct an ComplexMatrixToken from the specified array of 135 * tokens. The tokens in the array must be scalar tokens 136 * convertible into complex numbers. 137 * @param tokens The array of tokens, which must contains 138 * rows*columns ScalarTokens. 139 * @param rows The number of rows in the matrix to be created. 140 * @param columns The number of columns in the matrix to be 141 * created. 142 * @exception IllegalActionException If the array of tokens is 143 * null, or the length of the array is not correct, or if one of 144 * the elements of the array is null, or if one of the elements 145 * of the array cannot be losslessly converted to an integer. 146 */ 147 public ComplexMatrixToken(Token[] tokens, int rows, int columns) 148 throws IllegalActionException { 149 if (tokens == null) { 150 throw new IllegalActionException( 151 "ComplexMatrixToken: The specified" + " array is null."); 152 } 153 154 if (tokens.length != rows * columns) { 155 throw new IllegalActionException("ComplexMatrixToken: The specified" 156 + " array is not of the correct length"); 157 } 158 159 _rowCount = rows; 160 _columnCount = columns; 161 _value = new Complex[rows][columns]; 162 163 for (int i = 0; i < tokens.length; i++) { 164 Token token = tokens[i]; 165 166 if (token instanceof ScalarToken) { 167 _value[i / columns][i % columns] = ((ScalarToken) token) 168 .complexValue(); 169 } else if (token == null) { 170 _value[i / columns][i % columns] = Complex.ZERO; 171 } else { 172 throw new IllegalActionException("ComplexMatrixToken: Element " 173 + i + " in the array with value " + token 174 + " is not a ScalarToken"); 175 } 176 } 177 } 178 179 /////////////////////////////////////////////////////////////////// 180 //// public methods //// 181 182 /** Return the content of this token as a new 2-D Complex matrix. 183 * @return A 2-D Complex matrix 184 */ 185 @Override 186 public Complex[][] complexMatrix() { 187 return ComplexMatrixMath.allocCopy(_value); 188 } 189 190 /** Convert the specified token into an instance of ComplexMatrixToken. 191 * This method does lossless conversion. 192 * If the argument is already an instance of ComplexMatrixToken, 193 * it is returned without any change. Otherwise, if the argument 194 * is below ComplexMatrixToken in the type hierarchy, it is converted to 195 * an instance of ComplexMatrixToken or one of the subclasses of 196 * ComplexMatrixToken and returned. If none of the above condition is 197 * met, an exception is thrown. 198 * @param token The token to be converted to a ComplexMatrixToken. 199 * @return A ComplexMatrixToken 200 * @exception IllegalActionException If the conversion cannot 201 * be carried out. 202 */ 203 public static ComplexMatrixToken convert(Token token) 204 throws IllegalActionException { 205 if (token instanceof ComplexMatrixToken) { 206 return (ComplexMatrixToken) token; 207 } 208 209 int compare = TypeLattice.compare(BaseType.COMPLEX_MATRIX, token); 210 211 if (compare == CPO.LOWER || compare == CPO.INCOMPARABLE) { 212 throw new IllegalActionException( 213 notSupportedIncomparableConversionMessage(token, 214 "[complex]")); 215 } 216 217 // try Complex 218 // compare = TypeLattice.compare(BaseType.COMPLEX, token); 219 // if (compare == CPO.SAME || compare == CPO.HIGHER) { 220 // Complex[][] result = new Complex[1][1]; 221 // ComplexToken tem = ComplexToken.convert(token); 222 // result[0][0] = tem.complexValue(); 223 // return new ComplexMatrixToken(result); 224 // } 225 // try DoubleMatrix 226 compare = TypeLattice.compare(BaseType.DOUBLE_MATRIX, token); 227 228 if (compare == CPO.SAME || compare == CPO.HIGHER) { 229 DoubleMatrixToken tem = DoubleMatrixToken.convert(token); 230 return new ComplexMatrixToken(tem.complexMatrix()); 231 } 232 233 // The argument is below ComplexMatrixToken in the type hierarchy, 234 // but I don't recognize it. 235 throw new IllegalActionException( 236 notSupportedConversionMessage(token, "[complex]")); 237 } 238 239 /** Return a new matrix that is a sub-matrix of this matrix. 240 * @param rowStart The row to start on. 241 * @param colStart The column to start on. 242 * @param rowSpan The number of rows to copy. 243 * @param colSpan The number of columns to copy. 244 * @return a sub-matrix of this matrix. 245 * @exception IllegalActionException If the returned matrix is empty or if the specified 246 * parameters result in out of bounds accesses. 247 */ 248 @Override 249 public MatrixToken crop(int rowStart, int colStart, int rowSpan, 250 int colSpan) throws IllegalActionException { 251 Complex[][] value = this.complexMatrix(); 252 try { 253 Complex[][] result = new Complex[rowSpan][colSpan]; 254 for (int i = 0; i < rowSpan; i++) { 255 System.arraycopy(value[rowStart + i], colStart, result[i], 0, 256 colSpan); 257 } 258 return new ComplexMatrixToken(result); 259 } catch (ArrayIndexOutOfBoundsException ex) { 260 throw new IllegalActionException( 261 "Matrix crop indices out of bounds (rowStart = " + rowStart 262 + ", colStart = " + colStart + ", rowSpan = " 263 + rowSpan + ", colSpan = " + colSpan + ")."); 264 } 265 } 266 267 /** Return true if the argument is an instance of ComplexMatrixToken 268 * of the same dimensions and the corresponding elements of the matrices 269 * are equal. 270 * @param object An instance of Object. 271 * @return True if the argument is an instance of ComplexMatrixToken 272 * of the same dimensions and the corresponding elements of the 273 * matrices are equal. 274 */ 275 @Override 276 public boolean equals(Object object) { 277 if (object == null) { 278 return false; 279 } 280 // This test rules out instances of a subclass. 281 if (object.getClass() != getClass()) { 282 return false; 283 } 284 285 ComplexMatrixToken matrixArgument = (ComplexMatrixToken) object; 286 287 if (_rowCount != matrixArgument.getRowCount()) { 288 return false; 289 } 290 291 if (_columnCount != matrixArgument.getColumnCount()) { 292 return false; 293 } 294 295 Complex[][] matrix = matrixArgument.complexMatrix(); 296 297 for (int i = 0; i < _rowCount; i++) { 298 for (int j = 0; j < _columnCount; j++) { 299 if (!_value[i][j].equals(matrix[i][j])) { 300 return false; 301 } 302 } 303 } 304 305 return true; 306 } 307 308 /** Return the number of columns in the matrix. 309 * @return The number of columns in the matrix. 310 */ 311 @Override 312 public int getColumnCount() { 313 return _columnCount; 314 } 315 316 /** Return the element of the matrix at the specified 317 * row and column in a ComplexToken. 318 * @param row The row index of the desired element. 319 * @param column The column index of the desired element. 320 * @return A ComplexToken containing the matrix element. 321 * @exception ArrayIndexOutOfBoundsException If the specified 322 * row or column number is outside the range of the matrix. 323 */ 324 @Override 325 public Token getElementAsToken(final int row, final int column) 326 throws ArrayIndexOutOfBoundsException { 327 return new ComplexToken(_value[row][column]); 328 } 329 330 /** Return the element of the contained matrix at the specified 331 * row and column. 332 * @param row The row index of the desired element. 333 * @param column The column index of the desired element. 334 * @return The Complex at the specified matrix entry. 335 * @exception ArrayIndexOutOfBoundsException If the specified 336 * row or column number is outside the range of the matrix. 337 */ 338 public Complex getElementAt(final int row, final int column) { 339 return _value[row][column]; 340 } 341 342 /** Return the Type of the tokens contained in this matrix token. 343 * This must be a type representing a scalar token. 344 * @return BaseType.COMPLEX. 345 */ 346 @Override 347 public Type getElementType() { 348 return BaseType.COMPLEX; 349 } 350 351 /** Return the number of rows in the matrix. 352 * @return The number of rows in the matrix. 353 */ 354 @Override 355 public int getRowCount() { 356 return _rowCount; 357 } 358 359 /** Return the type of this token. 360 * @return BaseType.COMPLEX_MATRIX 361 */ 362 @Override 363 public Type getType() { 364 return BaseType.COMPLEX_MATRIX; 365 } 366 367 /** Return a hash code value for this token. This method returns the 368 * integer portion of the magnitude of the sum of the elements. 369 * @return A hash code value for this token. 370 */ 371 @Override 372 public int hashCode() { 373 Complex sum = new Complex(0); 374 375 for (int i = 0; i < _rowCount; i++) { 376 for (int j = 0; j < _columnCount; j++) { 377 sum = sum.add(_value[i][j]); 378 } 379 } 380 381 return (int) sum.magnitude(); 382 } 383 384 /** Join a matrix of matrices into a single matrix by tiling. 385 * All matrices in the matrix must be of the same type, 386 * the same type as this matrix. But none of them needs to 387 * actually be this matrix. This base class simply throws 388 * an exception. Derived classes provide the implementation. 389 * The number of columns in the resulting matrix is the sum 390 * of the number of columns in the first row of the argument. 391 * The number of rows in the resulting matrix is the sum 392 * of the number of rows in the first column of the argument. 393 * The matrices are copied into the result starting at the 394 * position determined by the first row or column. 395 * If the matrices overlap, then while copying left to right, 396 * top-to-bottom, data will be overwritten. If there are gaps, 397 * the resulting matrix will be filled with zeros. 398 * @param matrices A two-dimensional array of matrix tokens. 399 * @return A new matrix token of the same type as the elements 400 * in the input matrix of matrix tokens. 401 * @exception IllegalActionException If the types of the matrices 402 * in the input are not all the same, or if tiling fails due 403 * to size incompatibilities, or if the input matrix has no 404 * tokens. 405 */ 406 @Override 407 public MatrixToken join(MatrixToken[][] matrices) 408 throws IllegalActionException { 409 if (matrices == null || matrices.length == 0 410 || matrices[0].length == 0) { 411 throw new IllegalActionException("matrixJoin: No input matrices."); 412 } 413 // Calculate the size of the result. 414 // This assumes the matrices tile. 415 int rows = 0; 416 int columns = 0; 417 for (MatrixToken[] matrice : matrices) { 418 rows += matrice[0].getRowCount(); 419 } 420 for (int j = 0; j < matrices[0].length; j++) { 421 columns += matrices[0][j].getColumnCount(); 422 } 423 Complex[][] tiled = new Complex[rows][columns]; 424 int row = 0; 425 for (int i = 0; i < matrices.length; i++) { 426 int column = 0; 427 for (int j = 0; j < matrices[i].length; j++) { 428 if (!(matrices[i][j] instanceof ComplexMatrixToken)) { 429 throw new IllegalActionException( 430 "matrixJoin: matrices not all of the same type."); 431 } 432 int rowCount = matrices[i][j].getRowCount(); 433 if (row + rowCount > rows) { 434 rowCount = rows - row; 435 } 436 int columnCount = matrices[i][j].getColumnCount(); 437 if (column + columnCount > columns) { 438 columnCount = columns - column; 439 } 440 ComplexMatrixMath.matrixCopy(matrices[i][j].complexMatrix(), 0, 441 0, tiled, row, column, rowCount, columnCount); 442 // Starting position for the next column. 443 column += matrices[0][j].getColumnCount(); 444 } 445 // Starting position for the next column. 446 row += matrices[i][0].getRowCount(); 447 } 448 return new ComplexMatrixToken(tiled); 449 } 450 451 /** Split this matrix into multiple matrices. See the base 452 * class for documentation. 453 * @param rows The number of rows per submatrix. 454 * @param columns The number of columns per submatrix. 455 * @return An array of matrix tokens. 456 */ 457 @Override 458 public MatrixToken[][] split(int[] rows, int[] columns) { 459 MatrixToken[][] result = new MatrixToken[rows.length][columns.length]; 460 Complex[][] source = complexMatrix(); 461 int row = 0; 462 for (int i = 0; i < rows.length; i++) { 463 int column = 0; 464 for (int j = 0; j < columns.length; j++) { 465 Complex[][] contents = new Complex[rows[i]][columns[j]]; 466 int rowspan = rows[i]; 467 if (row + rowspan > source.length) { 468 rowspan = source.length - row; 469 } 470 int columnspan = columns[j]; 471 if (column + columnspan > source[0].length) { 472 columnspan = source[0].length - column; 473 } 474 if (columnspan > 0 && rowspan > 0) { 475 ComplexMatrixMath.matrixCopy(source, row, column, contents, 476 0, 0, rowspan, columnspan); 477 } 478 column += columns[j]; 479 try { 480 // Use the copy constructor to ensure zero fill. 481 result[i][j] = new ComplexMatrixToken(contents); 482 } catch (IllegalActionException e) { 483 throw new InternalErrorException(e); 484 } 485 } 486 row += rows[i]; 487 } 488 return result; 489 } 490 491 /** Return a new Token representing the left multiplicative 492 * identity. The returned token contains an identity matrix 493 * whose dimensions are the same as the number of rows of 494 * the matrix contained in this token. 495 * @return A new ComplexMatrixToken containing the left multiplicative 496 * identity. 497 */ 498 @Override 499 public Token one() { 500 try { 501 return new ComplexMatrixToken(ComplexMatrixMath.identity(_rowCount), 502 DO_NOT_COPY); 503 } catch (IllegalActionException illegalAction) { 504 // should not happen 505 throw new InternalErrorException("ComplexMatrixToken.one: " 506 + "Cannot create identity matrix."); 507 } 508 } 509 510 /** Return a new Token representing the right multiplicative 511 * identity. The returned token contains an identity matrix 512 * whose dimensions are the same as the number of columns of 513 * the matrix contained in this token. 514 * @return A new ComplexMatrixToken containing the right 515 * multiplicative identity. 516 */ 517 @Override 518 public Token oneRight() { 519 try { 520 return new ComplexMatrixToken( 521 ComplexMatrixMath.identity(_columnCount), DO_NOT_COPY); 522 } catch (IllegalActionException illegalAction) { 523 // should not happen 524 throw new InternalErrorException("ComplexMatrixToken.oneRight: " 525 + "Cannot create identity matrix."); 526 } 527 } 528 529 /** Return a new Token representing the additive identity. 530 * The returned token contains a matrix whose elements are 531 * all zero, and the size of the matrix is the same as the 532 * matrix contained in this token. 533 * @return A new ComplexMatrixToken containing the additive identity. 534 */ 535 @Override 536 public Token zero() { 537 try { 538 return new ComplexMatrixToken( 539 ComplexMatrixMath.zero(_rowCount, _columnCount), 540 DO_NOT_COPY); 541 } catch (IllegalActionException illegalAction) { 542 // should not happen 543 throw new InternalErrorException( 544 "ComplexMatrixToken.zero: " + "Cannot create zero matrix."); 545 } 546 } 547 548 /////////////////////////////////////////////////////////////////// 549 //// protected methods //// 550 551 /** Return a new token whose value is the value of the argument 552 * Token added to the value of this Token. It is assumed that 553 * the type of the argument is ComplexMatrixToken. 554 * @param rightArgument The token to add to this token. 555 * @exception IllegalActionException If the units are not 556 * compatible, or this operation is not supported by the derived 557 * class. 558 * @return A new ComplexMatrixToken containing the result. 559 */ 560 @Override 561 protected MatrixToken _add(MatrixToken rightArgument) 562 throws IllegalActionException { 563 ComplexMatrixToken convertedArgument = (ComplexMatrixToken) rightArgument; 564 Complex[][] result = ComplexMatrixMath.add(_value, 565 convertedArgument._getInternalComplexMatrix()); 566 return new ComplexMatrixToken(result); 567 } 568 569 /** Return a new token whose value is the value of the argument 570 * Token added to the value of each element of this Token. It is 571 * assumed that the type of the argument is the same as the type 572 * of each element of this class or is a matrix with one element. 573 * @param rightArgument The token to add to this token. 574 * @exception IllegalActionException If this operation is not 575 * supported by the derived class. 576 * @return A new ComplexMatrixToken containing the result. 577 */ 578 @Override 579 protected MatrixToken _addElement(Token rightArgument) 580 throws IllegalActionException { 581 Complex scalar; 582 if (rightArgument instanceof ComplexMatrixToken) { 583 if (((ComplexMatrixToken) rightArgument).getRowCount() != 1 584 || ((ComplexMatrixToken) rightArgument) 585 .getColumnCount() != 1) { 586 // Throw an exception. 587 return super._moduloElement(rightArgument); 588 } 589 scalar = ((ComplexMatrixToken) rightArgument).getElementAt(0, 0); 590 } else { 591 scalar = ((ComplexToken) rightArgument).complexValue(); 592 } 593 Complex[][] result = ComplexMatrixMath.add(_value, scalar); 594 return new ComplexMatrixToken(result); 595 } 596 597 /** Return a new token whose elements are the result of dividing 598 * the elements of this token by the argument. It is 599 * assumed that the type of the argument is the same as the type 600 * of each element of this class or is a matrix with one element. 601 * @param rightArgument The token that divides this token. 602 * @exception IllegalActionException If this operation is not 603 * supported by the derived class. 604 * @return A new Token containing the result. 605 */ 606 @Override 607 protected MatrixToken _divideElement(Token rightArgument) 608 throws IllegalActionException { 609 Complex scalar; 610 if (rightArgument instanceof ComplexMatrixToken) { 611 if (((ComplexMatrixToken) rightArgument).getRowCount() != 1 612 || ((ComplexMatrixToken) rightArgument) 613 .getColumnCount() != 1) { 614 // Throw an exception. 615 return super._moduloElement(rightArgument); 616 } 617 scalar = ((ComplexMatrixToken) rightArgument).getElementAt(0, 0); 618 } else { 619 scalar = ((ComplexToken) rightArgument).complexValue(); 620 } 621 Complex[][] result = ComplexMatrixMath.divide(_value, scalar); 622 return new ComplexMatrixToken(result); 623 } 624 625 /** Return a reference to the internal 2-D matrix of complex 626 * numbers that represents this Token. Because no copying is 627 * done, the contents must NOT be modified to preserve the 628 * immutability of Token. 629 * @return A 2-D complex Java matrix. 630 */ 631 protected Complex[][] _getInternalComplexMatrix() { 632 return _value; 633 } 634 635 /** Return a new token whose value is the value of the argument 636 * Token multiplied to the value of this Token. It is assumed that 637 * the type of the argument is ComplexMatrixToken. 638 * @param rightArgument The token to multiply this token by. 639 * @exception IllegalActionException If the units are not 640 * compatible, or this operation is not supported by the derived 641 * class. 642 * @return A new ComplexMatrixToken containing the result. 643 */ 644 @Override 645 protected MatrixToken _multiply(MatrixToken rightArgument) 646 throws IllegalActionException { 647 ComplexMatrixToken convertedArgument = (ComplexMatrixToken) rightArgument; 648 Complex[][] result = ComplexMatrixMath.multiply(_value, 649 convertedArgument._getInternalComplexMatrix()); 650 return new ComplexMatrixToken(result); 651 } 652 653 /** Return a new token whose value is the value of this token 654 * multiplied by the value of the argument token. 655 * @param rightArgument The token to multiply this token by. 656 * @exception IllegalActionException If this method is not 657 * supported by the derived class. 658 * @return A new ComplexMatrixToken containing the result. 659 */ 660 @Override 661 protected MatrixToken _multiplyElement(Token rightArgument) 662 throws IllegalActionException { 663 Complex scalar; 664 if (rightArgument instanceof ComplexMatrixToken) { 665 if (((ComplexMatrixToken) rightArgument).getRowCount() != 1 666 || ((ComplexMatrixToken) rightArgument) 667 .getColumnCount() != 1) { 668 // Throw an exception. 669 return super._moduloElement(rightArgument); 670 } 671 scalar = ((ComplexMatrixToken) rightArgument).getElementAt(0, 0); 672 } else { 673 scalar = ((ComplexToken) rightArgument).complexValue(); 674 } 675 Complex[][] result = ComplexMatrixMath.multiply(_value, scalar); 676 return new ComplexMatrixToken(result); 677 } 678 679 /** Return a new token whose value is the value of the argument 680 * Token subtracted to the value of this Token. It is assumed that 681 * the type of the argument is ComplexMatrixToken. 682 * @param rightArgument The token to subtract to this token. 683 * @exception IllegalActionException If the units are not 684 * compatible, or this operation is not supported by the derived 685 * class. 686 * @return A new ComplexMatrixToken containing the result. 687 */ 688 @Override 689 protected MatrixToken _subtract(MatrixToken rightArgument) 690 throws IllegalActionException { 691 ComplexMatrixToken convertedArgument = (ComplexMatrixToken) rightArgument; 692 Complex[][] result = ComplexMatrixMath.subtract(_value, 693 convertedArgument._getInternalComplexMatrix()); 694 return new ComplexMatrixToken(result); 695 } 696 697 /** Return a new token whose value is the value of the argument 698 * Token subtracted from the value of each element of this Token. It is 699 * assumed that the type of the argument is the same as the type 700 * of each element of this class or is a matrix with one element. 701 * @param rightArgument The token to subtract from this token. 702 * @exception IllegalActionException If this operation is not 703 * supported by the derived class. 704 * @return A new Token containing the result. 705 */ 706 @Override 707 protected MatrixToken _subtractElement(Token rightArgument) 708 throws IllegalActionException { 709 Complex scalar; 710 if (rightArgument instanceof ComplexMatrixToken) { 711 if (((ComplexMatrixToken) rightArgument).getRowCount() != 1 712 || ((ComplexMatrixToken) rightArgument) 713 .getColumnCount() != 1) { 714 // Throw an exception. 715 return super._moduloElement(rightArgument); 716 } 717 scalar = ((ComplexMatrixToken) rightArgument).getElementAt(0, 0); 718 } else { 719 scalar = ((ComplexToken) rightArgument).complexValue(); 720 } 721 Complex[][] result = ComplexMatrixMath.add(_value, scalar.negate()); 722 return new ComplexMatrixToken(result); 723 } 724 725 /** Return a new token whose value is the value of the argument 726 * Token subtracted from the value of each element of this Token. It is 727 * assumed that the type of the argument is the same as the type 728 * of each element of this class or is a matrix with one element. 729 * @param rightArgument The token to subtract from this token. 730 * @exception IllegalActionException If this operation is not 731 * supported by the derived class. 732 * @return A new Token containing the result. 733 */ 734 @Override 735 protected MatrixToken _subtractElementReverse(Token rightArgument) 736 throws IllegalActionException { 737 Complex scalar; 738 if (rightArgument instanceof ComplexMatrixToken) { 739 if (((ComplexMatrixToken) rightArgument).getRowCount() != 1 740 || ((ComplexMatrixToken) rightArgument) 741 .getColumnCount() != 1) { 742 // Throw an exception. 743 return super._moduloElement(rightArgument); 744 } 745 scalar = ((ComplexMatrixToken) rightArgument).getElementAt(0, 0); 746 } else { 747 scalar = ((ComplexToken) rightArgument).complexValue(); 748 } 749 Complex[][] result = ComplexMatrixMath 750 .negative(ComplexMatrixMath.add(_value, scalar.negate())); 751 return new ComplexMatrixToken(result); 752 } 753 754 /////////////////////////////////////////////////////////////////// 755 //// private methods //// 756 // initialize the row and column count and copy the specified 757 // matrix. This method is used by the constructors. 758 private void _initialize(Complex[][] value, int copy) { 759 _rowCount = value.length; 760 _columnCount = value[0].length; 761 762 if (copy == DO_NOT_COPY) { 763 _value = value; 764 } else { 765 // Can't use System.arraycopy() because we have 766 // to ensure that nulls are replaced with zero. 767 _value = new Complex[value.length][value[0].length]; 768 for (int i = 0; i < value.length; i++) { 769 for (int j = 0; j < value[0].length; j++) { 770 if (value[i][j] != null) { 771 _value[i][j] = value[i][j]; 772 } else { 773 _value[i][j] = Complex.ZERO; 774 } 775 } 776 } 777 } 778 } 779 780 /////////////////////////////////////////////////////////////////// 781 //// private variables //// 782 private Complex[][] _value = null; 783 784 private int _rowCount = 0; 785 786 private int _columnCount = 0; 787}