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 {
108 if(in_row <
n_rows && in_col <
n_cols)
for(
auto I = row_ptr[in_row]; I < row_ptr[in_row + 1]; ++I)
if(in_col == col_idx[I])
return val_idx[I];
109 return access::rw(bin) = data_t(0);
112 Mat<data_t>
operator*(
const Col<data_t>& in_mat)
const {
113 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, 1);
115 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]); });
120 Mat<data_t>
operator*(
const Mat<data_t>& in_mat)
const {
121 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, in_mat.n_cols);
123 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]); });
130 : n_rows{in_mat.n_rows}
131 , n_cols{in_mat.n_cols}
132 , n_elem{in_mat.n_elem} {
134 in_mat.copy_to(row_ptr.get(), col_idx.get(), val_idx.get());
138 : row_ptr{std::move(in_mat.row_ptr)}
139 , col_idx{std::move(in_mat.col_idx)}
140 , val_idx{std::move(in_mat.val_idx)}
141 , n_rows{in_mat.n_rows}
142 , n_cols{in_mat.n_cols}
143 , n_elem{in_mat.n_elem} {}
146 if(
this == &in_mat)
return *
this;
147 access::rw(n_rows) = in_mat.
n_rows;
148 access::rw(n_cols) = in_mat.
n_cols;
149 access::rw(n_elem) = in_mat.
n_elem;
151 in_mat.copy_to(row_ptr.get(), col_idx.get(), val_idx.get());
156 if(
this == &in_mat)
return *
this;
157 access::rw(n_rows) = in_mat.
n_rows;
158 access::rw(n_cols) = in_mat.n_cols;
159 access::rw(n_elem) = in_mat.n_elem;
160 row_ptr = std::move(in_mat.row_ptr);
161 col_idx = std::move(in_mat.col_idx);
162 val_idx = std::move(in_mat.val_idx);
167 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);
168 if(n_elem > index_t(1000)) {
174 for(index_t I = 0; I < n_elem; ++I) {
175 if(I >= row_ptr[c_idx]) ++c_idx;
176 suanpan_info(
"({}, {}) ===> {:+.8E}\n", c_idx - 1, col_idx[I], val_idx[I]);
181 : n_rows(index_t(in_mat.n_rows))
182 , n_cols(index_t(in_mat.n_cols)) {
188 const sp_i auto shift = index_t(base);
191 col_idx[I] = index_t(in_mat.col_idx[I]) + shift;
192 val_idx[I] = data_t(in_mat.val_idx[I]);
195 in_it current_pos = 0, current_row = 0;
197 while(current_pos < in_mat.
n_elem)
198 if(in_mat.row_idx[current_pos] < current_row) ++current_pos;
199 else row_ptr[current_row++] = index_t(current_pos) + shift;
208 access::rw(n_rows) = index_t(in_mat.
n_rows);
209 access::rw(n_cols) = index_t(in_mat.
n_cols);
211 init(access::rw(n_elem) = index_t(in_mat.
n_elem));
214 col_idx[I] = index_t(in_mat.col_idx[I]);
215 val_idx[I] = data_t(in_mat.val_idx[I]);
218 in_it current_pos = 0, current_row = 0;
220 while(current_pos < in_mat.
n_elem)
221 if(in_mat.row_idx[current_pos] < current_row) ++current_pos;
222 else row_ptr[current_row++] = index_t(current_pos);
224 row_ptr[0] = index_t(0);
225 row_ptr[n_rows] = n_elem;
constexpr T max_element(T start, T end)
Definition utility.h:39
void for_each(const IT start, const IT end, F &&FN)
Definition utility.h:28
#define suanpan_info
Definition suanPan.h:369
#define suanpan_for_each
Definition suanPan.h:195