23template<sp_d data_t, sp_i index_t>
class csr_form;
25template<sp_d data_t, sp_i index_t>
class csc_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_idx =
nullptr;
32 index_ptr col_ptr =
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_idx, in_it*
const new_col_ptr, in_dt*
const new_val_idx)
const {
38 new_row_idx[I] = in_it(row_idx[I]);
39 new_val_idx[I] = in_dt(val_idx[I]);
43 void init(
const index_t in_elem) {
44 row_idx = std::move(index_ptr(
new index_t[in_elem]));
45 col_ptr = std::move(index_ptr(
new index_t[
n_cols + 1]));
46 val_idx = std::move(data_ptr(
new data_t[in_elem]));
61 [[nodiscard]] const index_t*
row_mem()
const {
return row_idx.get(); }
63 [[nodiscard]]
const index_t*
col_mem()
const {
return col_ptr.get(); }
65 [[nodiscard]]
const data_t*
val_mem()
const {
return val_idx.get(); }
67 [[nodiscard]] index_t*
row_mem() {
return row_idx.get(); }
69 [[nodiscard]] index_t*
col_mem() {
return col_ptr.get(); }
71 [[nodiscard]] data_t*
val_mem() {
return val_idx.get(); }
73 index_t
row(
const index_t I)
const {
return row_idx[I]; }
75 index_t
col(
const index_t I)
const {
return col_ptr[I]; }
77 data_t
val(
const index_t I)
const {
return val_idx[I]; }
79 [[nodiscard]] data_t
max()
const {
80 if(0 ==
n_elem)
return data_t(0);
88 return copy *= scalar;
93 return copy /= scalar;
110 data_t
operator()(
const index_t in_row,
const index_t in_col)
const {
112 for(
auto I = col_ptr[in_col]; I < col_ptr[in_col + 1]; ++I)
113 if(in_row == row_idx[I])
return val_idx[I];
114 return access::rw(bin) = data_t(0);
117 Mat<data_t>
operator*(
const Col<data_t>& in_mat)
const {
118 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, 1);
119 for(index_t I = 0; I <
n_cols; ++I)
120 for(
auto J = col_ptr[I]; J < col_ptr[I + 1]; ++J) out_mat(row_idx[J]) += val_idx[J] * in_mat(I);
124 Mat<data_t>
operator*(
const Mat<data_t>& in_mat)
const {
125 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, in_mat.n_cols);
126 for(index_t I = 0; I <
n_cols; ++I)
127 for(
auto J = col_ptr[I]; J < col_ptr[I + 1]; ++J) out_mat.row(row_idx[J]) += val_idx[J] * in_mat.row(I);
133 : n_rows{in_mat.n_rows}
134 , n_cols{in_mat.n_cols}
135 , n_elem{in_mat.n_elem} {
137 in_mat.copy_to(row_idx.get(), col_ptr.get(), val_idx.get());
141 : row_idx{std::move(in_mat.row_idx)}
142 , col_ptr{std::move(in_mat.col_ptr)}
143 , val_idx{std::move(in_mat.val_idx)}
144 , n_rows{in_mat.n_rows}
145 , n_cols{in_mat.n_cols}
146 , n_elem{in_mat.n_elem} {}
149 if(
this == &in_mat)
return *
this;
150 access::rw(n_rows) = in_mat.
n_rows;
151 access::rw(n_cols) = in_mat.
n_cols;
152 access::rw(n_elem) = in_mat.
n_elem;
154 in_mat.copy_to(row_idx.get(), col_ptr.get(), val_idx.get());
159 if(
this == &in_mat)
return *
this;
160 access::rw(n_rows) = in_mat.
n_rows;
161 access::rw(n_cols) = in_mat.n_cols;
162 access::rw(n_elem) = in_mat.n_elem;
163 row_idx = std::move(in_mat.row_idx);
164 col_ptr = std::move(in_mat.col_ptr);
165 val_idx = std::move(in_mat.val_idx);
170 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);
171 if(n_elem > index_t(1000)) {
177 for(index_t I = 0; I < n_elem; ++I) {
178 if(I >= col_ptr[c_idx]) ++c_idx;
179 suanpan_info(
"({}, {}) ===> {:+.8E}\n", row_idx[I], c_idx - 1, val_idx[I]);
184 : n_rows(index_t(in_mat.n_rows))
185 , n_cols(index_t(in_mat.n_cols)) {
191 const sp_i auto shift = index_t(base);
194 row_idx[I] = index_t(in_mat.row_idx[I]) + shift;
195 val_idx[I] = data_t(in_mat.val_idx[I]);
198 in_it current_pos = 0, current_col = 0;
200 while(current_pos < in_mat.
n_elem)
201 if(in_mat.col_idx[current_pos] < current_col) ++current_pos;
202 else col_ptr[current_col++] = index_t(current_pos) + shift;
211 access::rw(n_rows) = index_t(in_mat.
n_rows);
212 access::rw(n_cols) = index_t(in_mat.
n_cols);
214 init(access::rw(n_elem) = index_t(in_mat.
n_elem));
217 row_idx[I] = index_t(in_mat.row_idx[I]);
218 val_idx[I] = data_t(in_mat.val_idx[I]);
221 in_it current_pos = 0, current_col = 0;
223 while(current_pos < in_mat.
n_elem)
224 if(in_mat.col_idx[current_pos] < current_col) ++current_pos;
225 else col_ptr[current_col++] = index_t(current_pos);
227 col_ptr[0] = index_t(0);
228 col_ptr[n_cols] = 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