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>>) ;
64 [[nodiscard]] virtual
bool is_empty() const = 0;
72 [[nodiscard]] virtual
T max() const = 0;
73 [[nodiscard]] virtual Col<
T>
diag() const = 0;
79 virtual const
T& operator()(uword, uword) const = 0;
89 virtual
T&
at(uword, uword) = 0;
91 [[nodiscard]] virtual const
T*
memptr() const = 0;
94 virtual
void operator+=(const shared_ptr<
MetaMat>&) = 0;
95 virtual
void operator-=(const shared_ptr<
MetaMat>&) = 0;
100 virtual Mat<
T> operator*(const Mat<
T>&) const = 0;
102 virtual
void operator*=(
T) = 0;
109 template<ArmaContainer<T> C> Mat<T>
solve(C&& B) {
114 template<ArmaContainer<T> C>
int solve(Mat<T>& X,
const C& B) {
119 template<ArmaContainer<T> C>
int solve(Mat<T>& X, C&& B) {
132 if(0 != this->
direct_solve(X, std::forward<C>(B))) X.reset();
143 void save(
const char*);
154 [[nodiscard]] Col<T>
evaluate(
const Col<T>&)
const;
158 : triplet_mat(in_rows, in_cols)
178 if(!
to_mat(*this).save(name))
195 X.zeros(arma::size(B));
197 unique_ptr<Preconditioner<T>> preconditioner;
198 if(
PreconditionerType::JACOBI == this->setting.preconditioner_type) preconditioner = std::make_unique<Jacobi<T>>(this->diag());
199#ifndef SUANPAN_SUPERLUMT
201 if(this->triplet_mat.is_empty()) preconditioner = std::make_unique<
ILU<T>>(to_triplet_form<T, int>(
this));
202 else preconditioner = std::make_unique<ILU<T>>(this->triplet_mat);
205 else if(
PreconditionerType::NONE == this->setting.preconditioner_type) preconditioner = std::make_unique<UnityPreconditioner<T>>();
209 this->setting.preconditioner = preconditioner.get();
211 std::atomic_int code = 0;
215 Col<T> sub_x(X.colptr(I), X.n_rows, false, true);
216 const Col<T> sub_b(B.colptr(I), B.n_rows);
217 auto col_setting = setting;
218 code += GMRES(this, sub_x, sub_b, col_setting);
222 Col<T> sub_x(X.colptr(I), X.n_rows, false, true);
223 const Col<T> sub_b(B.colptr(I), B.n_rows);
224 auto col_setting = setting;
225 code += BiCGSTAB(this, sub_x, sub_b, col_setting);
227 else throw invalid_argument(
"no proper iterative solver assigned but somehow iterative solving is called");
238 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);
245 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
246 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);
251 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
254 for(index_t I = 0; I < in_mat.
n_elem; ++I) {
255 if(I >= in_mat.
row_mem()[c_idx]) ++c_idx;
263 Mat<data_t> out_mat(in_mat.
n_rows, in_mat.
n_cols, fill::zeros);
266 for(index_t I = 0; I < in_mat.
n_elem; ++I) {
267 if(I >= in_mat.
col_mem()[c_idx]) ++c_idx;
277 const sp_i auto n_rows = index_t(in_mat->
n_rows);
278 const sp_i auto n_cols = index_t(in_mat->
n_cols);
279 const sp_i auto n_elem = index_t(in_mat->
n_elem);
282 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: suanPan.h:319
unique_ptr< MetaMat< T > > operator*(const T value, const unique_ptr< MetaMat< T > > &M)
Definition: operator_times.hpp:24
Definition: SolverSetting.hpp:40
IterativeSolver iterative_solver
Definition: SolverSetting.hpp:46
constexpr auto SUANPAN_SUCCESS
Definition: suanPan.h:162
constexpr auto SUANPAN_FAIL
Definition: suanPan.h:163
#define suanpan_error(...)
Definition: suanPan.h:297
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:27