()
| 489 | } |
| 490 | |
| 491 | @Override |
| 492 | public Matrix[] lup() |
| 493 | { |
| 494 | Matrix[] lup = new Matrix[3]; |
| 495 | |
| 496 | Matrix P = eye(rows()); |
| 497 | Matrix L; |
| 498 | Matrix U = this; |
| 499 | |
| 500 | //Initalization is a little wierd b/c we want to handle rectangular cases as well! |
| 501 | if(rows() > cols())//In this case, we will be changing U before returning it (have to make it smaller, but we can still avoid allocating extra space |
| 502 | L = getMatrixOfSameType(rows(), cols()); |
| 503 | else |
| 504 | L = getMatrixOfSameType(rows(), rows()); |
| 505 | |
| 506 | for(int i = 0; i < U.rows(); i++) |
| 507 | { |
| 508 | //If rectangular, we still need to loop through to update ther est of L - even though we wont make many other changes |
| 509 | if(i < U.cols()) |
| 510 | { |
| 511 | //Partial pivoting, find the largest value in this colum and move it to the top! |
| 512 | //Find the largest magintude value in the colum k, row j |
| 513 | int largestRow = i; |
| 514 | double largestVal = Math.abs(U.get(i, i)); |
| 515 | for (int j = i + 1; j < U.rows(); j++) |
| 516 | { |
| 517 | double rowJLeadVal = Math.abs(U.get(j, i)); |
| 518 | if (rowJLeadVal > largestVal) |
| 519 | { |
| 520 | largestRow = j; |
| 521 | largestVal = rowJLeadVal; |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | //SWAP! |
| 526 | U.swapRows(largestRow, i); |
| 527 | P.swapRows(largestRow, i); |
| 528 | L.swapRows(largestRow, i); |
| 529 | |
| 530 | L.set(i, i, 1); |
| 531 | } |
| 532 | |
| 533 | //Seting up L |
| 534 | for(int k = 0; k < Math.min(i, U.cols()); k++) |
| 535 | { |
| 536 | double tmp = U.get(i, k)/U.get(k, k); |
| 537 | L.set(i, k, (Double.isNaN(tmp) ? 0.0 : tmp) ); |
| 538 | U.set(i, k, 0.0); |
| 539 | |
| 540 | for(int j = k+1; j < U.cols(); j++) |
| 541 | { |
| 542 | U.increment(i, j, -L.get(i, k)*U.get(k, j)); |
| 543 | } |
| 544 | } |
| 545 | } |
| 546 | |
| 547 | |
| 548 | if(rows() > cols())//Clean up! |
nothing calls this directly
no test coverage detected