23template<sp_d data_t, sp_i index_t>
class csc_form;
25template<sp_d data_t, sp_i index_t>
class csr_form final {
26 const data_t bin = data_t(0);
28 using index_ptr = std::unique_ptr<index_t[]>;
29 using data_ptr = std::unique_ptr<data_t[]>;
31 index_ptr row_ptr =
nullptr;
32 index_ptr col_idx =
nullptr;
33 data_ptr val_idx =
nullptr;
35 template<sp_d in_dt, sp_i in_it>
void copy_to(in_it*
const new_row_ptr, in_it*
const new_col_idx, in_dt*
const new_val_idx)
const {
38 new_col_idx[I] = in_it(col_idx[I]);
39 new_val_idx[I] = in_dt(val_idx[I]);
43 void init(
const index_t in_elem) {
44 row_ptr = std::move(index_ptr(
new index_t[
n_rows + 1]));
45 col_idx = std::move(index_ptr(
new index_t[in_elem]));
46 val_idx = std::move(data_ptr(
new data_t[in_elem]));
61 [[nodiscard]] const index_t*
row_mem()
const {
return row_ptr.get(); }
63 [[nodiscard]]
const index_t*
col_mem()
const {
return col_idx.get(); }
65 [[nodiscard]]
const data_t*
val_mem()
const {
return val_idx.get(); }
67 [[nodiscard]] index_t*
row_mem() {
return row_ptr.get(); }
69 [[nodiscard]] index_t*
col_mem() {
return col_idx.get(); }
71 [[nodiscard]] data_t*
val_mem() {
return val_idx.get(); }
73 [[nodiscard]] data_t
max()
const {
74 if(0 ==
n_elem)
return data_t(0);
82 return copy *= scalar;
87 return copy /= scalar;
103 :
csr_form(in_mat, in_base, in_full) {}
107 data_t
operator()(
const index_t in_row,
const index_t in_col)
const {
109 for(
auto I = row_ptr[in_row]; I < row_ptr[in_row + 1]; ++I)
110 if(in_col == col_idx[I])
return val_idx[I];
111 return access::rw(bin) = data_t(0);
114 Mat<data_t>
operator*(
const Col<data_t>& in_mat)
const {
115 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, 1);
117 suanpan::for_each(
n_rows, [&](
const index_t I) {
for(
auto J = row_ptr[I]; J < row_ptr[I + 1]; ++J) out_mat(I) += val_idx[J] * in_mat(col_idx[J]); });
122 Mat<data_t>
operator*(
const Mat<data_t>& in_mat)
const {
123 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, in_mat.n_cols);
125 suanpan::for_each(
n_rows, [&](
const index_t I) {
for(
auto J = row_ptr[I]; J < row_ptr[I + 1]; ++J) out_mat.row(I) += val_idx[J] * in_mat.row(col_idx[J]); });
132 : n_rows{in_mat.n_rows}
133 , n_cols{in_mat.n_cols}
134 , n_elem{in_mat.n_elem} {
136 in_mat.copy_to(row_ptr.get(), col_idx.get(), val_idx.get());
140 : row_ptr{std::move(in_mat.row_ptr)}
141 , col_idx{std::move(in_mat.col_idx)}
142 , val_idx{std::move(in_mat.val_idx)}
143 , n_rows{in_mat.n_rows}
144 , n_cols{in_mat.n_cols}
145 , n_elem{in_mat.n_elem} {}
148 if(
this == &in_mat)
return *
this;
149 access::rw(n_rows) = in_mat.
n_rows;
150 access::rw(n_cols) = in_mat.
n_cols;
151 access::rw(n_elem) = in_mat.
n_elem;
153 in_mat.copy_to(row_ptr.get(), col_idx.get(), val_idx.get());
158 if(
this == &in_mat)
return *
this;
159 access::rw(n_rows) = in_mat.
n_rows;
160 access::rw(n_cols) = in_mat.n_cols;
161 access::rw(n_elem) = in_mat.n_elem;
162 row_ptr = std::move(in_mat.row_ptr);
163 col_idx = std::move(in_mat.col_idx);
164 val_idx = std::move(in_mat.val_idx);
169 suanpan_info(
"A sparse matrix in triplet form with size of {} by {}, the sparsity of {:.3f}%.\n", n_rows, n_cols, 1E2 -
static_cast<double>(n_elem) /
static_cast<double>(n_rows) /
static_cast<double>(n_cols) * 1E2);
170 if(n_elem > index_t(1000)) {
176 for(index_t I = 0; I < n_elem; ++I) {
177 if(I >= row_ptr[c_idx]) ++c_idx;
178 suanpan_info(
"({}, {}) ===> {:+.8E}\n", c_idx - 1, col_idx[I], val_idx[I]);
205 : n_rows(index_t(in_mat.n_rows))
206 , n_cols(index_t(in_mat.n_cols)) {
212 const sp_i auto shift = index_t(base);
215 col_idx[I] = index_t(in_mat.col_idx[I]) + shift;
216 val_idx[I] = data_t(in_mat.val_idx[I]);
219 in_it current_pos = 0, current_row = 0;
221 while(current_pos < in_mat.
n_elem)
222 if(in_mat.row_idx[current_pos] < current_row) ++current_pos;
223 else row_ptr[current_row++] = index_t(current_pos) + shift;
232 access::rw(n_rows) = index_t(in_mat.
n_rows);
233 access::rw(n_cols) = index_t(in_mat.
n_cols);
235 init(access::rw(n_elem) = index_t(in_mat.
n_elem));
238 col_idx[I] = index_t(in_mat.col_idx[I]);
239 val_idx[I] = data_t(in_mat.val_idx[I]);
242 in_it current_pos = 0, current_row = 0;
244 while(current_pos < in_mat.
n_elem)
245 if(in_mat.row_idx[current_pos] < current_row) ++current_pos;
246 else row_ptr[current_row++] = index_t(current_pos);
248 row_ptr[0] = index_t(0);
249 row_ptr[n_rows] = n_elem;
constexpr T max_element(T start, T end)
Definition utility.h:42
void for_each(const IT start, const IT end, F &&FN)
Definition utility.h:31
#define suanpan_info
Definition suanPan.h:345
#define suanpan_for_each
Definition suanPan.h:181