| 600 | |
| 601 | |
| 602 | void UdUrecompose_transpose (RowMatrix& M) |
| 603 | /* In-place recomposition of Symmetric matrix from U'dU factor store in UD format |
| 604 | * Generally used for recomposing result of UdUinverse |
| 605 | * Note definiteness of result depends purely on diagonal(M) |
| 606 | * i.e. if d is positive definite (>0) then result is positive definite |
| 607 | * Reference: A+G p.223 |
| 608 | * In place computation uses simple structure of solution due to triangular zero elements |
| 609 | * Defn: R = (U' d) row i , C = U column j -> M(i,j) = R dot C; |
| 610 | * However M(i,j) only dependent R(k<=i), C(k<=j) due to zeros |
| 611 | * Therefore in place multiple sequences such k < i <= j |
| 612 | * Input: |
| 613 | * M - U'dU factorisation (UD format) |
| 614 | * Output: |
| 615 | * M - U'dU recomposition (symmetric) |
| 616 | */ |
| 617 | { |
| 618 | std::size_t i,j,k; |
| 619 | const std::size_t n = M.size1(); |
| 620 | assert (n == M.size2()); |
| 621 | |
| 622 | // Recompose M = (U'dU) in place |
| 623 | if (n > 0) |
| 624 | { |
| 625 | i = n-1; |
| 626 | do { |
| 627 | RowMatrix::Row Mi(M,i); |
| 628 | // (U' d) row i of lower triangle from upper triangle |
| 629 | for (j = 0; j < i; ++j) |
| 630 | Mi[j] = M(j,i) * M(j,j); |
| 631 | // (U' d) U in place |
| 632 | j = n-1; |
| 633 | do { // j>=i |
| 634 | // Compute matrix product (U'd) row i * U col j |
| 635 | RowMatrix::value_type Mij = Mi[j]; |
| 636 | if (j > i) // Optimised handling of 1 in U |
| 637 | Mij *= Mi[i]; |
| 638 | for (k = 0; k < i; ++k) // Inner loop k < i <=j, only strict triangular elements |
| 639 | Mij += Mi[k] * M(k,j); // M(i,k) element of U'd, M(k,j) element of U |
| 640 | M(j,i) = Mi[j] = Mij; |
| 641 | } while (j-- > i); |
| 642 | } while (i-- > 0); |
| 643 | } |
| 644 | } |
| 645 | |
| 646 | |
| 647 | void UdUrecompose (RowMatrix& M) |
no outgoing calls
no test coverage detected