suanPan
SparseMat.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 SPARSEMAT_HPP
30 #define SPARSEMAT_HPP
31 
32 #include "MetaMat.hpp"
33 
34 template<sp_d T> class SparseMat : public MetaMat<T> {
35 public:
37  using MetaMat<T>::solve;
38 
39  SparseMat(uword, uword, uword = 0);
40 
41  [[nodiscard]] bool is_empty() const override;
42  void zeros() override;
43 
44  void unify(uword) override;
45  void nullify(uword) override;
46 
47  [[nodiscard]] T max() const override;
48 
49  const T& operator()(uword, uword) const override;
50  T& at(uword, uword) override;
51 
52  [[nodiscard]] const T* memptr() const override;
53  T* memptr() override;
54 
55  void operator+=(const shared_ptr<MetaMat<T>>&) override;
56  void operator-=(const shared_ptr<MetaMat<T>>&) override;
57 
58  void operator+=(const triplet_form<T, uword>&) override;
59  void operator-=(const triplet_form<T, uword>&) override;
60 
61  Mat<T> operator*(const Mat<T>&) override;
62 
63  void operator*=(T) override;
64 
65  [[nodiscard]] int sign_det() const override;
66 
67  void csc_condense() override;
68  void csr_condense() override;
69 };
70 
71 template<sp_d T> SparseMat<T>::SparseMat(const uword in_row, const uword in_col, const uword in_elem)
72  : MetaMat<T>(in_row, in_col, 0) { triplet_mat.init(in_elem); }
73 
74 template<sp_d T> bool SparseMat<T>::is_empty() const { return triplet_mat.is_empty(); }
75 
76 template<sp_d T> void SparseMat<T>::zeros() {
78  this->factored = false;
79 }
80 
81 template<sp_d T> void SparseMat<T>::unify(const uword idx) {
82  nullify(idx);
83  triplet_mat.at(idx, idx) = 1.;
84 }
85 
86 template<sp_d T> void SparseMat<T>::nullify(const uword idx) {
87  using index_t = typename decltype(triplet_mat)::index_type;
88 
89  const auto t_idx = static_cast<index_t>(idx);
90 
91  suanpan_for(static_cast<index_t>(0), triplet_mat.n_elem, [&](const index_t I) { if(triplet_mat.row(I) == t_idx || triplet_mat.col(I) == t_idx) triplet_mat.val_mem()[I] = 0.; });
92 
93  this->factored = false;
94 }
95 
96 template<sp_d T> T SparseMat<T>::max() const { return triplet_mat.max(); }
97 
98 template<sp_d T> const T& SparseMat<T>::operator()(const uword in_row, const uword in_col) const {
99  using index_t = typename decltype(triplet_mat)::index_type;
100  return triplet_mat(static_cast<index_t>(in_row), static_cast<index_t>(in_col));
101 }
102 
103 template<sp_d T> T& SparseMat<T>::at(const uword in_row, const uword in_col) {
104  this->factored = false;
105  using index_t = typename decltype(triplet_mat)::index_type;
106  return triplet_mat.at(static_cast<index_t>(in_row), static_cast<index_t>(in_col));
107 }
108 
109 template<sp_d T> const T* SparseMat<T>::memptr() const { throw invalid_argument("not supported"); }
110 
111 template<sp_d T> T* SparseMat<T>::memptr() { throw invalid_argument("not supported"); }
112 
113 template<sp_d T> void SparseMat<T>::operator+=(const shared_ptr<MetaMat<T>>& in_mat) {
114  if(nullptr == in_mat) return;
115 
116  if(!in_mat->triplet_mat.is_empty()) return this->operator+=(in_mat->triplet_mat);
117 
118  for(uword I = 0llu; I < in_mat->n_rows; ++I) for(uword J = 0llu; J < in_mat->n_cols; ++J) if(const auto t_val = in_mat->operator()(I, J); !suanpan::approx_equal(0., t_val)) at(I, J) = t_val;
119 }
120 
121 template<sp_d T> void SparseMat<T>::operator-=(const shared_ptr<MetaMat<T>>& in_mat) {
122  if(nullptr == in_mat) return;
123 
124  if(!in_mat->triplet_mat.is_empty()) return this->operator-=(in_mat->triplet_mat);
125 
126  for(uword I = 0llu; I < in_mat->n_rows; ++I) for(uword J = 0llu; J < in_mat->n_cols; ++J) if(const auto t_val = in_mat->operator()(I, J); !suanpan::approx_equal(0., t_val)) at(I, J) = -t_val;
127 }
128 
129 template<sp_d T> void SparseMat<T>::operator+=(const triplet_form<T, uword>& in_mat) {
130  this->triplet_mat += in_mat;
131  this->factored = false;
132 }
133 
134 template<sp_d T> void SparseMat<T>::operator-=(const triplet_form<T, uword>& in_mat) {
135  this->triplet_mat -= in_mat;
136  this->factored = false;
137 }
138 
139 template<sp_d T> Mat<T> SparseMat<T>::operator*(const Mat<T>& in_mat) { return triplet_mat * in_mat; }
140 
141 template<sp_d T> void SparseMat<T>::operator*=(const T scalar) { triplet_mat *= scalar; }
142 
143 template<sp_d T> int SparseMat<T>::sign_det() const { throw invalid_argument("not supported"); }
144 
146 
148 
149 #endif
150 
const T * memptr() const override
Definition: SparseMat.hpp:109
void operator+=(const shared_ptr< MetaMat< T >> &) override
Definition: SparseMat.hpp:113
bool factored
Definition: MetaMat.hpp:41
T max() const override
Definition: SparseMat.hpp:96
std::enable_if_t<!std::numeric_limits< T >::is_integer, bool > approx_equal(T x, T y, int ulp=2)
Definition: utility.h:46
Mat< T > operator*(const Mat< T > &) override
Definition: SparseMat.hpp:139
void init(const index_t in_elem)
Definition: triplet_form.hpp:181
void operator-=(const shared_ptr< MetaMat< T >> &) override
Definition: SparseMat.hpp:121
void operator*=(T) override
Definition: SparseMat.hpp:141
bool is_empty() const
Definition: triplet_form.hpp:169
void csc_condense()
Definition: triplet_form.hpp:209
triplet_form< T, uword > triplet_mat
Definition: MetaMat.hpp:50
int sign_det() const override
Definition: SparseMat.hpp:143
bool is_empty() const override
Definition: SparseMat.hpp:74
const T & operator()(uword, uword) const override
Definition: SparseMat.hpp:98
data_t & at(index_t, index_t)
Definition: triplet_form.hpp:381
data_t max() const
Definition: triplet_form.hpp:171
void nullify(uword) override
Definition: SparseMat.hpp:86
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:24
T & at(uword, uword) override
Definition: SparseMat.hpp:103
void csr_condense()
Definition: triplet_form.hpp:204
A MetaMat class that holds matrices.
Definition: MetaMat.hpp:39
A SparseMat class that holds matrices.
Definition: SparseMat.hpp:34
const index_t n_elem
Definition: triplet_form.hpp:130
void csr_condense() override
Definition: SparseMat.hpp:147
void zeros()
Definition: triplet_form.hpp:176
SparseMat(uword, uword, uword=0)
Definition: SparseMat.hpp:71
void zeros() override
Definition: SparseMat.hpp:76
void unify(uword) override
Definition: SparseMat.hpp:81
void csc_condense() override
Definition: SparseMat.hpp:145