23 template<sp_d data_t, sp_i index_t>
class csr_form;
25 template<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 {
36 suanpan_for(index_t(0),
n_cols + 1, [&](
const index_t I) { new_col_ptr[I] = in_it(col_ptr[I]); });
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]));
58 csc_form& operator=(csc_form&&) noexcept;
59 ~csc_form() = default;
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 [[nodiscard]] data_t
max()
const {
74 if(0 == n_elem)
return data_t(0);
75 return *std::max_element(val_idx.get(), val_idx.get() +
n_elem);
82 return copy *= scalar;
87 return copy /= scalar;
104 const data_t&
operator()(
const index_t in_row,
const index_t in_col)
const {
105 if(in_row < n_rows && in_col < n_cols)
for(
auto I = col_ptr[in_col]; I < col_ptr[in_col + 1]; ++I)
if(in_row == row_idx[I])
return val_idx[I];
106 return access::rw(bin) = data_t(0);
110 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, 1);
111 for(index_t I = 0; I <
n_cols; ++I)
for(
auto J = col_ptr[I]; J < col_ptr[I + 1]; ++J) out_mat(row_idx[J]) += val_idx[J] * in_mat(I);
116 Mat<data_t> out_mat = arma::zeros<Mat<data_t>>(in_mat.n_rows, in_mat.n_cols);
117 for(index_t I = 0; I <
n_cols; ++I)
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);
127 in_mat.copy_to(row_idx.get(), col_ptr.get(), val_idx.get());
131 : row_idx{std::move(in_mat.row_idx)}
132 , col_ptr{std::move(in_mat.col_ptr)}
133 , val_idx{std::move(in_mat.val_idx)}
136 ,
n_elem{in_mat.n_elem} {}
139 if(
this == &in_mat)
return *
this;
144 in_mat.copy_to(row_idx.get(), col_ptr.get(), val_idx.get());
149 if(
this == &in_mat)
return *
this;
151 access::rw(
n_cols) = in_mat.n_cols;
152 access::rw(
n_elem) = in_mat.n_elem;
153 row_idx = std::move(in_mat.row_idx);
154 col_ptr = std::move(in_mat.col_ptr);
155 val_idx = std::move(in_mat.val_idx);
160 suanpan_info(
"A sparse matrix in triplet form with size of %u by %u, the sparsity of %.3f%%.\n", static_cast<unsigned>(
n_rows), static_cast<unsigned>(
n_cols), 1E2 - static_cast<double>(
n_elem) / static_cast<double>(
n_rows) / static_cast<double>(
n_cols) * 1E2);
161 if(
n_elem > index_t(1000)) {
167 for(index_t I = 0; I <
n_elem; ++I) {
168 if(I >= col_ptr[c_idx]) ++c_idx;
169 suanpan_info(
"(%3u, %3u) ===> %+.4E\n", static_cast<unsigned>(row_idx[I]), static_cast<unsigned>(c_idx) - 1, val_idx[I]);
181 const sp_i auto shift = index_t(base);
184 row_idx[I] = index_t(in_mat.row_idx[I]) + shift;
185 val_idx[I] = data_t(in_mat.val_idx[I]);
188 in_it current_pos = 0, current_col = 0;
190 while(current_pos < in_mat.
n_elem)
191 if(in_mat.col_idx[current_pos] < current_col) ++current_pos;
192 else col_ptr[current_col++] = index_t(current_pos) + shift;
207 row_idx[I] = index_t(in_mat.row_idx[I]);
208 val_idx[I] = data_t(in_mat.val_idx[I]);
211 in_it current_pos = 0, current_col = 0;
213 while(current_pos < in_mat.
n_elem)
214 if(in_mat.col_idx[current_pos] < current_col) ++current_pos;
215 else col_ptr[current_col++] = index_t(current_pos);
217 col_ptr[0] = index_t(0);
concept sp_i
Definition: suanPan.h:232
void suanpan_info(const char *M,...)
Definition: print.cpp:47
#define suanpan_for_each
Definition: suanPan.h:180
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:24