suanPan
DenseMat.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 DENSEMAT_HPP
30 #define DENSEMAT_HPP
31 
32 #include "MetaMat.hpp"
33 
34 template<sp_d T> class DenseMat : public MetaMat<T> {
35  void init();
36 
37 protected:
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 
45 public:
46  using MetaMat<T>::solve;
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  T max() const override;
59 
60  const T* memptr() const override;
61  T* memptr() override;
62 
63  void operator+=(const shared_ptr<MetaMat<T>>&) override;
64  void operator-=(const shared_ptr<MetaMat<T>>&) override;
65 
66  void operator+=(const triplet_form<T, uword>&) override;
67  void operator-=(const triplet_form<T, uword>&) override;
68 
69  void operator*=(T) override;
70 
71  [[nodiscard]] int sign_det() const override;
72 };
73 
74 template<sp_d T> void DenseMat<T>::init() {
75  if(nullptr != memory) memory::release(access::rw(memory));
76  access::rw(memory) = is_empty() ? nullptr : memory::acquire<T>(this->n_elem);
77 }
78 
79 template<sp_d T> podarray<float> DenseMat<T>::to_float() {
80  podarray<float> f_memory(this->n_elem);
81 
82  suanpan_for(0llu, this->n_elem, [&](const uword I) { f_memory(I) = static_cast<float>(memory[I]); });
83 
84  return f_memory;
85 }
86 
87 template<sp_d T> DenseMat<T>::DenseMat(const uword in_rows, const uword in_cols, const uword in_elem)
88  : MetaMat<T>(in_rows, in_cols, in_elem) {
89  init();
91 }
92 
93 template<sp_d T> DenseMat<T>::DenseMat(const DenseMat& old_mat)
94  : MetaMat<T>(old_mat)
95  , pivot(old_mat.pivot)
96  , s_memory(old_mat.s_memory) {
97  init();
98  if(nullptr != old_mat.memory) std::copy(old_mat.memory, old_mat.memory + old_mat.n_elem, DenseMat<T>::memptr());
99 }
100 
101 template<sp_d T> DenseMat<T>::DenseMat(DenseMat&& old_mat) noexcept
102  : MetaMat<T>(std::move(old_mat))
103  , pivot(std::move(old_mat.pivot))
104  , s_memory(std::move(old_mat.s_memory)) {
105  access::rw(memory) = old_mat.memory;
106  access::rw(old_mat.memory) = nullptr;
107 }
108 
109 template<sp_d T> DenseMat<T>& DenseMat<T>::operator=(const DenseMat& old_mat) {
110  if(this == &old_mat) return *this;
111  MetaMat<T>::operator=(old_mat);
112  pivot = old_mat.pivot;
113  s_memory = old_mat.s_memory;
114  init();
115  if(nullptr != old_mat.memory) std::copy(old_mat.memory, old_mat.memory + old_mat.n_elem, memptr());
116  return *this;
117 }
118 
119 template<sp_d T> DenseMat<T>& DenseMat<T>::operator=(DenseMat&& old_mat) noexcept {
120  if(this == &old_mat) return *this;
121  MetaMat<T>::operator=(std::move(old_mat));
122  pivot = std::move(old_mat.pivot);
123  s_memory = std::move(old_mat.s_memory);
124  access::rw(memory) = old_mat.memory;
125  access::rw(old_mat.memory) = nullptr;
126  return *this;
127 }
128 
129 template<sp_d T> DenseMat<T>::~DenseMat() { if(nullptr != memory) memory::release(access::rw(memory)); }
130 
131 template<sp_d T> bool DenseMat<T>::is_empty() const { return 0 == this->n_elem; }
132 
133 template<sp_d T> void DenseMat<T>::zeros() {
134  arrayops::fill_zeros(memptr(), this->n_elem);
135  this->factored = false;
136 }
137 
138 template<sp_d T> T DenseMat<T>::max() const { return op_max::direct_max(memptr(), this->n_elem); }
139 
140 template<sp_d T> const T* DenseMat<T>::memptr() const { return memory; }
141 
142 template<sp_d T> T* DenseMat<T>::memptr() { return const_cast<T*>(memory); }
143 
144 template<sp_d T> void DenseMat<T>::operator+=(const shared_ptr<MetaMat<T>>& M) {
145  if(nullptr == M) return;
146  if(!M->triplet_mat.is_empty()) return this->operator+=(M->triplet_mat);
147  if(this->n_rows != M->n_rows || this->n_cols != M->n_cols || this->n_elem != M->n_elem) return;
148  if(nullptr == M->memptr()) return;
149  arrayops::inplace_plus(memptr(), M->memptr(), this->n_elem);
150  this->factored = false;
151 }
152 
153 template<sp_d T> void DenseMat<T>::operator-=(const shared_ptr<MetaMat<T>>& M) {
154  if(nullptr == M) return;
155  if(!M->triplet_mat.is_empty()) return this->operator-=(M->triplet_mat);
156  if(this->n_rows != M->n_rows || this->n_cols != M->n_cols || this->n_elem != M->n_elem) return;
157  if(nullptr == M->memptr()) return;
158  arrayops::inplace_minus(memptr(), M->memptr(), this->n_elem);
159  this->factored = false;
160 }
161 
162 template<sp_d T> void DenseMat<T>::operator+=(const triplet_form<T, uword>& M) {
163  if(this->n_rows != M.n_rows || this->n_cols != M.n_cols) return;
164 
165  const auto row = M.row_mem();
166  const auto col = M.col_mem();
167  const auto val = M.val_mem();
168  for(uword I = 0llu; I < M.n_elem; ++I) this->at(row[I], col[I]) += val[I];
169 }
170 
171 template<sp_d T> void DenseMat<T>::operator-=(const triplet_form<T, uword>& M) {
172  if(this->n_rows != M.n_rows || this->n_cols != M.n_cols) return;
173 
174  const auto row = M.row_mem();
175  const auto col = M.col_mem();
176  const auto val = M.val_mem();
177  for(uword I = 0llu; I < M.n_elem; ++I) this->at(row[I], col[I]) -= val[I];
178 }
179 
180 template<sp_d T> void DenseMat<T>::operator*=(const T value) { arrayops::inplace_mul(memptr(), value, this->n_elem); }
181 
182 template<sp_d T> int DenseMat<T>::sign_det() const {
183  auto det_sign = 1;
184  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;
185  return det_sign;
186 }
187 
188 #endif
189 
bool factored
Definition: MetaMat.hpp:41
const data_t * val_mem() const
Definition: triplet_form.hpp:151
const T *const memory
Definition: DenseMat.hpp:43
const T * memptr() const override
Definition: DenseMat.hpp:140
A DenseMat class that holds matrices.
Definition: DenseMat.hpp:34
void operator+=(const shared_ptr< MetaMat< T >> &) override
Definition: DenseMat.hpp:144
void zeros() override
Definition: DenseMat.hpp:133
podarray< float > to_float()
Definition: DenseMat.hpp:79
Definition: triplet_form.hpp:62
podarray< float > s_memory
Definition: DenseMat.hpp:39
podarray< int > pivot
Definition: DenseMat.hpp:38
void operator*=(T) override
Definition: DenseMat.hpp:180
const index_t * col_mem() const
Definition: triplet_form.hpp:149
DenseMat & operator=(const DenseMat &)
Definition: DenseMat.hpp:109
DenseMat(uword, uword, uword)
Definition: DenseMat.hpp:87
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:24
int sign_det() const override
Definition: DenseMat.hpp:182
const index_t n_rows
Definition: triplet_form.hpp:128
A MetaMat class that holds matrices.
Definition: MetaMat.hpp:39
const index_t n_cols
Definition: triplet_form.hpp:129
const index_t * row_mem() const
Definition: triplet_form.hpp:147
bool is_empty() const override
Definition: DenseMat.hpp:131
const index_t n_elem
Definition: triplet_form.hpp:130
concept sp_d
Definition: suanPan.h:231
MetaMat & operator=(const MetaMat &)=delete
const uword n_elem
Definition: MetaMat.hpp:54
T max() const override
Definition: DenseMat.hpp:138
~DenseMat() override
Definition: DenseMat.hpp:129
void operator-=(const shared_ptr< MetaMat< T >> &) override
Definition: DenseMat.hpp:153
const uword n_rows
Definition: MetaMat.hpp:52
virtual T & at(uword, uword)=0