suanPan
Loading...
Searching...
No Matches
DenseMat.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 DENSEMAT_HPP
30#define DENSEMAT_HPP
31
32#include "MetaMat.hpp"
33
34template<sp_d T> class DenseMat : public MetaMat<T> {
35 void init();
36
37protected:
38 podarray<int> pivot;
39 podarray<float> s_memory; // float storage used in mixed precision algorithm
40
41 podarray<float> to_float();
42
43 const T* const memory = nullptr;
44
45public:
47
48 DenseMat(uword, uword, uword);
49 DenseMat(const DenseMat&);
50 DenseMat(DenseMat&&) noexcept;
51 DenseMat& operator=(const DenseMat&);
52 DenseMat& operator=(DenseMat&&) noexcept;
53 ~DenseMat() override;
54
55 [[nodiscard]] bool is_empty() const override;
56 void zeros() override;
57
58 [[nodiscard]] T max() const override;
59 [[nodiscard]] Col<T> diag() const override;
60
61 const T* memptr() const override;
62 T* memptr() override;
63
64 void operator+=(const shared_ptr<MetaMat<T>>&) override;
65 void operator-=(const shared_ptr<MetaMat<T>>&) override;
66
67 void operator+=(const triplet_form<T, uword>&) override;
68 void operator-=(const triplet_form<T, uword>&) override;
69
70 void operator*=(T) override;
71
72 [[nodiscard]] int sign_det() const override;
73};
74
75template<sp_d T> void DenseMat<T>::init() {
76 if(nullptr != memory) memory::release(access::rw(memory));
77 access::rw(memory) = is_empty() ? nullptr : memory::acquire<T>(this->n_elem);
78}
79
80template<sp_d T> podarray<float> DenseMat<T>::to_float() {
81 podarray<float> f_memory(this->n_elem);
82
83 suanpan_for(0llu, this->n_elem, [&](const uword I) { f_memory(I) = static_cast<float>(memory[I]); });
84
85 return f_memory;
86}
87
88template<sp_d T> DenseMat<T>::DenseMat(const uword in_rows, const uword in_cols, const uword in_elem)
89 : MetaMat<T>(in_rows, in_cols, in_elem) {
90 init();
92}
93
94template<sp_d T> DenseMat<T>::DenseMat(const DenseMat& old_mat)
95 : MetaMat<T>(old_mat)
96 , pivot(old_mat.pivot)
97 , s_memory(old_mat.s_memory) {
98 init();
99 if(nullptr != old_mat.memory) std::copy(old_mat.memory, old_mat.memory + old_mat.n_elem, DenseMat<T>::memptr());
100}
101
102template<sp_d T> DenseMat<T>::DenseMat(DenseMat&& old_mat) noexcept
103 : MetaMat<T>(std::move(old_mat))
104 , pivot(std::move(old_mat.pivot))
105 , s_memory(std::move(old_mat.s_memory)) {
106 access::rw(memory) = old_mat.memory;
107 access::rw(old_mat.memory) = nullptr;
108}
109
110template<sp_d T> DenseMat<T>& DenseMat<T>::operator=(const DenseMat& old_mat) {
111 if(this == &old_mat) return *this;
112 MetaMat<T>::operator=(old_mat);
113 pivot = old_mat.pivot;
114 s_memory = old_mat.s_memory;
115 init();
116 if(nullptr != old_mat.memory) std::copy(old_mat.memory, old_mat.memory + old_mat.n_elem, memptr());
117 return *this;
118}
119
120template<sp_d T> DenseMat<T>& DenseMat<T>::operator=(DenseMat&& old_mat) noexcept {
121 if(this == &old_mat) return *this;
122 MetaMat<T>::operator=(std::move(old_mat));
123 pivot = std::move(old_mat.pivot);
124 s_memory = std::move(old_mat.s_memory);
125 access::rw(memory) = old_mat.memory;
126 access::rw(old_mat.memory) = nullptr;
127 return *this;
128}
129
130template<sp_d T> DenseMat<T>::~DenseMat() { if(nullptr != memory) memory::release(access::rw(memory)); }
131
132template<sp_d T> bool DenseMat<T>::is_empty() const { return 0 == this->n_elem; }
133
134template<sp_d T> void DenseMat<T>::zeros() {
135 arrayops::fill_zeros(memptr(), this->n_elem);
136 this->factored = false;
137}
138
139template<sp_d T> T DenseMat<T>::max() const {
140 T max_value = T(1);
141 const auto t_size = std::min(this->n_rows, this->n_cols);
142 for(uword I = 0; I < t_size; ++I) if(const auto t_val = this->operator()(I, I); t_val > max_value) max_value = t_val;
143 return max_value;
144}
145
146template<sp_d T> Col<T> DenseMat<T>::diag() const {
147 Col<T> diag_vec(std::min(this->n_rows, this->n_cols), fill::none);
148
149 suanpan_for(0llu, diag_vec.n_elem, [&](const uword I) { diag_vec(I) = this->operator()(I, I); });
150
151 return diag_vec;
152}
153
154template<sp_d T> const T* DenseMat<T>::memptr() const { return memory; }
155
156template<sp_d T> T* DenseMat<T>::memptr() { return const_cast<T*>(memory); }
157
158template<sp_d T> void DenseMat<T>::operator+=(const shared_ptr<MetaMat<T>>& M) {
159 if(nullptr == M) return;
160 if(!M->triplet_mat.is_empty()) return this->operator+=(M->triplet_mat);
161 if(this->n_rows != M->n_rows || this->n_cols != M->n_cols || this->n_elem != M->n_elem) return;
162 if(nullptr == M->memptr()) return;
163 arrayops::inplace_plus(memptr(), M->memptr(), this->n_elem);
164 this->factored = false;
165}
166
167template<sp_d T> void DenseMat<T>::operator-=(const shared_ptr<MetaMat<T>>& M) {
168 if(nullptr == M) return;
169 if(!M->triplet_mat.is_empty()) return this->operator-=(M->triplet_mat);
170 if(this->n_rows != M->n_rows || this->n_cols != M->n_cols || this->n_elem != M->n_elem) return;
171 if(nullptr == M->memptr()) return;
172 arrayops::inplace_minus(memptr(), M->memptr(), this->n_elem);
173 this->factored = false;
174}
175
176template<sp_d T> void DenseMat<T>::operator+=(const triplet_form<T, uword>& M) {
177 if(this->n_rows != M.n_rows || this->n_cols != M.n_cols) return;
178
179 const auto row = M.row_mem();
180 const auto col = M.col_mem();
181 const auto val = M.val_mem();
182 for(uword I = 0llu; I < M.n_elem; ++I) this->at(row[I], col[I]) += val[I];
183}
184
185template<sp_d T> void DenseMat<T>::operator-=(const triplet_form<T, uword>& M) {
186 if(this->n_rows != M.n_rows || this->n_cols != M.n_cols) return;
187
188 const auto row = M.row_mem();
189 const auto col = M.col_mem();
190 const auto val = M.val_mem();
191 for(uword I = 0llu; I < M.n_elem; ++I) this->at(row[I], col[I]) -= val[I];
192}
193
194template<sp_d T> void DenseMat<T>::operator*=(const T value) { arrayops::inplace_mul(memptr(), value, this->n_elem); }
195
196template<sp_d T> int DenseMat<T>::sign_det() const {
197 if(IterativeSolver::NONE != this->setting.iterative_solver) throw invalid_argument("analysis requires the sign of determinant but iterative solver does not support it");
198 auto det_sign = 1;
199 for(unsigned I = 0; I < pivot.n_elem; ++I) if((this->operator()(I, I) < 0.) ^ (static_cast<int>(I) + 1 != pivot(I))) det_sign = -det_sign;
200 return det_sign;
201}
202
203#endif
204
A DenseMat class that holds matrices.
Definition: DenseMat.hpp:34
podarray< int > pivot
Definition: DenseMat.hpp:38
podarray< float > s_memory
Definition: DenseMat.hpp:39
const T *const memory
Definition: DenseMat.hpp:43
A MetaMat class that holds matrices.
Definition: MetaMat.hpp:39
MetaMat & operator=(const MetaMat &)=delete
const uword n_elem
Definition: MetaMat.hpp:50
Mat< T > direct_solve(const C &B)
Definition: MetaMat.hpp:124
Definition: triplet_form.hpp:62
Definition: suanPan.h:318
podarray< float > to_float()
Definition: DenseMat.hpp:80
Col< T > diag() const override
Definition: DenseMat.hpp:146
const T * memptr() const override
Definition: DenseMat.hpp:154
void zeros() override
Definition: DenseMat.hpp:134
void operator+=(const shared_ptr< MetaMat< T > > &) override
Definition: DenseMat.hpp:158
DenseMat & operator=(const DenseMat &)
Definition: DenseMat.hpp:110
T max() const override
Definition: DenseMat.hpp:139
void operator*=(T) override
Definition: DenseMat.hpp:194
bool is_empty() const override
Definition: DenseMat.hpp:132
int sign_det() const override
Definition: DenseMat.hpp:196
DenseMat(uword, uword, uword)
Definition: DenseMat.hpp:88
~DenseMat() override
Definition: DenseMat.hpp:130
void operator-=(const shared_ptr< MetaMat< T > > &) override
Definition: DenseMat.hpp:167
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