001/* 002 * $Id$ 003 */ 004 005package edu.jas.vector; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import org.apache.logging.log4j.LogManager; 012import org.apache.logging.log4j.Logger; 013 014import edu.jas.kern.PrettyPrint; 015import edu.jas.structure.AlgebraElem; 016import edu.jas.structure.NotInvertibleException; 017import edu.jas.structure.RingElem; 018 019 020/** 021 * GenMatrix implements a generic matrix algebra over RingElem entries. Matrix 022 * has n columns and m rows over C. 023 * @author Heinz Kredel 024 */ 025 026public class GenMatrix<C extends RingElem<C>> implements AlgebraElem<GenMatrix<C>, C> { 027 028 029 private static final Logger logger = LogManager.getLogger(GenMatrix.class); 030 031 032 public final GenMatrixRing<C> ring; 033 034 035 public final ArrayList<ArrayList<C>> matrix; 036 037 038 private int hashValue = 0; 039 040 041 /** 042 * Constructor for zero GenMatrix. 043 * @param r matrix ring 044 */ 045 public GenMatrix(GenMatrixRing<C> r) { 046 this(r, r.getZERO().matrix); 047 } 048 049 050 /** 051 * Constructor for GenMatrix. 052 * @param r matrix ring 053 * @param m matrix 054 */ 055 public GenMatrix(GenMatrixRing<C> r, List<List<C>> m) { 056 ring = r; 057 matrix = new ArrayList<ArrayList<C>>(r.rows); 058 for (List<C> row : m) { 059 ArrayList<C> nr = new ArrayList<C>(row); 060 matrix.add(nr); 061 } 062 logger.info("{} x {} matrix constructed", ring.rows, ring.cols); 063 } 064 065 066 /** 067 * Constructor for GenMatrix. 068 * @param r matrix ring 069 * @param m matrix 070 */ 071 public GenMatrix(GenMatrixRing<C> r, ArrayList<ArrayList<C>> m) { 072 if (r == null || m == null) { 073 throw new IllegalArgumentException("Empty r or m not allowed, r = " + r + ", m = " + m); 074 } 075 ring = r; 076 matrix = new ArrayList<ArrayList<C>>(m); 077 logger.info("{} x {} matrix constructed", ring.rows, ring.cols); 078 } 079 080 081 /** 082 * Constructor for GenMatrix. 083 * @param r matrix ring 084 * @param m matrix 085 */ 086 public GenMatrix(GenMatrixRing<C> r, C[][] m) { 087 ring = r; 088 matrix = new ArrayList<ArrayList<C>>(r.rows); 089 for (C[] row : m) { 090 ArrayList<C> nr = new ArrayList<C>(r.cols); 091 for (int i = 0; i < row.length; i++) { 092 nr.add(row[i]); 093 } 094 matrix.add(nr); 095 } 096 logger.info("{} x {} matrix constructed", ring.rows, ring.cols); 097 } 098 099 100 /** 101 * Get element at row i, column j. 102 * @param i row index. 103 * @param j column index. 104 * @return this(i,j). 105 */ 106 public C get(int i, int j) { 107 return matrix.get(i).get(j); 108 } 109 110 111 /** 112 * Set element at row i, column j. Mutates this matrix. 113 * @param i row index. 114 * @param j column index. 115 * @param el element to set. 116 */ 117 public void setMutate(int i, int j, C el) { 118 ArrayList<C> ri = matrix.get(i); 119 ri.set(j, el); 120 hashValue = 0; // invalidate 121 } 122 123 124 /** 125 * Set element at row i, column j. 126 * @param i row index. 127 * @param j column index. 128 * @param el element to set. 129 * @return new matrix m, with m(i,j) == el. 130 */ 131 public GenMatrix<C> set(int i, int j, C el) { 132 GenMatrix<C> mat = this.copy(); 133 mat.setMutate(i, j, el); 134 return mat; 135 } 136 137 138 /** 139 * Get column i. 140 * @param i column index. 141 * @return this(*,i) as vector. 142 */ 143 public GenVector<C> getColumn(int i) { 144 List<C> cl = new ArrayList<C>(ring.rows); 145 for (int k = 0; k < ring.rows; k++) { 146 cl.add(matrix.get(k).get(i)); 147 } 148 GenVectorModul<C> vfac = new GenVectorModul<C>(ring.coFac, ring.rows); 149 GenVector<C> col = new GenVector<C>(vfac, cl); 150 return col; 151 } 152 153 154 /** 155 * Get row i. 156 * @param i row index. 157 * @return this(i,*) as vector. 158 */ 159 public GenVector<C> getRow(int i) { 160 List<C> cl = new ArrayList<C>(ring.cols); 161 cl.addAll(matrix.get(i)); 162 GenVectorModul<C> vfac = new GenVectorModul<C>(ring.coFac, ring.cols); 163 GenVector<C> row = new GenVector<C>(vfac, cl); 164 return row; 165 } 166 167 168 /** 169 * Get diagonal. 170 * @return diagonal(this) as vector. 171 */ 172 public GenVector<C> getDiagonal() { 173 List<C> cl = new ArrayList<C>(ring.rows); 174 for (int i = 0; i < ring.rows; i++) { 175 cl.add(matrix.get(i).get(i)); 176 } 177 GenVectorModul<C> vfac = new GenVectorModul<C>(ring.coFac, ring.rows); 178 GenVector<C> dia = new GenVector<C>(vfac, cl); 179 return dia; 180 } 181 182 183 /** 184 * Get upper triangular U matrix. 185 * @return U as matrix with equal length rows. 186 */ 187 public GenMatrix<C> getUpper() { 188 final C zero = ring.coFac.getZERO(); 189 final C one = ring.coFac.getONE(); 190 List<List<C>> cl = new ArrayList<List<C>>(ring.rows); 191 for (int k = 0; k < ring.rows; k++) { 192 List<C> ul = matrix.get(k); 193 List<C> rl = new ArrayList<C>(ring.cols); 194 for (int i = 0; i < ring.cols; i++) { 195 if (i < k) { 196 rl.add(zero); 197 } else if (i >= k) { 198 rl.add(ul.get(i)); 199 // } else { 200 // if (ul.get(i).isZERO()) { 201 // rl.add(zero); 202 // } else { 203 // rl.add(one); // mat(k,k).inverse() 204 // } 205 } 206 } 207 cl.add(rl); 208 } 209 GenMatrix<C> U = new GenMatrix<C>(ring, cl); 210 return U; 211 } 212 213 214 /** 215 * Get upper triangular U matrix with diagonale 1. 216 * @return U as matrix with equal length rows and diagonale 1. 217 */ 218 public GenMatrix<C> getUpperScaled() { 219 final C zero = ring.coFac.getZERO(); 220 final C one = ring.coFac.getONE(); 221 List<List<C>> cl = new ArrayList<List<C>>(ring.rows); 222 for (int k = 0; k < ring.rows; k++) { 223 List<C> ul = matrix.get(k); 224 C kk = ul.get(k); 225 if (kk.isZERO()) { 226 kk = one; 227 } else { 228 kk = kk.inverse(); 229 } 230 List<C> rl = new ArrayList<C>(ring.cols); 231 for (int i = 0; i < ring.cols; i++) { 232 if (i < k) { 233 rl.add(zero); 234 } else { // if (i >= k) 235 rl.add( ul.get(i).multiply(kk) ); 236 } 237 } 238 cl.add(rl); 239 } 240 GenMatrix<C> U = new GenMatrix<C>(ring, cl); 241 return U; 242 } 243 244 245 /** 246 * Get lower triangular L matrix. 247 * @return L as matrix with equal length rows. 248 */ 249 public GenMatrix<C> getLower() { 250 final C zero = ring.coFac.getZERO(); 251 List<List<C>> cl = new ArrayList<List<C>>(ring.rows); 252 for (int k = 0; k < ring.rows; k++) { 253 List<C> ul = matrix.get(k); 254 List<C> rl = new ArrayList<C>(ring.cols); 255 for (int i = 0; i < ring.cols; i++) { 256 if (i <= k) { 257 rl.add(ul.get(i)); // can be zero 258 } else if (i > k) { 259 rl.add(zero); 260 } 261 } 262 cl.add(rl); 263 } 264 GenMatrix<C> L = new GenMatrix<C>(ring, cl); 265 return L; 266 } 267 268 269 /** 270 * Get the String representation as RingElem. 271 * @see java.lang.Object#toString() 272 */ 273 @Override 274 public String toString() { 275 StringBuffer s = new StringBuffer(); 276 boolean firstRow = true; 277 s.append("[\n"); 278 for (List<C> val : matrix) { 279 if (firstRow) { 280 firstRow = false; 281 } else { 282 s.append(",\n"); 283 } 284 boolean first = true; 285 s.append("[ "); 286 for (C c : val) { 287 if (first) { 288 first = false; 289 } else { 290 s.append(", "); 291 } 292 s.append(c.toString()); 293 } 294 s.append(" ]"); 295 } 296 s.append(" ] "); 297 if (!PrettyPrint.isTrue()) { 298 s.append(":: " + ring.toString()); 299 s.append("\n"); 300 } 301 return s.toString(); 302 } 303 304 305 /** 306 * Get a scripting compatible string representation. 307 * @return script compatible representation for this Element. 308 * @see edu.jas.structure.Element#toScript() 309 */ 310 @Override 311 public String toScript() { 312 // Python case 313 StringBuffer s = new StringBuffer(); 314 boolean firstRow = true; 315 s.append("( "); 316 for (List<C> val : matrix) { 317 if (firstRow) { 318 firstRow = false; 319 } else { 320 s.append(", "); 321 } 322 boolean first = true; 323 s.append("( "); 324 for (C c : val) { 325 if (first) { 326 first = false; 327 } else { 328 s.append(", "); 329 } 330 s.append(c.toScript()); 331 } 332 s.append(" )"); 333 } 334 s.append(" ) "); 335 return s.toString(); 336 } 337 338 339 /** 340 * Get a scripting compatible string representation of the factory. 341 * @return script compatible representation for this ElemFactory. 342 * @see edu.jas.structure.Element#toScriptFactory() 343 */ 344 @Override 345 public String toScriptFactory() { 346 // Python case 347 return factory().toScript(); 348 } 349 350 351 /** 352 * Get the corresponding element factory. 353 * @return factory for this Element. 354 * @see edu.jas.structure.Element#factory() 355 */ 356 public GenMatrixRing<C> factory() { 357 return ring; 358 } 359 360 361 /** 362 * Copy method. 363 * @see edu.jas.structure.Element#copy() 364 */ 365 @Override 366 public GenMatrix<C> copy() { 367 //return ring.copy(this); 368 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 369 ArrayList<C> v; 370 for (ArrayList<C> val : matrix) { 371 v = new ArrayList<C>(val); 372 m.add(v); 373 } 374 return new GenMatrix<C>(ring, m); 375 } 376 377 378 /** 379 * Stack method. 380 * @param st stacked matrix ring. 381 * @param b other matrix. 382 * @return stacked matrix, this on top of other. 383 */ 384 public GenMatrix<C> stack(GenMatrixRing<C> st, GenMatrix<C> b) { 385 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(st.rows); 386 ArrayList<C> v; 387 for (ArrayList<C> val : matrix) { 388 v = new ArrayList<C>(val); 389 m.add(v); 390 } 391 for (ArrayList<C> val : b.matrix) { 392 v = new ArrayList<C>(val); 393 m.add(v); 394 } 395 return new GenMatrix<C>(st, m); 396 } 397 398 399 /** 400 * Concat method. 401 * @param cc concated matrix ring. 402 * @param b other matrix. 403 * @return concated matrix, this before of other. 404 */ 405 public GenMatrix<C> concat(GenMatrixRing<C> cc, GenMatrix<C> b) { 406 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(cc.rows); 407 ArrayList<ArrayList<C>> bm = b.matrix; 408 ArrayList<C> v, o; 409 int i = 0; 410 for (ArrayList<C> val : matrix) { 411 v = new ArrayList<C>(val); 412 o = bm.get(i++); 413 v.addAll(o); 414 m.add(v); 415 } 416 return new GenMatrix<C>(cc, m); 417 } 418 419 420 /** 421 * Test if this is equal to a zero matrix. 422 */ 423 public boolean isZERO() { 424 for (List<C> row : matrix) { 425 for (C elem : row) { 426 if (!elem.isZERO()) { 427 return false; 428 } 429 } 430 } 431 return true; 432 } 433 434 435 /** 436 * Test if this is one. 437 * @return true if this is 1, else false. 438 */ 439 public boolean isONE() { 440 int i = 0; 441 for (List<C> row : matrix) { 442 int j = 0; 443 for (C elem : row) { 444 if (i == j) { 445 if (!elem.isONE()) { 446 //System.out.println("elem.isONE = " + elem); 447 return false; 448 } 449 } else if (!elem.isZERO()) { 450 //System.out.println("elem.isZERO = " + elem); 451 return false; 452 } 453 j++; 454 } 455 i++; 456 } 457 return true; 458 } 459 460 461 /** 462 * Comparison with any other object. 463 * @see java.lang.Object#equals(java.lang.Object) 464 */ 465 @Override 466 @SuppressWarnings("unchecked") 467 public boolean equals(Object other) { 468 if (!(other instanceof GenMatrix)) { 469 return false; 470 } 471 GenMatrix om = (GenMatrix) other; 472 if (!ring.equals(om.ring)) { 473 return false; 474 } 475 if (!matrix.equals(om.matrix)) { 476 return false; 477 } 478 return true; 479 } 480 481 482 /** 483 * Hash code for this GenMatrix. 484 * @see java.lang.Object#hashCode() 485 */ 486 @Override 487 public int hashCode() { 488 if (hashValue == 0) { 489 hashValue = 37 * matrix.hashCode() + ring.hashCode(); 490 if (hashValue == 0) { 491 hashValue = 1; 492 } 493 } 494 return hashValue; 495 } 496 497 498 /** 499 * compareTo, lexicogaphical comparison. 500 * @param b other 501 * @return 1 if (this < b), 0 if (this == b) or -1 if (this > b). 502 */ 503 @Override 504 public int compareTo(GenMatrix<C> b) { 505 if (!ring.equals(b.ring)) { 506 return -1; 507 } 508 ArrayList<ArrayList<C>> om = b.matrix; 509 int i = 0; 510 for (ArrayList<C> val : matrix) { 511 ArrayList<C> ov = om.get(i++); 512 int j = 0; 513 for (C c : val) { 514 int s = c.compareTo(ov.get(j++)); 515 if (s != 0) { 516 return s; 517 } 518 } 519 } 520 return 0; 521 } 522 523 524 /** 525 * Test if this is a unit. I.e. there exists x with this.multiply(x).isONE() 526 * == true. Tests if matrix is not singular. 527 * Was previously a test if all diagonal elements are units and all other 528 * elements are zero. 529 * @return true if this is a unit, else false. 530 */ 531 public boolean isUnit() { 532 LinAlg<C> la = new LinAlg<C>(); 533 GenMatrix<C> mat = this.copy(); 534 List<Integer> P = la.decompositionLU(mat); 535 if (P == null || P.isEmpty()) { 536 return false; 537 } 538 return true; 539 } 540 541 542 /** 543 * sign of matrix. 544 * @return 1 if (this < 0), 0 if (this == 0) or -1 if (this > 0). 545 */ 546 public int signum() { 547 return compareTo(ring.getZERO()); 548 } 549 550 551 /** 552 * Sum of matrices. 553 * @param b other matrix. 554 * @return this+b 555 */ 556 public GenMatrix<C> sum(GenMatrix<C> b) { 557 ArrayList<ArrayList<C>> om = b.matrix; 558 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 559 int i = 0; 560 for (ArrayList<C> val : matrix) { 561 ArrayList<C> ov = om.get(i++); 562 ArrayList<C> v = new ArrayList<C>(ring.cols); 563 int j = 0; 564 for (C c : val) { 565 C e = c.sum(ov.get(j++)); 566 v.add(e); 567 } 568 m.add(v); 569 } 570 return new GenMatrix<C>(ring, m); 571 } 572 573 574 /** 575 * Difference of matrices. 576 * @param b other matrix. 577 * @return this-b 578 */ 579 public GenMatrix<C> subtract(GenMatrix<C> b) { 580 ArrayList<ArrayList<C>> om = b.matrix; 581 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 582 int i = 0; 583 for (ArrayList<C> val : matrix) { 584 ArrayList<C> ov = om.get(i++); 585 ArrayList<C> v = new ArrayList<C>(ring.cols); 586 int j = 0; 587 for (C c : val) { 588 C e = c.subtract(ov.get(j++)); 589 v.add(e); 590 } 591 m.add(v); 592 } 593 return new GenMatrix<C>(ring, m); 594 } 595 596 597 /** 598 * Negative of this matrix. 599 * @return -this 600 */ 601 public GenMatrix<C> negate() { 602 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 603 //int i = 0; 604 for (ArrayList<C> val : matrix) { 605 ArrayList<C> v = new ArrayList<C>(ring.cols); 606 for (C c : val) { 607 C e = c.negate(); 608 v.add(e); 609 } 610 m.add(v); 611 } 612 return new GenMatrix<C>(ring, m); 613 } 614 615 616 /** 617 * Absolute value of this matrix. 618 * @return abs(this) 619 */ 620 public GenMatrix<C> abs() { 621 if (signum() < 0) { 622 return negate(); 623 } 624 return this; 625 } 626 627 628 /** 629 * Product of this matrix with scalar. 630 * @param s scalar. 631 * @return this*s 632 */ 633 public GenMatrix<C> multiply(C s) { 634 return scalarMultiply(s); 635 } 636 637 638 /** 639 * Product of this matrix with scalar. 640 * @param s scalar 641 * @return this*s 642 */ 643 public GenMatrix<C> scalarMultiply(C s) { 644 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 645 //int i = 0; 646 for (ArrayList<C> val : matrix) { 647 ArrayList<C> v = new ArrayList<C>(ring.cols); 648 for (C c : val) { 649 C e = c.multiply(s); 650 v.add(e); 651 } 652 m.add(v); 653 } 654 return new GenMatrix<C>(ring, m); 655 } 656 657 658 /** 659 * Left product of this matrix with scalar. 660 * @param s scalar 661 * @return s*this 662 */ 663 public GenMatrix<C> leftScalarMultiply(C s) { 664 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 665 //int i = 0; 666 for (ArrayList<C> val : matrix) { 667 ArrayList<C> v = new ArrayList<C>(ring.cols); 668 for (C c : val) { 669 C e = s.multiply(c); 670 v.add(e); 671 } 672 m.add(v); 673 } 674 return new GenMatrix<C>(ring, m); 675 } 676 677 678 /** 679 * Linear compination of this matrix with scalar multiple of other matrix. 680 * @param s scalar 681 * @param t scalar 682 * @param b other matrix. 683 * @return this*s+b*t 684 */ 685 public GenMatrix<C> linearCombination(C s, GenMatrix<C> b, C t) { 686 ArrayList<ArrayList<C>> om = b.matrix; 687 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 688 int i = 0; 689 for (ArrayList<C> val : matrix) { 690 ArrayList<C> ov = om.get(i++); 691 ArrayList<C> v = new ArrayList<C>(ring.cols); 692 int j = 0; 693 for (C c : val) { 694 C c1 = c.multiply(s); 695 C c2 = ov.get(j++).multiply(t); 696 C e = c1.sum(c2); 697 v.add(e); 698 } 699 m.add(v); 700 } 701 return new GenMatrix<C>(ring, m); 702 } 703 704 705 /** 706 * Linear combination of this matrix with scalar multiple of other matrix. 707 * @param t scalar 708 * @param b other matrix. 709 * @return this+b*t 710 */ 711 public GenMatrix<C> linearCombination(GenMatrix<C> b, C t) { 712 ArrayList<ArrayList<C>> om = b.matrix; 713 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 714 int i = 0; 715 for (ArrayList<C> val : matrix) { 716 ArrayList<C> ov = om.get(i++); 717 ArrayList<C> v = new ArrayList<C>(ring.cols); 718 int j = 0; 719 for (C c : val) { 720 C c2 = ov.get(j++).multiply(t); 721 C e = c.sum(c2); 722 v.add(e); 723 } 724 m.add(v); 725 } 726 return new GenMatrix<C>(ring, m); 727 } 728 729 730 /** 731 * Left linear combination of this matrix with scalar multiple of other 732 * matrix. 733 * @param t scalar 734 * @param b other matrix. 735 * @return this+t*b 736 */ 737 public GenMatrix<C> linearCombination(C t, GenMatrix<C> b) { 738 ArrayList<ArrayList<C>> om = b.matrix; 739 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 740 int i = 0; 741 for (ArrayList<C> val : matrix) { 742 ArrayList<C> ov = om.get(i++); 743 ArrayList<C> v = new ArrayList<C>(ring.cols); 744 int j = 0; 745 for (C c : val) { 746 C c2 = t.multiply(ov.get(j++)); 747 C e = c.sum(c2); 748 v.add(e); 749 } 750 m.add(v); 751 } 752 return new GenMatrix<C>(ring, m); 753 } 754 755 756 /** 757 * left linear compination of this matrix with scalar multiple of other 758 * matrix. 759 * @param s scalar 760 * @param t scalar 761 * @param b other matrix. 762 * @return s*this+t*b 763 */ 764 public GenMatrix<C> leftLinearCombination(C s, C t, GenMatrix<C> b) { 765 ArrayList<ArrayList<C>> om = b.matrix; 766 ArrayList<ArrayList<C>> m = new ArrayList<ArrayList<C>>(ring.rows); 767 int i = 0; 768 for (ArrayList<C> val : matrix) { 769 ArrayList<C> ov = om.get(i++); 770 ArrayList<C> v = new ArrayList<C>(ring.cols); 771 int j = 0; 772 for (C c : val) { 773 C c1 = s.multiply(c); 774 C c2 = t.multiply(ov.get(j++)); 775 C e = c1.sum(c2); 776 v.add(e); 777 } 778 m.add(v); 779 } 780 return new GenMatrix<C>(ring, m); 781 } 782 783 784 /** 785 * Transposed matrix. 786 * @param tr transposed matrix ring. 787 * @return transpose(this) 788 */ 789 public GenMatrix<C> transpose(GenMatrixRing<C> tr) { 790 GenMatrix<C> t = tr.getZERO().copy(); 791 ArrayList<ArrayList<C>> m = t.matrix; 792 int i = 0; 793 for (ArrayList<C> val : matrix) { 794 int j = 0; 795 for (C c : val) { 796 (m.get(j)).set(i, c); //A[j,i] = A[i,j] 797 j++; 798 } 799 i++; 800 } 801 // return new GenMatrix<C>(tr,m); 802 return t; 803 } 804 805 806 /** 807 * Transposed matrix. 808 * @return transpose(this) 809 */ 810 public GenMatrix<C> transpose() { 811 GenMatrixRing<C> tr = ring.transpose(); 812 return transpose(tr); 813 } 814 815 816 /** 817 * Multiply this with S. 818 * @param S other matrix. 819 * @return this * S. 820 */ 821 public GenMatrix<C> multiply(GenMatrix<C> S) { 822 int na = ring.blocksize; 823 int nb = ring.blocksize; 824 //System.out.println("#blocks = " + (matrix.size()/na) + ", na = " + na 825 // + " SeqMultBlockTrans"); 826 ArrayList<ArrayList<C>> m = matrix; 827 //ArrayList<ArrayList<C>> s = S.matrix; 828 829 GenMatrixRing<C> tr = S.ring.transpose(); 830 GenMatrix<C> T = S.transpose(tr); 831 ArrayList<ArrayList<C>> t = T.matrix; 832 //System.out.println("T = " + T); 833 834 GenMatrixRing<C> pr = ring.product(S.ring); 835 GenMatrix<C> P = pr.getZERO().copy(); 836 ArrayList<ArrayList<C>> p = P.matrix; 837 //System.out.println("P = " + P); 838 839 for (int ii = 0; ii < m.size(); ii += na) { 840 for (int jj = 0; jj < t.size(); jj += nb) { 841 842 for (int i = ii; i < Math.min((ii + na), m.size()); i++) { 843 ArrayList<C> Ai = m.get(i); //A[i]; 844 for (int j = jj; j < Math.min((jj + nb), t.size()); j++) { 845 ArrayList<C> Bj = t.get(j); //B[j]; 846 C c = ring.coFac.getZERO(); 847 for (int k = 0; k < Bj.size(); k++) { 848 c = c.sum(Ai.get(k).multiply(Bj.get(k))); 849 // c += Ai[k] * Bj[k]; 850 } 851 (p.get(i)).set(j, c); // C[i][j] = c; 852 } 853 } 854 855 } 856 } 857 return new GenMatrix<C>(pr, p); 858 } 859 860 861 /** 862 * Multiply this with S. Simple unblocked algorithm. 863 * @param S other matrix. 864 * @return this * S. 865 */ 866 public GenMatrix<C> multiplySimple(GenMatrix<C> S) { 867 ArrayList<ArrayList<C>> m = matrix; 868 ArrayList<ArrayList<C>> B = S.matrix; 869 870 GenMatrixRing<C> pr = ring.product(S.ring); 871 GenMatrix<C> P = pr.getZERO().copy(); 872 ArrayList<ArrayList<C>> p = P.matrix; 873 874 for (int i = 0; i < pr.rows; i++) { 875 ArrayList<C> Ai = m.get(i); //A[i]; 876 for (int j = 0; j < pr.cols; j++) { 877 C c = ring.coFac.getZERO(); 878 for (int k = 0; k < S.ring.rows; k++) { 879 c = c.sum(Ai.get(k).multiply(B.get(k).get(j))); 880 // c += A[i][k] * B[k][j]; 881 } 882 (p.get(i)).set(j, c); // C[i][j] = c; 883 } 884 } 885 return new GenMatrix<C>(pr, p); 886 } 887 888 889 /** 890 * Divide this by S. 891 * @param S other matrix. 892 * @return this * S^{-1}. 893 */ 894 public GenMatrix<C> divide(GenMatrix<C> S) { 895 //throw new UnsupportedOperationException("divide not yet implemented"); 896 return multiply(S.inverse()); 897 } 898 899 900 /** 901 * Divide left this by S. 902 * @param S other matrix. 903 * @return S^{-1} * this. 904 */ 905 public GenMatrix<C> divideLeft(GenMatrix<C> S) { 906 return S.inverse().multiply(this); 907 } 908 909 910 /** 911 * Remainder after division of this by S. 912 * @param S other matrix. 913 * @return this - (this / S) * S. 914 */ 915 public GenMatrix<C> remainder(GenMatrix<C> S) { 916 throw new UnsupportedOperationException("remainder not implemented"); 917 } 918 919 920 /** 921 * Quotient and remainder by division of this by S. 922 * @param S a GenMatrix 923 * @return [this/S, this - (this/S)*S]. 924 */ 925 public GenMatrix<C>[] quotientRemainder(GenMatrix<C> S) { 926 throw new UnsupportedOperationException("quotientRemainder not implemented, input = " + S); 927 } 928 929 930 /** 931 * Inverse of this. 932 * @return x with this * x = 1, if it exists. 933 * @see edu.jas.vector.LinAlg#inverseLU(edu.jas.vector.GenMatrix,java.util.List) 934 */ 935 public GenMatrix<C> inverse() { 936 //throw new UnsupportedOperationException("inverse implemented in LinAlg.inverseLU()"); 937 LinAlg<C> la = new LinAlg<C>(); 938 GenMatrix<C> mat = this.copy(); 939 List<Integer> P = la.decompositionLU(mat); 940 if (P == null || P.isEmpty()) { 941 throw new NotInvertibleException("matrix not invertible"); 942 } 943 mat = la.inverseLU(mat,P); 944 return mat; 945 } 946 947 948 /** 949 * Greatest common divisor. 950 * @param b other element. 951 * @return gcd(this,b). 952 */ 953 public GenMatrix<C> gcd(GenMatrix<C> b) { 954 throw new UnsupportedOperationException("gcd not implemented"); 955 } 956 957 958 /** 959 * Extended greatest common divisor. 960 * @param b other element. 961 * @return [ gcd(this,b), c1, c2 ] with c1*this + c2*b = gcd(this,b). 962 */ 963 public GenMatrix<C>[] egcd(GenMatrix<C> b) { 964 throw new UnsupportedOperationException("egcd not implemented"); 965 } 966 967}