37template<
typename T,
typename U>
concept ArmaContainer = std::is_floating_point_v<U> && (std::is_convertible_v<T, Mat<U>> || std::is_convertible_v<T, SpMat<U>>) ;
57 template<std::invocable<fmat&> F>
int mixed_trs(mat& X, mat&& B, F trs) {
60 X = arma::zeros(size(B));
62 auto multiplier = norm(B);
68 auto residual = conv_to<fmat>::from(B / multiplier);
70 if(0 != (INFO = trs(residual)))
break;
72 const mat incre = multiplier * conv_to<mat>::from(residual);
76 suanpan_debug(
"Mixed precision algorithm multiplier: {:.5E}.\n", multiplier = arma::norm(B -= this->
operator*(incre)));
89 MetaMat(
const uword in_rows,
const uword in_cols,
const uword in_elem)
114 this->
at(K,
K) =
T(1);
119 [[nodiscard]]
virtual T max()
const = 0;
120 [[nodiscard]]
virtual Col<T>
diag()
const = 0;
131 virtual T&
unsafe_at(
const uword I,
const uword J) {
return this->
at(I, J); }
137 virtual T&
at(uword, uword) = 0;
139 [[nodiscard]]
virtual const T*
memptr()
const = 0;
159 if(!
to_mat(*this).save(name))
171 this->csc_condense();
173 X.zeros(arma::size(B));
175 unique_ptr<Preconditioner<T>> preconditioner;
176 if(
PreconditionerType::JACOBI == this->setting.preconditioner_type) preconditioner = std::make_unique<Jacobi<T>>(this->diag());
177#ifndef SUANPAN_SUPERLUMT
179 if(this->triplet_mat.is_empty()) preconditioner = std::make_unique<
ILU<T>>(to_triplet_form<T, int>(
this));
180 else preconditioner = std::make_unique<ILU<T>>(this->triplet_mat);
183 else if(
PreconditionerType::NONE == this->setting.preconditioner_type) preconditioner = std::make_unique<UnityPreconditioner<T>>();
187 this->setting.preconditioner = preconditioner.get();
189 std::atomic_int code = 0;
193 Col<T> sub_x(X.colptr(I), X.n_rows, false, true);
194 const Col<T> sub_b(B.colptr(I), B.n_rows);
195 auto col_setting = setting;
196 code += GMRES(this, sub_x, sub_b, col_setting);
200 Col<T> sub_x(X.colptr(I), X.n_rows, false, true);
201 const Col<T> sub_b(B.colptr(I), B.n_rows);
202 auto col_setting = setting;
203 code += BiCGSTAB(this, sub_x, sub_b, col_setting);
205 else throw invalid_argument(
"no proper iterative solver assigned but somehow iterative solving is called");
212 for(uword J = 0; J < in_mat.
n_cols; ++J)
for(uword I = 0; I < in_mat.
n_rows; ++I) out_mat(I, J) = in_mat(I, J);
219 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
220 for(index_t I = 0; I < in_mat.
n_elem; ++I) out_mat(in_mat.
row(I), in_mat.
col(I)) += in_mat.
val(I);
225 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
228 for(index_t I = 0; I < in_mat.
n_elem; ++I) {
229 if(I >= in_mat.
row_mem()[c_idx]) ++c_idx;
237 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
240 for(index_t I = 0; I < in_mat.
n_elem; ++I) {
241 if(I >= in_mat.
col_mem()[c_idx]) ++c_idx;
251 const sp_i auto n_rows = index_t(in_mat->
n_rows);
252 const sp_i auto n_cols = index_t(in_mat->
n_cols);
253 const sp_i auto n_elem = index_t(in_mat->
n_elem);
256 for(index_t J = 0; J < n_cols; ++J)
for(index_t I = 0; I < n_rows; ++I) out_mat.
at(I, J) = in_mat->operator()(I, J);
A ILU class.
Definition ILU.hpp:40
Definition MetaMat.hpp:37
Definition SolverSetting.hpp:40
unsigned iterative_refinement
Definition SolverSetting.hpp:44
data_t tolerance
Definition SolverSetting.hpp:43
IterativeSolver iterative_solver
Definition SolverSetting.hpp:46
#define suanpan_debug(...)
Definition suanPan.h:307
constexpr auto SUANPAN_SUCCESS
Definition suanPan.h:172
constexpr auto SUANPAN_FAIL
Definition suanPan.h:173
#define suanpan_error(...)
Definition suanPan.h:309
void suanpan_for(const IT start, const IT end, F &&FN)
Definition utility.h:27