suanPan
Loading...
Searching...
No Matches
SparseMat.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2023 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
34template<sp_d T> class SparseMat : public MetaMat<T> {
35public:
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 [[nodiscard]] Col<T> diag() const override;
49
50 const T& operator()(uword, uword) const override;
51 T& at(uword, uword) override;
52
53 [[nodiscard]] const T* memptr() const override;
54 T* memptr() override;
55
56 void operator+=(const shared_ptr<MetaMat<T>>&) override;
57 void operator-=(const shared_ptr<MetaMat<T>>&) override;
58
59 void operator+=(const triplet_form<T, uword>&) override;
60 void operator-=(const triplet_form<T, uword>&) override;
61
62 Mat<T> operator*(const Mat<T>&) const override;
63
64 void operator*=(T) override;
65
66 [[nodiscard]] int sign_det() const override;
67
68 void csc_condense() override;
69 void csr_condense() override;
70
71 int iterative_solve(Mat<T>&, const Mat<T>&) override;
72};
73
74template<sp_d T> SparseMat<T>::SparseMat(const uword in_row, const uword in_col, const uword in_elem)
75 : MetaMat<T>(in_row, in_col, 0) { triplet_mat.init(in_elem); }
76
77template<sp_d T> bool SparseMat<T>::is_empty() const { return triplet_mat.is_empty(); }
78
79template<sp_d T> void SparseMat<T>::zeros() {
80 triplet_mat.zeros();
81 this->factored = false;
82}
83
84template<sp_d T> void SparseMat<T>::unify(const uword idx) {
85 nullify(idx);
86 triplet_mat.at(idx, idx) = 1.;
87}
88
89template<sp_d T> void SparseMat<T>::nullify(const uword idx) {
90 using index_t = typename decltype(triplet_mat)::index_type;
91
92 const auto t_idx = static_cast<index_t>(idx);
93
94 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.; });
95
96 this->factored = false;
97}
98
99template<sp_d T> T SparseMat<T>::max() const { return triplet_mat.max(); }
100
101template<sp_d T> Col<T> SparseMat<T>::diag() const { return triplet_mat.diag(); }
102
103template<sp_d T> const T& SparseMat<T>::operator()(const uword in_row, const uword in_col) const {
104 using index_t = typename decltype(triplet_mat)::index_type;
105 return triplet_mat(static_cast<index_t>(in_row), static_cast<index_t>(in_col));
106}
107
108template<sp_d T> T& SparseMat<T>::at(const uword in_row, const uword in_col) {
109 this->factored = false;
110 using index_t = typename decltype(triplet_mat)::index_type;
111 return triplet_mat.at(static_cast<index_t>(in_row), static_cast<index_t>(in_col));
112}
113
114template<sp_d T> const T* SparseMat<T>::memptr() const { throw invalid_argument("not supported"); }
115
116template<sp_d T> T* SparseMat<T>::memptr() { throw invalid_argument("not supported"); }
117
118template<sp_d T> void SparseMat<T>::operator+=(const shared_ptr<MetaMat<T>>& in_mat) {
119 if(nullptr == in_mat) return;
120
121 if(!in_mat->triplet_mat.is_empty()) return this->operator+=(in_mat->triplet_mat);
122
123 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;
124}
125
126template<sp_d T> void SparseMat<T>::operator-=(const shared_ptr<MetaMat<T>>& in_mat) {
127 if(nullptr == in_mat) return;
128
129 if(!in_mat->triplet_mat.is_empty()) return this->operator-=(in_mat->triplet_mat);
130
131 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;
132}
133
134template<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
139template<sp_d T> void SparseMat<T>::operator-=(const triplet_form<T, uword>& in_mat) {
140 this->triplet_mat -= in_mat;
141 this->factored = false;
142}
143
144template<sp_d T> Mat<T> SparseMat<T>::operator*(const Mat<T>& in_mat) const { return triplet_mat * in_mat; }
145
146template<sp_d T> void SparseMat<T>::operator*=(const T scalar) { triplet_mat *= scalar; }
147
148template<sp_d T> int SparseMat<T>::sign_det() const { throw invalid_argument("not supported"); }
149
150template<sp_d T> void SparseMat<T>::csc_condense() { triplet_mat.csc_condense(); }
151
152template<sp_d T> void SparseMat<T>::csr_condense() { triplet_mat.csr_condense(); }
153
154template<sp_d T> int SparseMat<T>::iterative_solve(Mat<T>& X, const Mat<T>& B) {
155 csc_condense();
156 return MetaMat<T>::iterative_solve(X, B);
157}
158
159#endif
160
A MetaMat class that holds matrices.
Definition: MetaMat.hpp:39
triplet_form< T, uword > triplet_mat
Definition: MetaMat.hpp:46
Mat< T > direct_solve(const C &B)
Definition: MetaMat.hpp:124
A SparseMat class that holds matrices.
Definition: SparseMat.hpp:34
Definition: triplet_form.hpp:62
void init(const index_t in_elem)
Definition: triplet_form.hpp:181
void zeros() override
Definition: SparseMat.hpp:79
int sign_det() const override
Definition: SparseMat.hpp:148
Mat< T > operator*(const Mat< T > &) const override
Definition: SparseMat.hpp:144
SparseMat(uword, uword, uword=0)
Definition: SparseMat.hpp:74
void operator+=(const shared_ptr< MetaMat< T > > &) override
Definition: SparseMat.hpp:118
const T * memptr() const override
Definition: SparseMat.hpp:114
void operator-=(const shared_ptr< MetaMat< T > > &) override
Definition: SparseMat.hpp:126
T max() const override
Definition: SparseMat.hpp:99
T & at(uword, uword) override
Access element with bound check.
Definition: SparseMat.hpp:108
int iterative_solve(Mat< T > &, const Mat< T > &) override
Definition: SparseMat.hpp:154
void csc_condense() override
Definition: SparseMat.hpp:150
void operator*=(T) override
Definition: SparseMat.hpp:146
Mat< T > iterative_solve(const Mat< T > &)
Definition: MetaMat.hpp:186
void csr_condense() override
Definition: SparseMat.hpp:152
const T & operator()(uword, uword) const override
Access element (read-only), returns zero if out-of-bound.
Definition: SparseMat.hpp:103
bool is_empty() const override
Definition: SparseMat.hpp:77
Col< T > diag() const override
Definition: SparseMat.hpp:101
void nullify(uword) override
Definition: SparseMat.hpp:89
void unify(uword) override
Definition: SparseMat.hpp:84
std::enable_if_t<!std::numeric_limits< T >::is_integer, bool > approx_equal(T x, T y, int ulp=2)
Definition: utility.h:58
const shared_ptr< MetaMat< T > > & operator-=(const shared_ptr< MetaMat< T > > &M, const shared_ptr< MetaMat< T > > &A)
Definition: operator_times.hpp:91
const shared_ptr< MetaMat< T > > & operator+=(const shared_ptr< MetaMat< T > > &M, const shared_ptr< MetaMat< T > > &A)
Definition: operator_times.hpp:50
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:27