1 2 package JSci.maths.matrices; 3 4 import JSci.maths.ExtraMath; 5 import JSci.maths.Mapping; 6 import JSci.maths.DimensionException; 7 import JSci.maths.MaximumIterationsExceededException; 8 import JSci.maths.vectors.AbstractIntegerVector; 9 import JSci.maths.vectors.IntegerVector; 10 import JSci.maths.groups.AbelianGroup; 11 import JSci.maths.algebras.*; 12 import JSci.maths.fields.*; 13 14 19 public class IntegerDiagonalMatrix extends AbstractIntegerSquareMatrix implements DiagonalMatrix { 20 23 protected final int diag[]; 24 28 public IntegerDiagonalMatrix(final int size) { 29 this(new int[size]); 30 } 31 37 public IntegerDiagonalMatrix(final int array[][]) { 38 this(array.length); 39 for(int i=0;i<array.length;i++) { 40 if(array[i].length != array.length) 41 throw new MatrixDimensionException("Array is not square."); 42 diag[i]=array[i][i]; 43 } 44 } 45 49 public IntegerDiagonalMatrix(final int array[]) { 50 super(array.length); 51 diag=array; 52 } 53 57 public static IntegerDiagonalMatrix identity(final int size) { 58 int array[]=new int[size]; 59 for(int i=0;i<size;i++) 60 array[i]=1; 61 return new IntegerDiagonalMatrix(array); 62 } 63 67 public boolean equals(AbstractIntegerMatrix m, double tol) { 68 if(m instanceof DiagonalMatrix) { 69 if(numRows != m.rows() || numCols != m.columns()) 70 return false; 71 int sumSqr = 0; 72 int delta = diag[0] - m.getElement(0,0); 73 sumSqr += delta*delta; 74 for(int i=1;i<numRows;i++) { 75 delta = diag[i] - m.getElement(i,i); 76 sumSqr += delta*delta; 77 } 78 return (sumSqr <= tol*tol); 79 } else { 80 return false; 81 } 82 } 83 86 public String toString() { 87 final StringBuffer buf=new StringBuffer (5*numRows*numCols); 88 for(int i=0;i<numRows;i++) { 89 for(int j=0;j<numCols;j++) { 90 buf.append(getElement(i,j)); 91 buf.append(' '); 92 } 93 buf.append('\n'); 94 } 95 return buf.toString(); 96 } 97 101 public AbstractDoubleMatrix toDoubleMatrix() { 102 final double array[]=new double[numRows]; 103 for(int i=0;i<numRows;i++) 104 array[i]=diag[i]; 105 return new DoubleDiagonalMatrix(array); 106 } 107 111 public AbstractComplexMatrix toComplexMatrix() { 112 final double array[]=new double[numRows]; 113 for(int i=0;i<numRows;i++) 114 array[i]=diag[i]; 115 return new ComplexDiagonalMatrix(array,new double[numRows]); 116 } 117 123 public int getElement(int i, int j) { 124 if(i>=0 && i<numRows && j>=0 && j<numCols) { 125 if(i == j) 126 return diag[i]; 127 else 128 return 0; 129 } else 130 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 131 } 132 140 public void setElement(int i, int j, final int x) { 141 if(i>=0 && i<numRows && j>=0 && j<numCols) { 142 if(i == j) 143 diag[i] = x; 144 else 145 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 146 } else 147 throw new MatrixDimensionException(getInvalidElementMsg(i,j)); 148 } 149 152 public boolean isSymmetric() { 153 return true; 154 } 155 158 public int det() { 159 int det=diag[0]; 160 for(int i=1;i<numRows;i++) 161 det*=diag[i]; 162 return det; 163 } 164 167 public int trace() { 168 int tr=diag[0]; 169 for(int i=1;i<numRows;i++) 170 tr+=diag[i]; 171 return tr; 172 } 173 177 public int infNorm() { 178 int result=Math.abs(diag[0]); 179 int tmpResult; 180 for(int i=1;i<numRows;i++) { 181 tmpResult=Math.abs(diag[i]); 182 if(tmpResult>result) 183 result=tmpResult; 184 } 185 return result; 186 } 187 191 public double frobeniusNorm() { 192 double result=diag[0]; 193 for(int i=1;i<numRows;i++) 194 result=ExtraMath.hypot(result,diag[i]); 195 return result; 196 } 197 201 public double operatorNorm() throws MaximumIterationsExceededException { 202 return infNorm(); 203 } 204 205 209 211 216 public AbstractIntegerSquareMatrix add(final AbstractIntegerSquareMatrix m) { 217 if(m instanceof IntegerDiagonalMatrix) 218 return add((IntegerDiagonalMatrix)m); 219 if(m instanceof DiagonalMatrix) 220 return addDiagonal(m); 221 if(m instanceof IntegerTridiagonalMatrix) 222 return add((IntegerTridiagonalMatrix)m); 223 if(m instanceof TridiagonalMatrix) 224 return addTridiagonal(m); 225 if(m instanceof IntegerSquareMatrix) 226 return add((IntegerSquareMatrix)m); 227 228 if(numRows==m.rows() && numCols==m.columns()) { 229 final int array[][]=new int[numRows][numCols]; 230 for(int i=0;i<numRows;i++) { 231 array[i][0]=m.getElement(i,0); 232 for(int j=1;j<numCols;j++) 233 array[i][j]=m.getElement(i,j); 234 } 235 for(int i=0; i<numRows; i++) 236 array[i][i] += diag[i]; 237 return new IntegerSquareMatrix(array); 238 } else { 239 throw new MatrixDimensionException("Matrices are different sizes."); 240 } 241 } 242 public IntegerSquareMatrix add(final IntegerSquareMatrix m) { 243 if(numRows==m.numRows && numCols==m.numCols) { 244 final int array[][]=new int[numRows][numCols]; 245 for(int i=0;i<numRows;i++) 246 System.arraycopy(m.matrix[i],0,array[i],0,numRows); 247 for(int i=0; i<numRows; i++) 248 array[i][i] += diag[i]; 249 return new IntegerSquareMatrix(array); 250 } else 251 throw new MatrixDimensionException("Matrices are different sizes."); 252 } 253 258 public IntegerTridiagonalMatrix add(final IntegerTridiagonalMatrix m) { 259 if(numRows==m.numRows) { 260 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(numRows); 261 System.arraycopy(m.ldiag,0,ans.ldiag,0,m.ldiag.length); 262 System.arraycopy(m.udiag,0,ans.udiag,0,m.udiag.length); 263 ans.diag[0]=diag[0]+m.diag[0]; 264 for(int i=1;i<numRows;i++) 265 ans.diag[i]=diag[i]+m.diag[i]; 266 return ans; 267 } else 268 throw new MatrixDimensionException("Matrices are different sizes."); 269 } 270 private IntegerTridiagonalMatrix addTridiagonal(final AbstractIntegerSquareMatrix m) { 271 int mRow=numRows; 272 if(mRow==m.rows()) { 273 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(mRow); 274 ans.diag[0]=diag[0]+m.getElement(0,0); 275 ans.udiag[0]=m.getElement(0,1); 276 mRow--; 277 for(int i=1;i<mRow;i++) { 278 ans.ldiag[i]=m.getElement(i,i-1); 279 ans.diag[i]=diag[i]+m.getElement(i,i); 280 ans.udiag[i]=m.getElement(i,i+1); 281 } 282 ans.ldiag[mRow]=m.getElement(mRow,mRow-1); 283 ans.diag[mRow]=diag[mRow]+m.getElement(mRow,mRow); 284 return ans; 285 } else { 286 throw new MatrixDimensionException("Matrices are different sizes."); 287 } 288 } 289 294 public IntegerDiagonalMatrix add(final IntegerDiagonalMatrix m) { 295 if(numRows==m.numRows) { 296 final int array[]=new int[numRows]; 297 array[0]=diag[0]+m.diag[0]; 298 for(int i=1;i<numRows;i++) 299 array[i]=diag[i]+m.diag[i]; 300 return new IntegerDiagonalMatrix(array); 301 } else 302 throw new MatrixDimensionException("Matrices are different sizes."); 303 } 304 private IntegerDiagonalMatrix addDiagonal(final AbstractIntegerSquareMatrix m) { 305 if(numRows==m.numRows) { 306 final int array[]=new int[numRows]; 307 array[0]=diag[0]+m.getElement(0,0); 308 for(int i=1;i<numRows;i++) 309 array[i]=diag[i]+m.getElement(i,i); 310 return new IntegerDiagonalMatrix(array); 311 } else 312 throw new MatrixDimensionException("Matrices are different sizes."); 313 } 314 315 317 322 public AbstractIntegerSquareMatrix subtract(final AbstractIntegerSquareMatrix m) { 323 if(m instanceof IntegerDiagonalMatrix) 324 return subtract((IntegerDiagonalMatrix)m); 325 if(m instanceof DiagonalMatrix) 326 return subtractDiagonal(m); 327 if(m instanceof IntegerTridiagonalMatrix) 328 return subtract((IntegerTridiagonalMatrix)m); 329 if(m instanceof TridiagonalMatrix) 330 return subtractTridiagonal(m); 331 if(m instanceof IntegerSquareMatrix) 332 return subtract((IntegerSquareMatrix)m); 333 334 if(numRows==m.rows() && numCols==m.columns()) { 335 final int array[][]=new int[numRows][numCols]; 336 for(int i=0;i<numRows;i++) { 337 array[i][0] = -m.getElement(i,0); 338 for(int j=1;j<numCols;j++) 339 array[i][j] = -m.getElement(i,j); 340 } 341 for(int i=0; i<numRows; i++) 342 array[i][i] += diag[i]; 343 return new IntegerSquareMatrix(array); 344 } else { 345 throw new MatrixDimensionException("Matrices are different sizes."); 346 } 347 } 348 public IntegerSquareMatrix subtract(final IntegerSquareMatrix m) { 349 if(numRows==m.numRows && numCols==m.numCols) { 350 final int array[][]=new int[numRows][numCols]; 351 for(int i=0;i<numRows;i++) { 352 array[i][0] = -m.matrix[i][0]; 353 for(int j=1;j<numCols;j++) 354 array[i][j] = -m.matrix[i][j]; 355 } 356 for(int i=0; i<numRows; i++) 357 array[i][i] += diag[i]; 358 return new IntegerSquareMatrix(array); 359 } else 360 throw new MatrixDimensionException("Matrices are different sizes."); 361 } 362 367 public IntegerTridiagonalMatrix subtract(final IntegerTridiagonalMatrix m) { 368 int mRow=numRows; 369 if(mRow==m.numRows) { 370 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(mRow); 371 ans.diag[0]=diag[0]-m.diag[0]; 372 ans.udiag[0]=-m.udiag[0]; 373 mRow--; 374 for(int i=1;i<mRow;i++) { 375 ans.ldiag[i]=-m.ldiag[i]; 376 ans.diag[i]=diag[i]-m.diag[i]; 377 ans.udiag[i]=-m.udiag[i]; 378 } 379 ans.ldiag[mRow]=-m.ldiag[mRow]; 380 ans.diag[mRow]=diag[mRow]-m.diag[mRow]; 381 return ans; 382 } else 383 throw new MatrixDimensionException("Matrices are different sizes."); 384 } 385 private IntegerTridiagonalMatrix subtractTridiagonal(final AbstractIntegerSquareMatrix m) { 386 int mRow=numRows; 387 if(mRow==m.rows()) { 388 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(mRow); 389 ans.diag[0]=diag[0]-m.getElement(0,0); 390 ans.udiag[0]=-m.getElement(0,1); 391 mRow--; 392 for(int i=1;i<mRow;i++) { 393 ans.ldiag[i]=-m.getElement(i,i-1); 394 ans.diag[i]=diag[i]-m.getElement(i,i); 395 ans.udiag[i]=-m.getElement(i,i+1); 396 } 397 ans.ldiag[mRow]=-m.getElement(mRow,mRow-1); 398 ans.diag[mRow]=diag[mRow]-m.getElement(mRow,mRow); 399 return ans; 400 } else { 401 throw new MatrixDimensionException("Matrices are different sizes."); 402 } 403 } 404 409 public IntegerDiagonalMatrix subtract(final IntegerDiagonalMatrix m) { 410 if(numRows==m.numRows) { 411 final int array[]=new int[numRows]; 412 array[0]=diag[0]-m.diag[0]; 413 for(int i=1;i<numRows;i++) 414 array[i]=diag[i]-m.diag[i]; 415 return new IntegerDiagonalMatrix(array); 416 } else 417 throw new MatrixDimensionException("Matrices are different sizes."); 418 } 419 private IntegerDiagonalMatrix subtractDiagonal(final AbstractIntegerSquareMatrix m) { 420 if(numRows==m.numRows) { 421 final int array[]=new int[numRows]; 422 array[0]=diag[0]-m.getElement(0,0); 423 for(int i=1;i<numRows;i++) 424 array[i]=diag[i]-m.getElement(i,i); 425 return new IntegerDiagonalMatrix(array); 426 } else 427 throw new MatrixDimensionException("Matrices are different sizes."); 428 } 429 430 432 437 public AbstractIntegerMatrix scalarMultiply(final int x) { 438 final int array[]=new int[numRows]; 439 array[0] = x*diag[0]; 440 for(int i=1;i<numRows;i++) 441 array[i] = x*diag[i]; 442 return new IntegerDiagonalMatrix(array); 443 } 444 445 447 448 450 455 public int scalarProduct(final AbstractIntegerSquareMatrix m) { 456 if(m instanceof IntegerDiagonalMatrix) 457 return scalarProduct((IntegerDiagonalMatrix)m); 458 if(m instanceof IntegerTridiagonalMatrix) 459 return scalarProduct((IntegerTridiagonalMatrix)m); 460 if(m instanceof IntegerSquareMatrix) 461 return scalarProduct((IntegerSquareMatrix)m); 462 463 if(numRows==m.rows() && numCols==m.columns()) { 464 int ans = diag[0]*m.getElement(0,0); 465 for(int i=1;i<numRows;i++) 466 ans += diag[i]*m.getElement(i,i); 467 return ans; 468 } else { 469 throw new MatrixDimensionException("Matrices are different sizes."); 470 } 471 } 472 public int scalarProduct(final IntegerSquareMatrix m) { 473 if(numRows==m.numRows && numCols==m.numCols) { 474 int ans = diag[0]*m.matrix[0][0]; 475 for(int i=1;i<numRows;i++) 476 ans += diag[i]*m.matrix[i][i]; 477 return ans; 478 } else 479 throw new MatrixDimensionException("Matrices are different sizes."); 480 } 481 public int scalarProduct(final IntegerTridiagonalMatrix m) { 482 if(numRows==m.numRows) { 483 int ans = diag[0]*m.diag[0]; 484 for(int i=1;i<numRows;i++) 485 ans += diag[i]*m.diag[i]; 486 return ans; 487 } else 488 throw new MatrixDimensionException("Matrices are different sizes."); 489 } 490 public int scalarProduct(final IntegerDiagonalMatrix m) { 491 if(numRows==m.numRows) { 492 int ans = diag[0]*m.diag[0]; 493 for(int i=1;i<numRows;i++) 494 ans += diag[i]*m.diag[i]; 495 return ans; 496 } else 497 throw new MatrixDimensionException("Matrices are different sizes."); 498 } 499 500 502 507 public AbstractIntegerVector multiply(final AbstractIntegerVector v) { 508 if(numCols==v.dimension()) { 509 final int array[]=new int[numRows]; 510 array[0]=diag[0]*v.getComponent(0); 511 for(int i=1;i<numRows;i++) 512 array[i]=diag[i]*v.getComponent(i); 513 return new IntegerVector(array); 514 } else { 515 throw new DimensionException("Matrix and vector are incompatible."); 516 } 517 } 518 524 public AbstractIntegerSquareMatrix multiply(final AbstractIntegerSquareMatrix m) { 525 if(m instanceof IntegerDiagonalMatrix) 526 return multiply((IntegerDiagonalMatrix)m); 527 if(m instanceof DiagonalMatrix) 528 return multiplyDiagonal(m); 529 if(m instanceof IntegerTridiagonalMatrix) 530 return multiply((IntegerTridiagonalMatrix)m); 531 if(m instanceof TridiagonalMatrix) 532 return multiplyTridiagonal(m); 533 if(m instanceof IntegerSquareMatrix) 534 return multiply((IntegerSquareMatrix)m); 535 536 if(numCols==m.rows()) { 537 final int mColumns = m.columns(); 538 final int array[][]=new int[numRows][mColumns]; 539 for(int i=0; i<numRows; i++) { 540 array[i][0]=diag[0]*m.getElement(i,0); 541 for(int j=1; j<mColumns; j++) 542 array[i][j]=diag[i]*m.getElement(i,j); 543 } 544 return new IntegerSquareMatrix(array); 545 } else { 546 throw new MatrixDimensionException("Incompatible matrices."); 547 } 548 } 549 public IntegerSquareMatrix multiply(final IntegerSquareMatrix m) { 550 if(numCols==m.numRows) { 551 final int array[][]=new int[numRows][m.numCols]; 552 for(int i=0; i<numRows; i++) { 553 array[i][0]=diag[0]*m.matrix[i][0]; 554 for(int j=1; j<m.numCols; j++) 555 array[i][j]=diag[i]*m.matrix[i][j]; 556 } 557 return new IntegerSquareMatrix(array); 558 } else 559 throw new MatrixDimensionException("Incompatible matrices."); 560 } 561 public IntegerTridiagonalMatrix multiply(final IntegerTridiagonalMatrix m) { 562 int mRow=numRows; 563 if(numCols==m.numRows) { 564 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(mRow); 565 ans.diag[0]=diag[0]*m.diag[0]; 566 ans.udiag[0]=diag[0]*m.udiag[0]; 567 mRow--; 568 for(int i=1;i<mRow;i++) { 569 ans.ldiag[i]=diag[i]*m.ldiag[i]; 570 ans.diag[i]=diag[i]*m.diag[i]; 571 ans.udiag[i]=diag[i]*m.udiag[i]; 572 } 573 ans.ldiag[mRow]=diag[mRow]*m.ldiag[mRow]; 574 ans.diag[mRow]=diag[mRow]*m.diag[mRow]; 575 return ans; 576 } else 577 throw new MatrixDimensionException("Incompatible matrices."); 578 } 579 private IntegerTridiagonalMatrix multiplyTridiagonal(final AbstractIntegerSquareMatrix m) { 580 int mRow=numRows; 581 if(numCols==m.rows()) { 582 final IntegerTridiagonalMatrix ans=new IntegerTridiagonalMatrix(mRow); 583 ans.diag[0]=diag[0]*m.getElement(0,0); 584 ans.udiag[0]=diag[0]*m.getElement(0,1); 585 mRow--; 586 for(int i=1;i<mRow;i++) { 587 ans.ldiag[i]=diag[i]*m.getElement(i,i-1); 588 ans.diag[i]=diag[i]*m.getElement(i,i); 589 ans.udiag[i]=diag[i]*m.getElement(i,i+1); 590 } 591 ans.ldiag[mRow]=diag[mRow]*m.getElement(mRow,mRow-1); 592 ans.diag[mRow]=diag[mRow]*m.getElement(mRow,mRow); 593 return ans; 594 } else { 595 throw new MatrixDimensionException("Incompatible matrices."); 596 } 597 } 598 public IntegerDiagonalMatrix multiply(final IntegerDiagonalMatrix m) { 599 if(numCols==m.numRows) { 600 final int array[]=new int[numRows]; 601 array[0]=diag[0]*m.diag[0]; 602 for(int i=1;i<numRows;i++) { 603 array[i]=diag[i]*m.diag[i]; 604 } 605 return new IntegerDiagonalMatrix(array); 606 } else 607 throw new MatrixDimensionException("Incompatible matrices."); 608 } 609 private IntegerDiagonalMatrix multiplyDiagonal(final AbstractIntegerSquareMatrix m) { 610 if(numCols==m.rows()) { 611 final int array[]=new int[numRows]; 612 array[0]=diag[0]*m.getElement(0,0); 613 for(int i=1;i<numRows;i++) { 614 array[i]=diag[i]*m.getElement(i,i); 615 } 616 return new IntegerDiagonalMatrix(array); 617 } else { 618 throw new MatrixDimensionException("Incompatible matrices."); 619 } 620 } 621 622 624 628 public Matrix transpose() { 629 return this; 630 } 631 632 634 638 public AbstractDoubleSquareMatrix inverse() { 639 final double array[]=new double[numRows]; 640 array[0]=1.0/diag[0]; 641 for(int i=1;i<numRows;i++) 642 array[i]=1.0/diag[i]; 643 return new DoubleDiagonalMatrix(array); 644 } 645 646 648 656 public AbstractDoubleSquareMatrix[] luDecompose(int pivot[]) { 657 if(LU!=null) { 658 if(pivot!=null) 659 System.arraycopy(LUpivot,0,pivot,0,pivot.length); 660 return LU; 661 } 662 if(pivot==null) 663 pivot=new int[numRows+1]; 664 for(int i=0;i<numRows;i++) 665 pivot[i]=i; 666 pivot[numRows]=1; 667 LU=new AbstractDoubleSquareMatrix[2]; 668 LU[0]=DoubleDiagonalMatrix.identity(numRows); 669 LU[1]=(AbstractDoubleSquareMatrix)this.toDoubleMatrix(); 670 LUpivot=new int[pivot.length]; 671 System.arraycopy(pivot,0,LUpivot,0,pivot.length); 672 return LU; 673 } 674 680 public AbstractDoubleSquareMatrix[] luDecompose() { 681 return luDecompose(null); 682 } 683 684 686 691 public AbstractDoubleSquareMatrix[] choleskyDecompose() { 692 final AbstractDoubleSquareMatrix lu[]=new AbstractDoubleSquareMatrix[2]; 693 final double array[]=new double[numRows]; 694 array[0]=Math.sqrt(diag[0]); 695 for(int i=1;i<numRows;i++) 696 array[i]=Math.sqrt(diag[i]); 697 lu[0]=new DoubleDiagonalMatrix(array); 698 lu[1]=lu[0]; 699 return lu; 700 } 701 702 704 709 public AbstractDoubleSquareMatrix[] qrDecompose() { 710 final AbstractDoubleSquareMatrix qr[]=new AbstractDoubleSquareMatrix[2]; 711 qr[0]=DoubleDiagonalMatrix.identity(numRows); 712 qr[1]=(AbstractDoubleSquareMatrix)this.toDoubleMatrix(); 713 return qr; 714 } 715 716 718 722 public AbstractDoubleSquareMatrix[] singularValueDecompose() { 723 final int N=numRows; 724 final int Nm1=N-1; 725 final double arrayU[]=new double[N]; 726 final double arrayS[]=new double[N]; 727 final double arrayV[]=new double[N]; 728 for(int i=0;i<Nm1;i++) { 729 arrayU[i]=-1.0; 730 arrayS[i]=Math.abs(diag[i]); 731 arrayV[i]=diag[i]<0.0 ? 1.0 : -1.0; 732 } 733 arrayU[Nm1]=1.0; 734 arrayS[Nm1]=Math.abs(diag[Nm1]); 735 arrayV[Nm1]=diag[Nm1]<0.0 ? -1.0 : 1.0; 736 final AbstractDoubleSquareMatrix svd[]=new AbstractDoubleSquareMatrix[3]; 737 svd[0]=new DoubleDiagonalMatrix(arrayU); 738 svd[1]=new DoubleDiagonalMatrix(arrayS); 739 svd[2]=new DoubleDiagonalMatrix(arrayV); 740 return svd; 741 } 742 743 } 744 | Popular Tags |