| 28 | }; |
| 29 | |
| 30 | void BasicLuKernel::_Factorize(Int dim, const Int* Bbegin, const Int* Bend, |
| 31 | const Int* Bi, const double* Bx, double pivottol, |
| 32 | bool strict_abs_pivottol, |
| 33 | SparseMatrix* L, SparseMatrix* U, |
| 34 | std::vector<Int>* rowperm, |
| 35 | std::vector<Int>* colperm, |
| 36 | std::vector<Int>* dependent_cols) { |
| 37 | BasicLuHelper lu(dim); |
| 38 | lu.obj.xstore[BASICLU_REL_PIVOT_TOLERANCE] = pivottol; |
| 39 | if (strict_abs_pivottol) { |
| 40 | lu.obj.xstore[BASICLU_ABS_PIVOT_TOLERANCE] = kLuDependencyTol; |
| 41 | lu.obj.xstore[BASICLU_REMOVE_COLUMNS] = 1; |
| 42 | } |
| 43 | Int err = basiclu_obj_factorize(&lu.obj, Bbegin, Bend, Bi, Bx); |
| 44 | if (err == BASICLU_ERROR_out_of_memory) |
| 45 | throw std::bad_alloc(); |
| 46 | if (err != BASICLU_OK && err != BASICLU_WARNING_singular_matrix) |
| 47 | throw std::logic_error("basiclu_obj_factorize failed"); |
| 48 | |
| 49 | // Extract factors. Dependent columns are at the end of the BASICLU pivot |
| 50 | // sequence. |
| 51 | Int rank = lu.obj.xstore[BASICLU_RANK]; |
| 52 | dependent_cols->clear(); |
| 53 | for (Int k = rank; k < dim; k++) |
| 54 | dependent_cols->push_back(k); |
| 55 | L->resize(dim, dim, dim + lu.obj.xstore[BASICLU_LNZ]); |
| 56 | U->resize(dim, dim, dim + lu.obj.xstore[BASICLU_UNZ]); |
| 57 | rowperm->resize(dim); |
| 58 | colperm->resize(dim); |
| 59 | err = basiclu_obj_get_factors(&lu.obj, rowperm->data(), colperm->data(), |
| 60 | L->colptr(), L->rowidx(), L->values(), |
| 61 | U->colptr(), U->rowidx(), U->values()); |
| 62 | if (err != BASICLU_OK) |
| 63 | throw std::logic_error("basiclu_obj_get_factors failed"); |
| 64 | |
| 65 | // Remove unit diagonal from L. |
| 66 | Int num_dropped = RemoveDiagonal(*L, nullptr); |
| 67 | assert(num_dropped == dim); |
| 68 | assert(L->entries() == lu.obj.xstore[BASICLU_LNZ]); |
| 69 | } |
| 70 | |
| 71 | } // namespace ipx |
nothing calls this directly
no test coverage detected