61 lines
1.4 KiB
C++
61 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include "./utils/vector.h"
|
|
#include "./utils/matrix.h"
|
|
|
|
namespace decomp{
|
|
|
|
// Stores PA = LU with partial pivoting (row permutations).
|
|
template <typename T>
|
|
struct LU{
|
|
utils::Matrix<T> LUmat; // combined L (unit diagonal implied) and U
|
|
std::vector<uint64_t> piv; // pivot indices (row permutations)
|
|
bool singular= false; // set true if zero (or near-zero) pivots encountered
|
|
|
|
LU() = default;
|
|
|
|
explicit LU(const utils::Matrix<T>& A) {
|
|
factor(A);
|
|
}
|
|
|
|
void factor(const utils::Matrix<T>&A){
|
|
|
|
const uint64_t rows = A.rows();
|
|
if (rows != A.cols()){
|
|
throw std::runtime_error("LU: factor non-square");
|
|
}
|
|
|
|
if (rows == 0){
|
|
LUmat = A;
|
|
piv.clear();
|
|
singular = false;
|
|
return;
|
|
}
|
|
|
|
T big, tmp;
|
|
|
|
LUmat = A;
|
|
piv.resize(rows); // piv stores the implicit scaling of each row.
|
|
//double d = 1.0; // No row interchanges yet.
|
|
|
|
for (uint64_t i = 0; i < rows; ++i){ // Loop over rows to get the implicit scaling information.
|
|
big = T{0};
|
|
for (uint64_t j = 0; j < rows; ++j){
|
|
tmp=std::abs(LUmat(i,j));
|
|
if (tmp > big){
|
|
big = tmp;
|
|
}
|
|
}
|
|
if (big == T{0}){
|
|
throw std::runtime_error("Singular matrix in LU.factor()");
|
|
}
|
|
}
|
|
}
|
|
|
|
}; // struct LU
|
|
|
|
typedef LU<float> LUf;
|
|
typedef LU<double> LUd;
|
|
|
|
|
|
} // namespace decomp
|