Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
matrix_ctor_dtor.h
Go to the documentation of this file.
1 /*****************************************************************************
2 * Multiscale Universal Interface Code Coupling Library *
3 * *
4 * Copyright (C) 2023 W. Liu *
5 * *
6 * This software is jointly licensed under the Apache License, Version 2.0 *
7 * and the GNU General Public License version 3, you may use it according *
8 * to either. *
9 * *
10 * ** Apache License, version 2.0 ** *
11 * *
12 * Licensed under the Apache License, Version 2.0 (the "License"); *
13 * you may not use this file except in compliance with the License. *
14 * You may obtain a copy of the License at *
15 * *
16 * http://www.apache.org/licenses/LICENSE-2.0 *
17 * *
18 * Unless required by applicable law or agreed to in writing, software *
19 * distributed under the License is distributed on an "AS IS" BASIS, *
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
21 * See the License for the specific language governing permissions and *
22 * limitations under the License. *
23 * *
24 * ** GNU General Public License, version 3 ** *
25 * *
26 * This program is free software: you can redistribute it and/or modify *
27 * it under the terms of the GNU General Public License as published by *
28 * the Free Software Foundation, either version 3 of the License, or *
29 * (at your option) any later version. *
30 * *
31 * This program is distributed in the hope that it will be useful, *
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
34 * GNU General Public License for more details. *
35 * *
36 * You should have received a copy of the GNU General Public License *
37 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
38 *****************************************************************************/
39 
47 #ifndef MUI_MATRIX_CTOR_DTOR_H_
48 #define MUI_MATRIX_CTOR_DTOR_H_
49 
50 namespace mui {
51 namespace linalg {
52 
53 // **************************************************
54 // ************ Public member functions *************
55 // **************************************************
56 
57 // Constructor - takes in size of row and column to generate an matrix, with default arguments of format vectors.
58 template<typename ITYPE, typename VTYPE>
59 sparse_matrix<ITYPE,VTYPE>::sparse_matrix(ITYPE r, ITYPE c, const std::string &format, const std::vector<VTYPE> &value_vector, const std::vector<ITYPE> &row_vector, const std::vector<ITYPE> &column_vector)
60  : rows_(r), cols_(c) {
61 
63 
64 
65  if (!value_vector.empty()) {
66 
67  nnz_ = value_vector.size();
68 
69  if (matrix_format_ == format::COO) {
70 
71  matrix_coo.values_.reserve(value_vector.size());
72  matrix_coo.row_indices_.reserve(row_vector.size());
73  matrix_coo.col_indices_.reserve(column_vector.size());
74 
75  matrix_coo.values_ = std::vector<VTYPE>(value_vector.begin(), value_vector.end());
76  matrix_coo.row_indices_ = std::vector<ITYPE>(row_vector.begin(), row_vector.end());
77  matrix_coo.col_indices_ = std::vector<ITYPE>(column_vector.begin(), column_vector.end());
78 
79  } else if (matrix_format_ == format::CSR) {
80 
81  matrix_csr.values_.reserve(value_vector.size());
82  matrix_csr.row_ptrs_.reserve(row_vector.size());
83  matrix_csr.col_indices_.reserve(column_vector.size());
84 
85  matrix_csr.values_ = std::vector<VTYPE>(value_vector.begin(), value_vector.end());
86  matrix_csr.row_ptrs_ = std::vector<ITYPE>(row_vector.begin(), row_vector.end());
87  matrix_csr.col_indices_ = std::vector<ITYPE>(column_vector.begin(), column_vector.end());
88 
89  } else if (matrix_format_ == format::CSC) {
90 
91  matrix_csc.values_.reserve(value_vector.size());
92  matrix_csc.row_indices_.reserve(row_vector.size());
93  matrix_csc.col_ptrs_.reserve(column_vector.size());
94 
95  matrix_csc.values_ = std::vector<VTYPE>(value_vector.begin(), value_vector.end());
96  matrix_csc.row_indices_ = std::vector<ITYPE>(row_vector.begin(), row_vector.end());
97  matrix_csc.col_ptrs_ = std::vector<ITYPE>(column_vector.begin(), column_vector.end());
98 
99  } else {
100  std::cerr << "MUI Error [matrix_ctor_dtor.h]: Unrecognised matrix format for matrix constructor" << std::endl;
101  std::cerr << " Please set the matrix_format_ as:" << std::endl;
102  std::cerr << " format::COO: COOrdinate format" << std::endl;
103  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
104  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
105  std::abort();
106  }
107 
108  this->assert_valid_vector_size("matrix_ctor_dtor.h", "sparse_matrix constructor function");
109  } else {
110 
111  if (matrix_format_ == format::CSR) {
112  matrix_csr.row_ptrs_.resize((rows_+1), 0);
113  } else if (matrix_format_ == format::CSC) {
114  matrix_csc.col_ptrs_.resize((cols_+1), 0);
115  }
116  }
117 
118 }
119 
120 // Constructor - null matrix
121 template<typename ITYPE, typename VTYPE>
123  : rows_(0), cols_(0) {
124 
126 
127  if (matrix_format_ == format::CSR) {
128  matrix_csr.row_ptrs_.resize((rows_+1), 0);
129  } else if (matrix_format_ == format::CSC) {
130  matrix_csc.col_ptrs_.resize((cols_+1), 0);
131  }
132 
133 }
134 
135 // Constructor - takes in another sparse_matrix object as an argument
136 template<typename ITYPE, typename VTYPE>
138  : rows_(exist_mat.rows_),
139  cols_(exist_mat.cols_),
140  nnz_(exist_mat.nnz_),
141  matrix_format_(exist_mat.matrix_format_) {
142 
143  // Copy the data from the existing matrix
144  if (matrix_format_ == format::COO) {
145  matrix_coo.values_ = std::move(exist_mat.matrix_coo.values_);
146  matrix_coo.row_indices_ = std::move(exist_mat.matrix_coo.row_indices_);
147  matrix_coo.col_indices_ = std::move(exist_mat.matrix_coo.col_indices_);
148  } else if (matrix_format_ == format::CSR) {
149  matrix_csr.values_ = std::move(exist_mat.matrix_csr.values_);
150  matrix_csr.row_ptrs_ = std::move(exist_mat.matrix_csr.row_ptrs_);
151  matrix_csr.col_indices_ = std::move(exist_mat.matrix_csr.col_indices_);
152  } else if (matrix_format_ == format::CSC) {
153  matrix_csc.values_ = std::move(exist_mat.matrix_csc.values_);
154  matrix_csc.row_indices_ = std::move(exist_mat.matrix_csc.row_indices_);
155  matrix_csc.col_ptrs_ = std::move(exist_mat.matrix_csc.col_ptrs_);
156  } else {
157  std::cerr << "MUI Error [matrix_ctor_dtor.h]: Unrecognised matrix format for matrix constructor" << std::endl;
158  std::cerr << " Please set the matrix_format_ as:" << std::endl;
159  std::cerr << " format::COO: COOrdinate format" << std::endl;
160  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
161  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
162  std::abort();
163  }
164 
165 }
166 
167 // Constructor - takes in a std::vector with row major dense matrix format as an argument
168 template<typename ITYPE, typename VTYPE>
169 sparse_matrix<ITYPE,VTYPE>::sparse_matrix(const std::vector<std::vector<VTYPE>>& denseVector, const std::string &format) {
170 
172 
173  // Set the dimensions of the sparse matrix based on the dimensions of the dense matrix vector
174  rows_ = denseVector.size();
175  cols_ = denseVector[0].size();
176 
177  // Calculate the total number of non-zero elements
178  for (const auto& row : denseVector) {
179  for (ITYPE i = 0; i < row.size(); ++i) {
180  if (std::abs(row[i]) >= std::numeric_limits<VTYPE>::min()) {
181  nnz_++;
182  }
183  }
184  }
185 
186  // Reserve space for the sparse entries
187  matrix_coo.values_.reserve(nnz_);
188  matrix_coo.row_indices_.reserve(nnz_);
189  matrix_coo.col_indices_.reserve(nnz_);
190 
191  // Loop over the dense matrix vector and add non-zero entries to COO data
192  for (ITYPE i = 0; i < rows_; ++i) {
193  for (ITYPE j = 0; j < cols_; ++j) {
194  const VTYPE val = denseVector[i][j];
195  if (std::abs(val) >= std::numeric_limits<VTYPE>::min()) {
196  matrix_coo.values_.emplace_back(val);
197  matrix_coo.row_indices_.emplace_back(i);
198  matrix_coo.col_indices_.emplace_back(j);
199  }
200  }
201  }
202 
203  if (matrix_format_ == format::COO) {
204 
205  // Do nothing
206 
207  } else if (matrix_format_ == format::CSR) {
208 
209  matrix_format_ = format::COO;
211 
212  } else if (matrix_format_ == format::CSC) {
213 
214  matrix_format_ = format::COO;
217 
218  } else {
219 
220  std::cerr << "MUI Error [matrix_ctor_dtor.h]: Unrecognised matrix format for matrix constructor" << std::endl;
221  std::cerr << " Please set the matrix_format_ as:" << std::endl;
222  std::cerr << " format::COO: COOrdinate format" << std::endl;
223  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
224  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
225  std::abort();
226 
227  }
228 
229 }
230 
231 // Constructor - generate various square matrices
232 template<typename ITYPE, typename VTYPE>
233 sparse_matrix<ITYPE,VTYPE>::sparse_matrix(ITYPE n, const std::string &token, const std::string &format)
234  : rows_(n), cols_(n) {
235 
236  this->set_matrix_format(format);
237 
238  if(token.empty()) {
239 
240  // empty (all-zero) square matrix (Do nothing from the code perspective)
241  if (matrix_format_ == format::CSR) {
242  matrix_csr.row_ptrs_.resize((rows_+1), 0);
243  } else if (matrix_format_ == format::CSC) {
244  matrix_csc.col_ptrs_.resize((cols_+1), 0);
245  }
246 
247  } else if(string_to_lower(trim(token))=="identity") {
248 
249  // set number of non-zero elements as n
250  nnz_ = n;
251 
252  // identity square matrix
253  if (matrix_format_ == format::COO) {
254 
255  matrix_coo.values_.reserve(n);
256  matrix_coo.row_indices_.reserve(n);
257  matrix_coo.col_indices_.reserve(n);
258 
259  for (ITYPE i = 0; i < n; ++i) {
260  matrix_coo.values_.emplace_back(1.0);
261  matrix_coo.row_indices_.emplace_back(i);
262  matrix_coo.col_indices_.emplace_back(i);
263  }
264 
265  } else if (matrix_format_ == format::CSR) {
266 
267  matrix_csr.values_.reserve(n);
268  matrix_csr.row_ptrs_.reserve(n+1);
269  matrix_csr.col_indices_.reserve(n);
270 
271  for (ITYPE i = 0; i < n; i++) {
272  matrix_csr.values_.emplace_back(1.0);
273  matrix_csr.row_ptrs_.emplace_back(i);
274  matrix_csr.col_indices_.emplace_back(i);
275  }
276 
277  matrix_csr.row_ptrs_.emplace_back(n);
278 
279  } else if (matrix_format_ == format::CSC) {
280 
281  matrix_csc.values_.reserve(n);
282  matrix_csc.row_indices_.reserve(n);
283  matrix_csc.col_ptrs_.reserve(n+1);
284 
285  for (ITYPE i = 0; i < n; ++i) {
286  matrix_csc.values_.emplace_back(1.0);
287  matrix_csc.row_indices_.emplace_back(i);
288  matrix_csc.col_ptrs_.emplace_back(i);
289  }
290 
291  matrix_csc.col_ptrs_.emplace_back(n);
292 
293  } else {
294  std::cerr << "MUI Error [matrix_ctor_dtor.h]: Unrecognised matrix format for matrix constructor" << std::endl;
295  std::cerr << " Please set the matrix_format_ as:" << std::endl;
296  std::cerr << " format::COO: COOrdinate format" << std::endl;
297  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
298  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
299  std::abort();
300  }
301 
302  } else {
303  std::cerr << "MUI Error [matrix_ctor_dtor.h]: unidentified token string for square matrix constructor" << std::endl;
304  std::cerr << " Please set the token string as:" << std::endl;
305  std::cerr << " empty string (default): Empty (all-zero) square matrix" << std::endl;
306  std::cerr << " 'identity': identity square matrix" << std::endl;
307  std::abort();
308  }
309 }
310 
311 // Destructor
312 template<typename ITYPE, typename VTYPE>
314 
315  // deallocate the memory for non-zero elements
316  matrix_coo.values_.clear();
317  matrix_coo.row_indices_.clear();
318  matrix_coo.col_indices_.clear();
319 
320  matrix_csr.values_.clear();
321  matrix_csr.row_ptrs_.clear();
322  matrix_csr.col_indices_.clear();
323 
324  matrix_csc.values_.clear();
325  matrix_csc.row_indices_.clear();
326  matrix_csc.col_ptrs_.clear();
327 
328  // Reset sparse matrix properties
329  rows_ = 0;
330  cols_ = 0;
331  nnz_ = 0;
332  matrix_format_ = format::CSR;
333  matrix_csr.row_ptrs_.resize(1, 0);
334 
335 }
336 
337 // **************************************************
338 // ********** Protected member functions ************
339 // **************************************************
340 
341 // Protected member function to set matrix format - helper function on matrix constructors
342 template<typename ITYPE, typename VTYPE>
343 void sparse_matrix<ITYPE,VTYPE>::set_matrix_format(const std::string &format) {
344 
345  std::string matrix_format = string_to_upper(trim(format));
346 
347  if (matrix_format == "COO") {
348  matrix_format_ = format::COO;
349  } else if (matrix_format == "CSR") {
350  matrix_format_ = format::CSR;
351  } else if (matrix_format == "CSC") {
352  matrix_format_ = format::CSC;
353  } else {
354  std::cerr << "MUI Error [matrix_ctor_dtor.h]: Unrecognised format type: " << format << " for matrix constructor" << std::endl;
355  std::cerr << " Please set the format string as:" << std::endl;
356  std::cerr << " 'COO': COOrdinate format" << std::endl;
357  std::cerr << " 'CSR' (default): Compressed Sparse Row format" << std::endl;
358  std::cerr << " 'CSC': Compressed Sparse Column format" << std::endl;
359  std::abort();
360  }
361 
362 }
363 
364 } // linalg
365 } // mui
366 
367 #endif /* MUI_MATRIX_CTOR_DTOR_H_ */
Definition: matrix.h:61
sparse_matrix(ITYPE, ITYPE, const std::string &="CSR", const std::vector< VTYPE > &={}, const std::vector< ITYPE > &={}, const std::vector< ITYPE > &={})
Definition: matrix_ctor_dtor.h:59
void set_matrix_format(const std::string &="CSR")
Definition: matrix_ctor_dtor.h:343
void coo_to_csc()
Definition: matrix_manipulation.h:1772
void assert_valid_vector_size(const std::string &={}, const std::string &={}) const
Definition: matrix_asserts.h:61
void resize(ITYPE, ITYPE)
Definition: matrix_manipulation.h:62
void coo_to_csr()
Definition: matrix_manipulation.h:1720
void sort_coo(bool=true, bool=false, const std::string &="overwrite")
Definition: matrix_manipulation.h:808
u u u u u u min
Definition: dim.h:289
std::string string_to_lower(const std::string &s)
Definition: linalg_util.h:78
std::string trim(const std::string &s)
Definition: linalg_util.h:73
std::string string_to_upper(const std::string &s)
Definition: linalg_util.h:85
Definition: comm.h:54