suanPan
MetaMat.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (C) 2017-2022 Theodore Chang
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  ******************************************************************************/
29 #ifndef METAMAT_HPP
30 #define METAMAT_HPP
31 
32 #include "triplet_form.hpp"
33 
34 enum class Precision {
35  MIXED,
36  FULL
37 };
38 
39 template<sp_d T> class MetaMat {
40 protected:
41  bool factored = false;
42 
43  double tolerance = 1E-13;
44 
46 
47  unsigned refinement = 10;
48 
49 public:
51 
52  const uword n_rows;
53  const uword n_cols;
54  const uword n_elem;
55 
56  MetaMat(uword, uword, uword);
57  MetaMat(const MetaMat&) = default;
58  MetaMat(MetaMat&&) noexcept = delete;
59  MetaMat& operator=(const MetaMat&) = delete;
60  MetaMat& operator=(MetaMat&&) noexcept = delete;
61  virtual ~MetaMat() = default;
62 
63  void set_tolerance(double);
64  void set_precision(Precision);
65  void set_refinement(unsigned);
66  void set_factored(bool);
67 
68  [[nodiscard]] virtual bool is_empty() const = 0;
69  virtual void zeros() = 0;
70 
71  virtual unique_ptr<MetaMat> make_copy() = 0;
72 
73  virtual void unify(uword) = 0;
74  virtual void nullify(uword) = 0;
75 
76  [[nodiscard]] virtual T max() const = 0;
77 
78  virtual const T& operator()(uword, uword) const = 0;
79  virtual T& at(uword, uword) = 0;
80 
81  [[nodiscard]] virtual const T* memptr() const = 0;
82  virtual T* memptr() = 0;
83 
84  virtual void operator+=(const shared_ptr<MetaMat>&) = 0;
85  virtual void operator-=(const shared_ptr<MetaMat>&) = 0;
86 
87  virtual void operator+=(const triplet_form<T, uword>&) = 0;
88  virtual void operator-=(const triplet_form<T, uword>&) = 0;
89 
90  virtual Mat<T> operator*(const Mat<T>&) = 0;
91 
92  virtual void operator*=(T) = 0;
93 
94  Mat<T> solve(const Mat<T>&);
95  Mat<T> solve(const SpMat<T>&);
96  Mat<T> solve(Mat<T>&&);
97  Mat<T> solve(SpMat<T>&&);
98 
99  virtual int solve(Mat<T>&, const Mat<T>&) = 0;
100  virtual int solve(Mat<T>&, const SpMat<T>&);
101  virtual int solve(Mat<T>&, Mat<T>&&);
102  virtual int solve(Mat<T>&, SpMat<T>&&);
103 
104  [[nodiscard]] virtual int sign_det() const = 0;
105 
106  void save(const char*);
107 
108  virtual void csc_condense();
109  virtual void csr_condense();
110 };
111 
112 template<sp_d T> MetaMat<T>::MetaMat(const uword in_rows, const uword in_cols, const uword in_elem)
113  : triplet_mat(in_rows, in_cols)
114  , n_rows(in_rows)
115  , n_cols(in_cols)
116  , n_elem(in_elem) {}
117 
118 template<sp_d T> void MetaMat<T>::set_tolerance(const double TOL) { tolerance = TOL; }
119 
120 template<sp_d T> void MetaMat<T>::set_precision(const Precision P) { precision = P; }
121 
122 template<sp_d T> void MetaMat<T>::set_refinement(const unsigned R) { refinement = R; }
123 
124 template<sp_d T> void MetaMat<T>::set_factored(const bool F) { factored = F; }
125 
126 template<sp_d T> Mat<T> MetaMat<T>::solve(const Mat<T>& B) {
127  Mat<T> X;
128  if(0 != this->solve(X, B)) X.reset();
129  return X;
130 }
131 
132 template<sp_d T> Mat<T> MetaMat<T>::solve(const SpMat<T>& B) {
133  Mat<T> X;
134  if(0 != this->solve(X, B)) X.reset();
135  return X;
136 }
137 
138 template<sp_d T> Mat<T> MetaMat<T>::solve(Mat<T>&& B) {
139  Mat<T> X;
140  if(0 != this->solve(X, std::forward<Mat<T>>(B))) X.reset();
141  return X;
142 }
143 
144 template<sp_d T> Mat<T> MetaMat<T>::solve(SpMat<T>&& B) {
145  Mat<T> X;
146  if(0 != this->solve(X, std::forward<SpMat<T>>(B))) X.reset();
147  return X;
148 }
149 
150 template<sp_d T> int MetaMat<T>::solve(Mat<T>& X, const SpMat<T>& B) { return this->solve(X, Mat<T>(B)); }
151 
152 template<sp_d T> int MetaMat<T>::solve(Mat<T>& X, Mat<T>&& B) { return this->solve(X, B); }
153 
154 template<sp_d T> int MetaMat<T>::solve(Mat<T>& X, SpMat<T>&& B) { return this->solve(X, B); }
155 
156 template<sp_d T> void MetaMat<T>::save(const char* name) { if(!to_mat(*this).save(name)) suanpan_error("cannot save matrix to file.\n"); }
157 
158 template<sp_d T> void MetaMat<T>::csc_condense() {}
159 
160 template<sp_d T> void MetaMat<T>::csr_condense() {}
161 
162 template<sp_d T> Mat<T> to_mat(const MetaMat<T>& in_mat) {
163  Mat<T> out_mat(in_mat.n_rows, in_mat.n_cols);
164  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);
165  return out_mat;
166 }
167 
168 template<sp_d T> Mat<T> to_mat(const shared_ptr<MetaMat<T>>& in_mat) { return to_mat(*in_mat); }
169 
170 template<sp_d data_t, sp_i index_t> Mat<data_t> to_mat(const triplet_form<data_t, index_t>& in_mat) {
171  Mat<data_t> out_mat(in_mat.n_rows, in_mat.n_cols, fill::zeros);
172  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);
173  return out_mat;
174 }
175 
176 template<sp_d data_t, sp_i index_t> Mat<data_t> to_mat(const csr_form<data_t, index_t>& in_mat) {
177  Mat<data_t> out_mat(in_mat.n_rows, in_mat.n_cols, fill::zeros);
178 
179  index_t c_idx = 1;
180  for(index_t I = 0; I < in_mat.n_elem; ++I) {
181  if(I >= in_mat.row_mem()[c_idx]) ++c_idx;
182  out_mat(c_idx - 1, in_mat.col_mem()[I]) += in_mat.val_mem()[I];
183  }
184 
185  return out_mat;
186 }
187 
188 template<sp_d data_t, sp_i index_t> Mat<data_t> to_mat(const csc_form<data_t, index_t>& in_mat) {
189  Mat<data_t> out_mat(in_mat.n_rows, in_mat.n_cols, fill::zeros);
190 
191  index_t c_idx = 1;
192  for(index_t I = 0; I < in_mat.n_elem; ++I) {
193  if(I >= in_mat.col_mem()[c_idx]) ++c_idx;
194  out_mat(in_mat.row_mem()[I], c_idx - 1) += in_mat.val_mem()[I];
195  }
196 
197  return out_mat;
198 }
199 
200 template<sp_d data_t, sp_i index_t> triplet_form<data_t, index_t> to_triplet_form(const shared_ptr<MetaMat<data_t>>& in_mat) {
201  if(!in_mat->triplet_mat.is_empty()) return triplet_form<data_t, index_t>(in_mat->triplet_mat);
202 
203  const sp_i auto n_rows = index_t(in_mat->n_rows);
204  const sp_i auto n_cols = index_t(in_mat->n_cols);
205  const sp_i auto n_elem = index_t(in_mat->n_elem);
206 
207  triplet_form<data_t, index_t> out_mat(n_rows, n_cols, n_elem);
208  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);
209 
210  return out_mat;
211 }
212 
213 #endif
214 
triplet_form< data_t, index_t > to_triplet_form(const shared_ptr< MetaMat< data_t >> &in_mat)
Definition: MetaMat.hpp:200
void set_tolerance(double)
Definition: MetaMat.hpp:118
const data_t * val_mem() const
Definition: csc_form.hpp:65
const index_t * row_mem() const
Definition: csr_form.hpp:61
const index_t n_elem
Definition: csc_form.hpp:52
void set_refinement(unsigned)
Definition: MetaMat.hpp:122
Definition: csc_form.hpp:25
concept sp_i
Definition: suanPan.h:232
void save(const char *)
Definition: MetaMat.hpp:156
const index_t n_cols
Definition: csr_form.hpp:51
const index_t * col_mem() const
Definition: csr_form.hpp:63
virtual void csr_condense()
Definition: MetaMat.hpp:160
triplet_form< T, uword > triplet_mat
Definition: MetaMat.hpp:50
const index_t * col_mem() const
Definition: csc_form.hpp:63
const index_t n_rows
Definition: csc_form.hpp:50
index_t col(const index_t I) const
Definition: triplet_form.hpp:161
const index_t n_elem
Definition: csr_form.hpp:52
Mat< T > solve(const Mat< T > &)
Definition: MetaMat.hpp:126
const index_t * row_mem() const
Definition: csc_form.hpp:61
data_t & at(index_t, index_t)
Definition: triplet_form.hpp:381
void set_factored(bool)
Definition: MetaMat.hpp:124
index_t row(const index_t I) const
Definition: triplet_form.hpp:159
unique_ptr< Material > make_copy(const shared_ptr< Material > &)
Definition: Material.cpp:359
const index_t n_rows
Definition: csr_form.hpp:50
Definition: csc_form.hpp:23
const index_t n_rows
Definition: triplet_form.hpp:128
const data_t * val_mem() const
Definition: csr_form.hpp:65
A MetaMat class that holds matrices.
Definition: MetaMat.hpp:39
const index_t n_cols
Definition: triplet_form.hpp:129
virtual void csc_condense()
Definition: MetaMat.hpp:158
const index_t n_cols
Definition: csc_form.hpp:51
const index_t n_elem
Definition: triplet_form.hpp:130
concept sp_d
Definition: suanPan.h:231
Mat< T > to_mat(const MetaMat< T > &in_mat)
Definition: MetaMat.hpp:162
data_t val(const index_t I) const
Definition: triplet_form.hpp:163
const uword n_elem
Definition: MetaMat.hpp:54
const uword n_cols
Definition: MetaMat.hpp:53
const uword n_rows
Definition: MetaMat.hpp:52
void set_precision(Precision)
Definition: MetaMat.hpp:120
Precision
Definition: MetaMat.hpp:34