001/* A token that contains a 2-D long 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.LongArrayMath; 040import ptolemy.math.LongMatrixMath; 041 042/////////////////////////////////////////////////////////////////// 043//// LongMatrixToken 044 045/** 046 A token that contains a 2-D long matrix. 047 048 @author Yuhong Xiong, Steve Neuendorffer 049 @version $Id$ 050 @since Ptolemy II 0.2 051 @Pt.ProposedRating Green (neuendor) 052 @Pt.AcceptedRating Yellow (cxh) 053 */ 054public class LongMatrixToken extends MatrixToken { 055 /** Construct an LongMatrixToken with a one by one matrix. The 056 * only element in the matrix has value 0 057 */ 058 public LongMatrixToken() { 059 _value = new long[1]; 060 _value[0] = 0; 061 _rowCount = 1; 062 _columnCount = 1; 063 } 064 065 /** Construct a LongMatrixToken with the specified 1-D matrix. 066 * Make a copy of the matrix and store the copy, 067 * so that changes on the specified matrix after this token is 068 * constructed will not affect the content of this token. 069 * @param value The 1-D matrix. 070 * @param rows The number of rows. 071 * @param columns The number of columns. 072 * @exception IllegalActionException If the specified matrix 073 * is null. 074 */ 075 public LongMatrixToken(long[] value, int rows, int columns) 076 throws IllegalActionException { 077 this(value, rows, columns, DO_COPY); 078 } 079 080 /** Construct a LongMatrixToken with the specified 1-D matrix. 081 * If copy is DO_COPY, make a copy of the matrix and store the copy, 082 * so that changes on the specified matrix after this token is 083 * constructed will not affect the content of this token. 084 * If copy is DO_NOT_COPY, just reference the matrix (do not copy 085 * its contents). This saves some time and memory. 086 * The argument matrix should NOT be modified after this constructor 087 * is called to preserve immutability. 088 * @param value The 1-D matrix. 089 * @param rows The number of rows. 090 * @param columns The number of columns. 091 * @param copy If this parameter is 092 * {@link ptolemy.data.MatrixToken#DO_COPY}, then the value matrix 093 * is copied. If this parameter is 094 * {@link ptolemy.data.MatrixToken#DO_NOT_COPY}, then the value matrix 095 * is NOT copied and should not be modified after construction of this 096 * object. 097 * @exception IllegalActionException If the specified matrix 098 * is null. 099 */ 100 public LongMatrixToken(long[] value, int rows, int columns, int copy) 101 throws IllegalActionException { 102 if (value == null) { 103 throw new IllegalActionException( 104 "LongMatrixToken: The specified " + "matrix is null."); 105 } 106 107 _rowCount = rows; 108 _columnCount = columns; 109 110 if (copy == DO_COPY) { 111 _value = LongArrayMath.allocCopy(value); 112 } else { 113 _value = value; 114 } 115 } 116 117 /** Construct a LongMatrixToken with the specified 2-D matrix. 118 * This method makes a copy of the matrix and stores the copy, 119 * so changes on the specified matrix after this token is 120 * constructed will not affect the content of this token. 121 * @param value The 2-D matrix used to initialize this object. 122 * @exception IllegalActionException If the specified matrix 123 * is null. 124 */ 125 public LongMatrixToken(long[][] value) throws IllegalActionException { 126 this(value, DO_COPY); 127 } 128 129 /** Construct a LongMatrixToken with the specified 2-D matrix. 130 * If copy is DO_COPY, make a copy of the matrix and store the copy, 131 * so that changes on the specified matrix after this token is 132 * constructed will not affect the content of this token. 133 * If copy is DO_NOT_COPY, just reference the matrix (do not copy 134 * its contents). This saves some time and memory. 135 * The argument matrix should NOT be modified after this constructor 136 * is called to preserve immutability. 137 * <p> 138 * Since the DO_NOT_COPY option requires some care, this constructor 139 * should be protected. 140 * @param value The 2-D matrix used to initialize this object. 141 * @param copy If this parameter is 142 * {@link ptolemy.data.MatrixToken#DO_COPY}, then the value matrix 143 * is copied. If this parameter is 144 * {@link ptolemy.data.MatrixToken#DO_NOT_COPY}, then the value matrix 145 * is NOT copied and should not be modified after construction of this 146 * object. 147 * @exception IllegalActionException If the specified matrix 148 * is null. 149 */ 150 public LongMatrixToken(long[][] value, int copy) 151 throws IllegalActionException { 152 if (value == null) { 153 throw new IllegalActionException( 154 "LongMatrixToken: The " + "specified matrix is null."); 155 } 156 157 _initialize(value, copy); 158 } 159 160 /** Construct a LongMatrixToken from the specified string. 161 * @param init A string expression of a 2-D long matrix. 162 * @exception IllegalActionException If the string does 163 * not contain a parsable 2-D long matrix. 164 */ 165 public LongMatrixToken(String init) throws IllegalActionException { 166 PtParser parser = new PtParser(); 167 ASTPtRootNode tree = parser.generateParseTree(init); 168 Token token = new ParseTreeEvaluator().evaluateParseTree(tree); 169 170 if (token instanceof LongMatrixToken) { 171 long[][] value = ((LongMatrixToken) token).longMatrix(); 172 _initialize(value, DO_COPY); 173 } else { 174 throw new IllegalActionException("A matrix token cannot be" 175 + " created from the expression '" + init + "'"); 176 } 177 } 178 179 /** Construct an LongMatrixToken from the specified array of 180 * tokens. The tokens in the array must be scalar tokens 181 * convertible into integers. 182 * @param tokens The array of tokens, which must contains 183 * rows*columns ScalarTokens. 184 * @param rows The number of rows in the matrix to be created. 185 * @param columns The number of columns in the matrix to be 186 * created. 187 * @exception IllegalActionException If the array of tokens is 188 * null, or the length of the array is not correct, or if one of 189 * the elements of the array is null, or if one of the elements 190 * of the array cannot be losslessly converted to a long. 191 */ 192 public LongMatrixToken(Token[] tokens, int rows, int columns) 193 throws IllegalActionException { 194 int elements = rows * columns; 195 196 if (tokens == null) { 197 throw new IllegalActionException( 198 "LongMatrixToken: The specified" + " array is null."); 199 } 200 201 if (tokens.length != elements) { 202 throw new IllegalActionException("LongMatrixToken: The specified" 203 + " array is not of the correct length"); 204 } 205 206 _rowCount = rows; 207 _columnCount = columns; 208 _value = new long[elements]; 209 210 for (int i = 0; i < elements; i++) { 211 Token token = tokens[i]; 212 213 if (token instanceof ScalarToken) { 214 _value[i] = ((ScalarToken) token).longValue(); 215 } else { 216 throw new IllegalActionException("LongMatrixToken: Element " + i 217 + " in the array with value " + token 218 + " is not a ScalarToken"); 219 } 220 } 221 } 222 223 /////////////////////////////////////////////////////////////////// 224 //// public methods //// 225 226 /** Convert the specified token into an instance of LongMatrixToken. 227 * This method does lossless conversion. 228 * If the argument is already an instance of LongMatrixToken, 229 * it is returned without any change. Otherwise, if the argument 230 * is below LongMatrixToken in the type hierarchy, it is converted to 231 * an instance of LongMatrixToken or one of the subclasses of 232 * LongMatrixToken and returned. If none of the above condition is 233 * met, an exception is thrown. 234 * @param token The token to be converted to a LongMatrixToken. 235 * @return A LongMatrixToken 236 * @exception IllegalActionException If the conversion cannot 237 * be carried out. 238 */ 239 public static LongMatrixToken convert(Token token) 240 throws IllegalActionException { 241 if (token instanceof LongMatrixToken) { 242 return (LongMatrixToken) token; 243 } 244 245 int compare = TypeLattice.compare(BaseType.LONG_MATRIX, token); 246 247 if (compare == CPO.LOWER || compare == CPO.INCOMPARABLE) { 248 throw new IllegalActionException( 249 notSupportedIncomparableConversionMessage(token, "[long]")); 250 } 251 252 // try long 253 // compare = TypeLattice.compare(BaseType.LONG, token); 254 // if (compare == CPO.SAME || compare == CPO.HIGHER) { 255 // LongToken tem = LongToken.convert(token); 256 // long[][] result = new long[1][1]; 257 // result[0][0] = tem.longValue(); 258 // return new LongMatrixToken(result); 259 // } 260 // try IntMatrix 261 compare = TypeLattice.compare(BaseType.INT_MATRIX, token); 262 263 if (compare == CPO.SAME || compare == CPO.HIGHER) { 264 IntMatrixToken tem = IntMatrixToken.convert(token); 265 long[][] result = tem.longMatrix(); 266 return new LongMatrixToken(result); 267 } 268 269 // The argument is below LongMatrixToken in the type hierarchy, 270 // but I don't recognize it. 271 throw new IllegalActionException( 272 notSupportedConversionMessage(token, "[long]")); 273 } 274 275 /** Convert the specified scalar token into an instance of 276 * LongMatrixToken. The resulting matrix will be square, with 277 * the number of rows and columns equal to the given size. 278 * This method does lossless conversion. 279 * @param token The token to be converted to a LongMatrixToken. 280 * @param size The number of rows and columns of the resulting matrix. 281 * @return A LongMatrixToken 282 * @exception IllegalActionException If the conversion cannot 283 * be carried out. 284 */ 285 public static Token convert(ScalarToken token, int size) 286 throws IllegalActionException { 287 // Check to make sure that the token is convertible to LONG. 288 int compare = TypeLattice.compare(BaseType.LONG, token); 289 290 if (compare == CPO.SAME || compare == CPO.HIGHER) { 291 if (token.isNil()) { 292 throw new IllegalActionException( 293 Token.notSupportedConversionMessage(token, "[long]")); 294 } 295 296 LongToken longToken = LongToken.convert(token); 297 long longValue = longToken.longValue(); 298 long[] result = new long[size * size]; 299 300 for (int i = 0; i < size; i++) { 301 result[i] = longValue; 302 } 303 304 return new LongMatrixToken(result, size, size, DO_NOT_COPY); 305 } 306 307 throw new IllegalActionException( 308 notSupportedConversionMessage(token, "[long]")); 309 } 310 311 /** Return a new matrix that is a sub-matrix of this matrix. 312 * @param rowStart The row to start on. 313 * @param colStart The column to start on. 314 * @param rowSpan The number of rows to copy. 315 * @param colSpan The number of columns to copy. 316 * @return a sub-matrix of this matrix. 317 * @exception IllegalActionException If the returned matrix is empty or if the specified 318 * parameters result in out of bounds accesses. 319 */ 320 @Override 321 public MatrixToken crop(int rowStart, int colStart, int rowSpan, 322 int colSpan) throws IllegalActionException { 323 long[][] value = this.longMatrix(); 324 try { 325 long[][] result = LongMatrixMath.crop(value, rowStart, colStart, 326 rowSpan, colSpan); 327 return new LongMatrixToken(result); 328 } catch (ArrayIndexOutOfBoundsException ex) { 329 throw new IllegalActionException( 330 "Matrix crop indices out of bounds (rowStart = " + rowStart 331 + ", colStart = " + colStart + ", rowSpan = " 332 + rowSpan + ", colSpan = " + colSpan + ")."); 333 } 334 } 335 336 /** Return true if the argument is an instance of LongMatrixToken 337 * of the same dimensions and the corresponding elements of the matrices 338 * are equal. 339 * @param object An instance of Object. 340 * @return True if the argument is an instance of LongMatrixToken 341 * of the same dimensions and the corresponding elements of the 342 * matrices are equal. 343 */ 344 @Override 345 public boolean equals(Object object) { 346 if (object == null) { 347 return false; 348 } 349 // This test rules out instances of a subclass. 350 if (object.getClass() != getClass()) { 351 return false; 352 } 353 354 LongMatrixToken matrixArgument = (LongMatrixToken) object; 355 356 if (_rowCount != matrixArgument.getRowCount()) { 357 return false; 358 } 359 360 if (_columnCount != matrixArgument.getColumnCount()) { 361 return false; 362 } 363 364 long[] value = matrixArgument._value; 365 int elements = _rowCount * _columnCount; 366 367 for (int i = 0; i < elements; i++) { 368 if (_value[i] != value[i]) { 369 return false; 370 } 371 } 372 373 return true; 374 } 375 376 /** Return the number of columns in the matrix. 377 * @return The number of columns in the matrix. 378 */ 379 @Override 380 public int getColumnCount() { 381 return _columnCount; 382 } 383 384 /** Return the element of the matrix at the specified 385 * row and column in a LongToken. 386 * @param row The row index of the desired element. 387 * @param column The column index of the desired element. 388 * @return A LongToken containing the matrix element. 389 * @exception ArrayIndexOutOfBoundsException If the specified 390 * row or column number is outside the range of the matrix. 391 */ 392 @Override 393 public Token getElementAsToken(int row, int column) 394 throws ArrayIndexOutOfBoundsException { 395 return new LongToken(_value[row * _columnCount + column]); 396 } 397 398 /** Return the element of the contained matrix at the specified 399 * row and column. 400 * @param row The row index of the desired element. 401 * @param column The column index of the desired element. 402 * @return The long at the specified matrix entry. 403 * @exception ArrayIndexOutOfBoundsException If the specified 404 * row or column number is outside the range of the matrix. 405 */ 406 public long getElementAt(int row, int column) { 407 return _value[row * _columnCount + column]; 408 } 409 410 /** Return the Type of the tokens contained in this matrix token. 411 * This must be a type representing a scalar token. 412 * @return BaseType.LONG. 413 */ 414 @Override 415 public Type getElementType() { 416 return BaseType.LONG; 417 } 418 419 /** Return the number of rows in the matrix. 420 * @return The number of rows in the matrix. 421 */ 422 @Override 423 public int getRowCount() { 424 return _rowCount; 425 } 426 427 /** Return the type of this token. 428 * @return BaseType.LONG_MATRIX 429 */ 430 @Override 431 public Type getType() { 432 return BaseType.LONG_MATRIX; 433 } 434 435 /** Return a hash code value for this token. This method returns the 436 * sum of the elements, casted to integer. 437 * @return A hash code value for this token. 438 */ 439 @Override 440 public int hashCode() { 441 long code = 0; 442 int elements = _rowCount * _columnCount; 443 444 for (int i = 0; i < elements; i++) { 445 code += _value[i]; 446 } 447 448 return (int) code; 449 } 450 451 /** Join a matrix of matrices into a single matrix by tiling. 452 * All matrices in the matrix must be of the same type, 453 * the same type as this matrix. But none of them needs to 454 * actually be this matrix. This base class simply throws 455 * an exception. Derived classes provide the implementation. 456 * The number of columns in the resulting matrix is the sum 457 * of the number of columns in the first row of the argument. 458 * The number of rows in the resulting matrix is the sum 459 * of the number of rows in the first column of the argument. 460 * The matrices are copied into the result starting at the 461 * position determined by the first row or column. 462 * If the matrices overlap, then while copying left to right, 463 * top-to-bottom, data will be overwritten. If there are gaps, 464 * the resulting matrix will be filled with zeros. 465 * @param matrices A two-dimensional array of matrix tokens. 466 * @return A new matrix token of the same type as the elements 467 * in the input matrix of matrix tokens. 468 * @exception IllegalActionException If the types of the matrices 469 * in the input are not all the same, or if tiling fails due 470 * to size incompatibilities, or if the input matrix has no 471 * tokens. 472 */ 473 @Override 474 public MatrixToken join(MatrixToken[][] matrices) 475 throws IllegalActionException { 476 if (matrices == null || matrices.length == 0 477 || matrices[0].length == 0) { 478 throw new IllegalActionException("matrixJoin: No input matrices."); 479 } 480 // Calculate the size of the result. 481 // This assumes the matrices tile. 482 int rows = 0; 483 int columns = 0; 484 for (MatrixToken[] matrice : matrices) { 485 rows += matrice[0].getRowCount(); 486 } 487 for (int j = 0; j < matrices[0].length; j++) { 488 columns += matrices[0][j].getColumnCount(); 489 } 490 long[][] tiled = new long[rows][columns]; 491 int row = 0; 492 for (int i = 0; i < matrices.length; i++) { 493 int column = 0; 494 for (int j = 0; j < matrices[i].length; j++) { 495 if (!(matrices[i][j] instanceof LongMatrixToken)) { 496 throw new IllegalActionException( 497 "matrixJoin: matrices not all of the same type."); 498 } 499 int rowCount = matrices[i][j].getRowCount(); 500 if (row + rowCount > rows) { 501 rowCount = rows - row; 502 } 503 int columnCount = matrices[i][j].getColumnCount(); 504 if (column + columnCount > columns) { 505 columnCount = columns - column; 506 } 507 LongMatrixMath.matrixCopy(matrices[i][j].longMatrix(), 0, 0, 508 tiled, row, column, rowCount, columnCount); 509 // Starting position for the next column. 510 column += matrices[0][j].getColumnCount(); 511 } 512 // Starting position for the next column. 513 row += matrices[i][0].getRowCount(); 514 } 515 return new LongMatrixToken(tiled); 516 } 517 518 /** Return the content in the token as a 2-D long matrix. 519 * The returned matrix is a copy so the caller is free to 520 * modify it. 521 * @return A 2-D long matrix. 522 */ 523 @Override 524 public long[][] longMatrix() { 525 return LongMatrixMath.toMatrixFromArray(_value, _rowCount, 526 _columnCount); 527 } 528 529 /** Return a new Token representing the left multiplicative 530 * identity. The returned token contains an identity matrix 531 * whose dimensions are the same as the number of rows of 532 * the matrix contained in this token. 533 * @return A new LongMatrixToken containing the left multiplicative 534 * identity. 535 */ 536 @Override 537 public Token one() { 538 try { 539 return new LongMatrixToken(LongMatrixMath.identity(_rowCount), 540 DO_NOT_COPY); 541 } catch (IllegalActionException illegalAction) { 542 // should not happen 543 throw new InternalErrorException( 544 "LongMatrixToken.one: " + "Cannot create identity matrix."); 545 } 546 } 547 548 /** Return a new Token representing the right multiplicative 549 * identity. The returned token contains an identity matrix 550 * whose dimensions are the same as the number of columns of 551 * the matrix contained in this token. 552 * @return A new LongMatrixToken containing the right multiplicative 553 * identity. 554 */ 555 @Override 556 public Token oneRight() { 557 try { 558 return new LongMatrixToken(LongMatrixMath.identity(_columnCount), 559 DO_NOT_COPY); 560 } catch (IllegalActionException illegalAction) { 561 // should not happen 562 throw new InternalErrorException("LongMatrixToken.oneRight: " 563 + "Cannot create identity matrix."); 564 } 565 } 566 567 /** Split this matrix into multiple matrices. See the base 568 * class for documentation. 569 * @param rows The number of rows per submatrix. 570 * @param columns The number of columns per submatrix. 571 * @return An array of matrix tokens. 572 */ 573 @Override 574 public MatrixToken[][] split(int[] rows, int[] columns) { 575 MatrixToken[][] result = new MatrixToken[rows.length][columns.length]; 576 long[][] source = longMatrix(); 577 int row = 0; 578 for (int i = 0; i < rows.length; i++) { 579 int column = 0; 580 for (int j = 0; j < columns.length; j++) { 581 long[][] contents = new long[rows[i]][columns[j]]; 582 int rowspan = rows[i]; 583 if (row + rowspan > source.length) { 584 rowspan = source.length - row; 585 } 586 int columnspan = columns[j]; 587 if (column + columnspan > source[0].length) { 588 columnspan = source[0].length - column; 589 } 590 if (columnspan > 0 && rowspan > 0) { 591 LongMatrixMath.matrixCopy(source, row, column, contents, 0, 592 0, rowspan, columnspan); 593 } 594 column += columns[j]; 595 try { 596 result[i][j] = new LongMatrixToken(contents); 597 } catch (IllegalActionException e) { 598 throw new InternalErrorException(e); 599 } 600 } 601 row += rows[i]; 602 } 603 return result; 604 } 605 606 /** Return a new Token representing the additive identity. 607 * The returned token contains a matrix whose elements are 608 * all zero, and the size of the matrix is the same as the 609 * matrix contained in this token. 610 * @return A new LongMatrixToken containing the additive identity. 611 */ 612 @Override 613 public Token zero() { 614 try { 615 return new LongMatrixToken(new long[_rowCount * _columnCount], 616 _rowCount, _columnCount, DO_NOT_COPY); 617 } catch (IllegalActionException illegalAction) { 618 // should not happen 619 throw new InternalErrorException( 620 "LongMatrixToken.zero: " + "Cannot create zero matrix."); 621 } 622 } 623 624 /////////////////////////////////////////////////////////////////// 625 //// protected methods //// 626 627 /** Return a new token whose value is the value of the argument 628 * Token added to the value of this Token. It is assumed that 629 * the type of the argument is LongMatrixToken. 630 * @param rightArgument The token to add to this token. 631 * @exception IllegalActionException If the units are not 632 * compatible, or this operation is not supported by the derived 633 * class. 634 * @return A new LongMatrixToken containing the result. 635 */ 636 @Override 637 protected MatrixToken _add(MatrixToken rightArgument) 638 throws IllegalActionException { 639 LongMatrixToken convertedArgument = (LongMatrixToken) rightArgument; 640 long[] result = LongArrayMath 641 .add(convertedArgument._getInternalLongArray(), _value); 642 return new LongMatrixToken(result, _rowCount, _columnCount, 643 DO_NOT_COPY); 644 } 645 646 /** Return a new token whose value is the value of the argument 647 * Token added to the value of each element of this Token. It is 648 * assumed that the type of the argument is the same as the type 649 * of each element of this class or is a matrix with one element. 650 * @param rightArgument The token to add to this token. 651 * @exception IllegalActionException If this operation is not 652 * supported by the derived class. 653 * @return A new Token containing the result. 654 */ 655 @Override 656 protected MatrixToken _addElement(Token rightArgument) 657 throws IllegalActionException { 658 long scalar; 659 if (rightArgument instanceof LongMatrixToken) { 660 if (((LongMatrixToken) rightArgument).getRowCount() != 1 661 || ((LongMatrixToken) rightArgument) 662 .getColumnCount() != 1) { 663 // Throw an exception. 664 return super._moduloElement(rightArgument); 665 } 666 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 667 } else { 668 scalar = ((LongToken) rightArgument).longValue(); 669 } 670 long[] result = LongArrayMath.add(_value, scalar); 671 return new LongMatrixToken(result, _rowCount, _columnCount, 672 DO_NOT_COPY); 673 } 674 675 /** Return a new token whose elements are the result of dividing 676 * the elements of this token by the argument. It is 677 * assumed that the type of the argument is the same as the type 678 * of each element of this class or is a matrix with one element. 679 * @param rightArgument The token that divides this token. 680 * @exception IllegalActionException If this operation is not 681 * supported by the derived class. 682 * @return A new Token containing the result. 683 */ 684 @Override 685 protected MatrixToken _divideElement(Token rightArgument) 686 throws IllegalActionException { 687 long scalar; 688 if (rightArgument instanceof LongMatrixToken) { 689 if (((LongMatrixToken) rightArgument).getRowCount() != 1 690 || ((LongMatrixToken) rightArgument) 691 .getColumnCount() != 1) { 692 // Throw an exception. 693 return super._moduloElement(rightArgument); 694 } 695 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 696 } else { 697 scalar = ((LongToken) rightArgument).longValue(); 698 } 699 long[] result = LongArrayMath.divide(_value, scalar); 700 return new LongMatrixToken(result, _rowCount, _columnCount, 701 DO_NOT_COPY); 702 } 703 704 /** Return a reference to the internal 2-D matrix of longs that 705 * represents this Token. Because no copying is done, the contents 706 * must NOT be modified to preserve the immutability of Token. 707 * @return A 2-D long matrix. 708 */ 709 protected long[] _getInternalLongArray() { 710 return _value; 711 } 712 713 /** Return a new token whose elements are the remainders of 714 * the elements of this token when divided by the argument. 715 * It is guaranteed by the caller that the type of the argument 716 * is the same as the type of each element of this class 717 * or is a matrix with one element. 718 * @param rightArgument The token that performs modulo on this token. 719 * @exception IllegalActionException If this operation is not 720 * supported by the derived class. 721 * @return A new Token containing the result. 722 */ 723 @Override 724 protected MatrixToken _moduloElement(Token rightArgument) 725 throws IllegalActionException { 726 long scalar; 727 if (rightArgument instanceof LongMatrixToken) { 728 if (((LongMatrixToken) rightArgument).getRowCount() != 1 729 || ((LongMatrixToken) rightArgument) 730 .getColumnCount() != 1) { 731 // Throw an exception. 732 return super._moduloElement(rightArgument); 733 } 734 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 735 } else { 736 scalar = ((LongToken) rightArgument).longValue(); 737 } 738 long[] result = LongArrayMath.modulo(_value, scalar); 739 return new LongMatrixToken(result, _rowCount, _columnCount, 740 DO_NOT_COPY); 741 } 742 743 /** Return a new token whose value is the value of this token 744 * multiplied by the value of the argument token. It is assumed 745 * that the type of the argument is LongMatrixToken. 746 * @param rightArgument The token to multiply this token by. 747 * @exception IllegalActionException If the units are not 748 * compatible, or this operation is not supported by the derived 749 * class. 750 * @return A new LongMatrixToken containing the result. 751 */ 752 @Override 753 protected MatrixToken _multiply(MatrixToken rightArgument) 754 throws IllegalActionException { 755 LongMatrixToken convertedArgument = (LongMatrixToken) rightArgument; 756 long[] A = _value; 757 long[] B = convertedArgument._getInternalLongArray(); 758 int m = _rowCount; 759 int n = _columnCount; 760 int p = convertedArgument.getColumnCount(); 761 long[] newMatrix = new long[m * p]; 762 int in = 0; 763 int ta = 0; 764 765 for (int i = 0; i < m; i++) { 766 ta += n; 767 768 for (int j = 0; j < p; j++) { 769 long sum = 0; 770 int ib = j; 771 772 for (int ia = i * n; ia < ta; ia++, ib += p) { 773 sum += A[ia] * B[ib]; 774 } 775 776 newMatrix[in++] = sum; 777 } 778 } 779 780 return new LongMatrixToken(newMatrix, m, p, DO_NOT_COPY); 781 } 782 783 /** Return a new token whose value is the value of this token 784 * multiplied by the value of the argument scalar token. 785 * @param rightArgument The token to multiply this token by. 786 * @exception IllegalActionException If this method is not 787 * supported by the derived class. 788 * @return A new LongMatrixToken containing the result. 789 */ 790 @Override 791 protected MatrixToken _multiplyElement(Token rightArgument) 792 throws IllegalActionException { 793 long scalar; 794 if (rightArgument instanceof LongMatrixToken) { 795 if (((LongMatrixToken) rightArgument).getRowCount() != 1 796 || ((LongMatrixToken) rightArgument) 797 .getColumnCount() != 1) { 798 // Throw an exception. 799 return super._moduloElement(rightArgument); 800 } 801 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 802 } else { 803 scalar = ((LongToken) rightArgument).longValue(); 804 } 805 long[] result = LongArrayMath.multiply(_value, scalar); 806 return new LongMatrixToken(result, _rowCount, _columnCount, 807 DO_NOT_COPY); 808 } 809 810 /** Return a new token whose value is the value of the argument token 811 * subtracted from the value of this token. It is assumed that the 812 * type of the argument is LongMatrixToken. 813 * @param rightArgument The token to subtract from this token. 814 * @exception IllegalActionException If the units are not 815 * compatible, or this operation is not supported by the derived 816 * class. 817 * @return A new LongMatrixToken containing the result. 818 */ 819 @Override 820 protected MatrixToken _subtract(MatrixToken rightArgument) 821 throws IllegalActionException { 822 LongMatrixToken convertedArgument = (LongMatrixToken) rightArgument; 823 long[] result = LongArrayMath.subtract(_value, 824 convertedArgument._getInternalLongArray()); 825 return new LongMatrixToken(result, _rowCount, _columnCount, 826 DO_NOT_COPY); 827 } 828 829 /** Return a new token whose value is the value of the argument 830 * Token subtracted from the value of each element of this Token. It is 831 * assumed that the type of the argument is the same as the type 832 * of each element of this class or is a matrix with one element. 833 * @param rightArgument The token to subtract from this token. 834 * @exception IllegalActionException If this operation is not 835 * supported by the derived class. 836 * @return A new Token containing the result. 837 */ 838 @Override 839 protected MatrixToken _subtractElement(Token rightArgument) 840 throws IllegalActionException { 841 long scalar; 842 if (rightArgument instanceof LongMatrixToken) { 843 if (((LongMatrixToken) rightArgument).getRowCount() != 1 844 || ((LongMatrixToken) rightArgument) 845 .getColumnCount() != 1) { 846 // Throw an exception. 847 return super._moduloElement(rightArgument); 848 } 849 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 850 } else { 851 scalar = ((LongToken) rightArgument).longValue(); 852 } 853 long[] result = LongArrayMath.add(_value, -scalar); 854 return new LongMatrixToken(result, _rowCount, _columnCount, 855 DO_NOT_COPY); 856 } 857 858 /** Return a new token whose value is the value of the argument 859 * Token subtracted from the value of each element of this Token. It is 860 * assumed that the type of the argument is the same as the type 861 * of each element of this class or is a matrix with one element. 862 * @param rightArgument The token to subtract from this token. 863 * @exception IllegalActionException If this operation is not 864 * supported by the derived class. 865 * @return A new Token containing the result. 866 */ 867 @Override 868 protected MatrixToken _subtractElementReverse(Token rightArgument) 869 throws IllegalActionException { 870 long scalar; 871 if (rightArgument instanceof LongMatrixToken) { 872 if (((LongMatrixToken) rightArgument).getRowCount() != 1 873 || ((LongMatrixToken) rightArgument) 874 .getColumnCount() != 1) { 875 // Throw an exception. 876 return super._moduloElement(rightArgument); 877 } 878 scalar = ((LongMatrixToken) rightArgument).getElementAt(0, 0); 879 } else { 880 scalar = ((LongToken) rightArgument).longValue(); 881 } 882 long[] result = LongArrayMath 883 .negative(LongArrayMath.add(_value, -scalar)); 884 return new LongMatrixToken(result, _rowCount, _columnCount, 885 DO_NOT_COPY); 886 } 887 888 /////////////////////////////////////////////////////////////////// 889 //// private methods //// 890 // Initialize the row and column count and copy the specified 891 // matrix. This method is used by the constructors. 892 private void _initialize(long[][] value, int copy) { 893 _rowCount = value.length; 894 _columnCount = value[0].length; 895 _value = LongMatrixMath.fromMatrixToArray(value); 896 } 897 898 /////////////////////////////////////////////////////////////////// 899 //// private variables //// 900 private long[] _value; 901 902 private int _rowCount; 903 904 private int _columnCount; 905}