| 609 | */ |
| 610 | template <typename MatrixType, typename OrderingType> |
| 611 | void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix) { |
| 612 | using internal::emptyIdxLU; |
| 613 | eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); |
| 614 | eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices"); |
| 615 | |
| 616 | m_isInitialized = true; |
| 617 | |
| 618 | // Apply the column permutation computed in analyzepattern() |
| 619 | // m_mat = matrix * m_perm_c.inverse(); |
| 620 | m_mat = matrix; |
| 621 | if (m_perm_c.size()) { |
| 622 | m_mat.uncompress(); // NOTE: The effect of this command is only to create the InnerNonzeros pointers. |
| 623 | // Then, permute only the column pointers |
| 624 | const StorageIndex* outerIndexPtr; |
| 625 | if (matrix.isCompressed()) |
| 626 | outerIndexPtr = matrix.outerIndexPtr(); |
| 627 | else { |
| 628 | StorageIndex* outerIndexPtr_t = new StorageIndex[matrix.cols() + 1]; |
| 629 | for (Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i]; |
| 630 | outerIndexPtr = outerIndexPtr_t; |
| 631 | } |
| 632 | for (Index i = 0; i < matrix.cols(); i++) { |
| 633 | m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i]; |
| 634 | m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i + 1] - outerIndexPtr[i]; |
| 635 | } |
| 636 | if (!matrix.isCompressed()) delete[] outerIndexPtr; |
| 637 | } else { // FIXME This should not be needed if the empty permutation is handled transparently |
| 638 | m_perm_c.resize(matrix.cols()); |
| 639 | for (StorageIndex i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i; |
| 640 | } |
| 641 | |
| 642 | Index m = m_mat.rows(); |
| 643 | Index n = m_mat.cols(); |
| 644 | Index nnz = m_mat.nonZeros(); |
| 645 | Index maxpanel = m_perfv.panel_size * m; |
| 646 | // Allocate working storage common to the factor routines |
| 647 | Index lwork = 0; |
| 648 | // Return the size of actually allocated memory when allocation failed, |
| 649 | // and 0 on success. |
| 650 | Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu); |
| 651 | if (info) { |
| 652 | m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n"; |
| 653 | m_factorizationIsOk = false; |
| 654 | return; |
| 655 | } |
| 656 | |
| 657 | // Set up pointers for integer working arrays |
| 658 | IndexVector segrep(m); |
| 659 | segrep.setZero(); |
| 660 | IndexVector parent(m); |
| 661 | parent.setZero(); |
| 662 | IndexVector xplore(m); |
| 663 | xplore.setZero(); |
| 664 | IndexVector repfnz(maxpanel); |
| 665 | IndexVector panel_lsub(maxpanel); |
| 666 | IndexVector xprune(n); |
| 667 | xprune.setZero(); |
| 668 | IndexVector marker(m * internal::LUNoMarker); |
nothing calls this directly
no test coverage detected