Multiscale Universal Interface  2.0
A Concurrent Framework for Coupling Heterogeneous Solvers
matrix_io_info.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_IO_INFO_H_
48 #define MUI_MATRIX_IO_INFO_H_
49 
50 #include <sstream>
51 #include <fstream>
52 #include <cassert>
53 #include <limits>
54 #include <algorithm>
55 #include <cctype>
56 
57 namespace mui {
58 namespace linalg {
59 
60 // **************************************************
61 // ************ Public member functions *************
62 // **************************************************
63 
64 // Member function to print matrix elements to the console
65 template<typename ITYPE, typename VTYPE>
67  for (ITYPE i = 0; i < rows_; ++i) {
68  std::cout << " ";
69  for (ITYPE j = 0; j < cols_; ++j){
70  std::cout << this->get_value(i,j) << " ";
71  }
72  std::cout << std::endl;
73  }
74 }
75 
76 // Member function to print matrix vectors to the console
77 template<typename ITYPE, typename VTYPE>
79  if (matrix_format_ == format::COO) {
80  std::cout << "The Value vector of matrix in COO format: " << std::endl;
81  std::cout << " ";
82  for (const auto& element : matrix_coo.values_) {
83  std::cout << element << " ";
84  }
85  std::cout << std::endl;
86 
87  std::cout << "The Row Index vector of matrix in COO format: " << std::endl;
88  std::cout << " ";
89  for (const auto& element : matrix_coo.row_indices_) {
90  std::cout << element << " ";
91  }
92  std::cout << std::endl;
93 
94  std::cout << "The Column Index vector of matrix in COO format: " << std::endl;
95  std::cout << " ";
96  for (const auto& element : matrix_coo.col_indices_) {
97  std::cout << element << " ";
98  }
99  std::cout << std::endl;
100  } else if (matrix_format_ == format::CSR) {
101  std::cout << "The Value vector of matrix in CSR format: " << std::endl;
102  std::cout << " ";
103  for (const auto& element : matrix_csr.values_) {
104  std::cout << element << " ";
105  }
106  std::cout << std::endl;
107 
108  std::cout << "The Row Pointers vector of matrix in CSR format: " << std::endl;
109  std::cout << " ";
110  for (const auto& element : matrix_csr.row_ptrs_) {
111  std::cout << element << " ";
112  }
113  std::cout << std::endl;
114 
115  std::cout << "The Column Index vector of matrix in CSR format: " << std::endl;
116  std::cout << " ";
117  for (const auto& element : matrix_csr.col_indices_) {
118  std::cout << element << " ";
119  }
120  std::cout << std::endl;
121  } else if (matrix_format_ == format::CSC) {
122  std::cout << "The Value vector of matrix in CSC format: " << std::endl;
123  std::cout << " ";
124  for (const auto& element : matrix_csc.values_) {
125  std::cout << element << " ";
126  }
127  std::cout << std::endl;
128 
129  std::cout << "The Row Index vector of matrix in CSC format: " << std::endl;
130  std::cout << " ";
131  for (const auto& element : matrix_csc.row_indices_) {
132  std::cout << element << " ";
133  }
134  std::cout << std::endl;
135 
136  std::cout << "The Column Pointers vector of matrix in CSC format: " << std::endl;
137  std::cout << " ";
138  for (const auto& element : matrix_csc.col_ptrs_) {
139  std::cout << element << " ";
140  }
141  std::cout << std::endl;
142  } else {
143  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix print_vectors >>" << std::endl;
144  std::cerr << " Please set the matrix_format_ as:" << std::endl;
145  std::cerr << " format::COO: COOrdinate format" << std::endl;
146  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
147  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
148  std::abort();
149  }
150 }
151 
152 // Member function to write matrix vectors to the file
153 template<typename ITYPE, typename VTYPE>
154 void sparse_matrix<ITYPE,VTYPE>::write_vectors_to_file(const std::string &format_file_name, const std::string &val_file_name, const std::string &row_file_name, const std::string &col_file_name) const {
155 
156  std::string ffn;
157  std::string vfn;
158  std::string rfn;
159  std::string cfn;
160 
161  // Open three separate output files
162  if ((val_file_name.empty()) || (row_file_name.empty()) || (col_file_name.empty())) {
163  ffn = format_file_name + "_format.dat";
164  vfn = format_file_name + "_value.dat";
165  rfn = format_file_name + "_row.dat";
166  cfn = format_file_name + "_column.dat";
167  } else {
168  ffn = format_file_name;
169  vfn = val_file_name;
170  rfn = row_file_name;
171  cfn = col_file_name;
172  }
173 
174  std::ofstream formatFile(ffn);
175  std::ofstream valueFile(vfn);
176  std::ofstream rowFile(rfn);
177  std::ofstream columnFile(cfn);
178 
179  // Check if all files were opened successfully
180  if (!formatFile) {
181  std::cerr << "MUI Error [matrix_io_info.h]: Error opening format output files in write_vectors_to_file()." << std::endl;
182  std::abort();
183  }
184  if (!valueFile) {
185  std::cerr << "MUI Error [matrix_io_info.h]: Error opening value vector output files in write_vectors_to_file()." << std::endl;
186  std::abort();
187  }
188  if (!rowFile) {
189  std::cerr << "MUI Error [matrix_io_info.h]: Error opening row vector output files in write_vectors_to_file()." << std::endl;
190  std::abort();
191  }
192  if (!columnFile) {
193  std::cerr << "MUI Error [matrix_io_info.h]: Error opening column vector output files in write_vectors_to_file()." << std::endl;
194  std::abort();
195  }
196 
197 
198 
199  if (matrix_format_ == format::COO) {
200  formatFile << "COO" << "\n";
201  formatFile << rows_ << "\n";
202  formatFile << cols_ << "\n";
203  // Write the contents of the vectors to the respective files
204  for (ITYPE i = 0; i < matrix_coo.values_.size(); ++i) {
205  valueFile << matrix_coo.values_[i] << "\n";
206  rowFile << matrix_coo.row_indices_[i] << "\n";
207  columnFile << matrix_coo.col_indices_[i] << "\n";
208  }
209  } else if (matrix_format_ == format::CSR) {
210  formatFile << "CSR" << "\n";
211  formatFile << rows_ << "\n";
212  formatFile << cols_ << "\n";
213  // Write the contents of the vectors to the respective files
214  for (ITYPE i = 0; i < matrix_csr.values_.size(); ++i) {
215  valueFile << matrix_csr.values_[i] << "\n";
216  columnFile << matrix_csr.col_indices_[i] << "\n";
217  }
218  for (ITYPE i = 0; i < (rows_+1); ++i) {
219  rowFile << matrix_csr.row_ptrs_[i] << "\n";
220  }
221  } else if (matrix_format_ == format::CSC) {
222  formatFile << "CSC" << "\n";
223  formatFile << rows_ << "\n";
224  formatFile << cols_ << "\n";
225  // Write the contents of the vectors to the respective files
226  for (ITYPE i = 0; i < matrix_csc.values_.size(); ++i) {
227  valueFile << matrix_csc.values_[i] << "\n";
228  rowFile << matrix_csc.row_indices_[i] << "\n";
229  }
230  for (ITYPE i = 0; i < (cols_+1); ++i) {
231  columnFile << matrix_csc.col_ptrs_[i] << "\n";
232  }
233  } else {
234  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix write_vectors_to_file() >>" << std::endl;
235  std::cerr << " Please set the matrix_format_ as:" << std::endl;
236  std::cerr << " format::COO: COOrdinate format" << std::endl;
237  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
238  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
239  std::abort();
240  }
241 
242  // Close the files
243  formatFile.close();
244  valueFile.close();
245  rowFile.close();
246  columnFile.close();
247 
248 }
249 
250 // Member function to read matrix vectors to the file
251 template<typename ITYPE, typename VTYPE>
252 void sparse_matrix<ITYPE,VTYPE>::read_vectors_from_file(const std::string &format_file_name, const std::string &val_file_name, const std::string &row_file_name, const std::string &col_file_name) {
253 
254  std::string ffn;
255  std::string vfn;
256  std::string rfn;
257  std::string cfn;
258 
259  // Open three separate input files
260  if ((val_file_name.empty()) || (row_file_name.empty()) || (col_file_name.empty())) {
261  ffn = format_file_name + "_format.dat";
262  vfn = format_file_name + "_value.dat";
263  rfn = format_file_name + "_row.dat";
264  cfn = format_file_name + "_column.dat";
265  } else {
266  ffn = format_file_name;
267  vfn = val_file_name;
268  rfn = row_file_name;
269  cfn = col_file_name;
270  }
271 
272  std::ifstream formatFile(ffn);
273  std::ifstream valueFile(vfn);
274  std::ifstream rowFile(rfn);
275  std::ifstream columnFile(cfn);
276 
277  // Check if all files were opened successfully
278  if (!formatFile) {
279  std::cerr << "MUI Error [matrix_io_info.h]: Error opening format input files in read_vectors_from_file()." << std::endl;
280  std::abort();
281  }
282  if (!valueFile) {
283  std::cerr << "MUI Error [matrix_io_info.h]: Error opening value vector input files in read_vectors_from_file()." << std::endl;
284  std::abort();
285  }
286  if (!rowFile) {
287  std::cerr << "MUI Error [matrix_io_info.h]: Error opening row vector input files in read_vectors_from_file()." << std::endl;
288  std::abort();
289  }
290  if (!columnFile) {
291  std::cerr << "MUI Error [matrix_io_info.h]: Error opening column vector input files in read_vectors_from_file()." << std::endl;
292  std::abort();
293  }
294 
295  assert((this->empty()) &&
296  "MUI Error [matrix_io_info.h]: read_vectors_from_file() can only takes in null matrix or empty (all-zero) matrix");
297 
298  format format_store = this->matrix_format_;
299 
300  std::string file_matrix_format;
301 
302  formatFile >> file_matrix_format;
303  formatFile >> rows_;
304  formatFile >> cols_;
305 
306  std::string file_matrix_format_trim = string_to_upper(trim(file_matrix_format));
307 
308 
309  if (file_matrix_format_trim == "COO") {
310  this->clear_vectors();
311  // Read the contents of the vectors from the respective files
312  int val;
313  while (valueFile >> val) {
314  matrix_coo.values_.reserve(matrix_coo.values_.size()+1);
315  matrix_coo.values_.emplace_back(val);
316  }
317  int row_idx;
318  while (rowFile >> row_idx) {
319  matrix_coo.row_indices_.reserve(matrix_coo.row_indices_.size()+1);
320  matrix_coo.row_indices_.emplace_back(row_idx);
321  }
322  int col_idx;
323  while (columnFile >> col_idx) {
324  matrix_coo.col_indices_.reserve(matrix_coo.col_indices_.size()+1);
325  matrix_coo.col_indices_.emplace_back(col_idx);
326  }
327  matrix_format_ = format::COO;
328  nnz_ = matrix_coo.values_.size();
329  } else if (file_matrix_format_trim == "CSR") {
330  this->clear_vectors();
331  // Read the contents of the vectors from the respective files
332  int val;
333  while (valueFile >> val) {
334  matrix_csr.values_.reserve(matrix_csr.values_.size()+1);
335  matrix_csr.values_.emplace_back(val);
336  }
337 
338  int row_ptr;
339  while (rowFile >> row_ptr) {
340  matrix_csr.row_ptrs_.reserve(matrix_csr.row_ptrs_.size()+1);
341  matrix_csr.row_ptrs_.emplace_back(row_ptr);
342  }
343 
344  int col_idx;
345  while (columnFile >> col_idx) {
346  matrix_csr.col_indices_.reserve(matrix_csr.col_indices_.size()+1);
347  matrix_csr.col_indices_.emplace_back(col_idx);
348  }
349 
350  matrix_format_ = format::CSR;
351  nnz_ = matrix_csr.values_.size();
352 
353  } else if (file_matrix_format_trim == "CSC") {
354  this->clear_vectors();
355  // Read the contents of the vectors from the respective files
356  int val;
357  while (valueFile >> val) {
358  matrix_csc.values_.reserve(matrix_csc.values_.size()+1);
359  matrix_csc.values_.emplace_back(val);
360  }
361  int row_idx;
362  while (rowFile >> row_idx) {
363  matrix_csc.row_indices_.reserve(matrix_csc.row_indices_.size()+1);
364  matrix_csc.row_indices_.emplace_back(row_idx);
365  }
366  int col_ptr;
367  while (columnFile >> col_ptr) {
368  matrix_csc.col_ptrs_.reserve(matrix_csc.col_ptrs_.size()+1);
369  matrix_csc.col_ptrs_.emplace_back(col_ptr);
370  }
371  matrix_format_ = format::CSC;
372  nnz_ = matrix_csc.values_.size();
373  } else {
374  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format: " << file_matrix_format_trim << " for matrix read_vectors_from_file() >>" << std::endl;
375  std::cerr << " Please set the matrix format as:" << std::endl;
376  std::cerr << " format::COO: COOrdinate format" << std::endl;
377  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
378  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
379  std::abort();
380  }
381 
382  // Close the files
383  formatFile.close();
384  valueFile.close();
385  rowFile.close();
386  columnFile.close();
387 
388  this->assert_valid_vector_size("matrix_io_info.h", "read_vectors_from_file()");
389 
390  if (format_store != matrix_format_) {
391  if (format_store == format::COO) {
392  this->format_conversion("COO", true, true, "overwrite");
393  } else if (format_store == format::CSR) {
394  this->format_conversion("CSR", true, true, "overwrite");
395  } else if (format_store == format::CSC) {
396  this->format_conversion("CSC", true, true, "overwrite");
397  } else {
398  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix write_vectors_to_file()" << std::endl;
399  std::cerr << " Please set the format_store as:" << std::endl;
400  std::cerr << " format::COO: COOrdinate format" << std::endl;
401  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
402  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
403  std::abort();
404  }
405  }
406 }
407 
408 // Overloading << operator to output matrix in CSV format
409 template<typename ITYPE, typename VTYPE>
410 std::ostream& operator << (std::ostream &ofile, const sparse_matrix<ITYPE,VTYPE> &exist_mat) {
411 
412  // Check if file was opened successfully
413  if (!ofile) {
414  std::cerr << "MUI Error [matrix_io_info.h]: Error opening output files in overloaded << operator." << std::endl;
415  std::abort();
416  }
417 
418  for (ITYPE i = 0; i < exist_mat.get_rows(); ++i) {
419  for (ITYPE j = 0; j < exist_mat.get_cols(); ++j) {
420  if (j == (exist_mat.get_cols() - 1)) {
421  ofile << exist_mat.get_value(i,j);
422  } else {
423  ofile << exist_mat.get_value(i,j) << ",";
424  }
425  }
426  if (i != (exist_mat.get_rows() - 1)) {
427  ofile << std::endl;
428  }
429  }
430  return ofile;
431 }
432 
433 // Function to overloading >> operator to read matrix from a file in CSV format with lines start with "//" as comment lines
434 template<typename ITYPE, typename VTYPE>
435 std::istream& operator>>(std::istream &ifile, sparse_matrix<ITYPE,VTYPE> &exist_mat) {
436 
437  // Check if file was opened successfully
438  if (!ifile) {
439  std::cerr << "MUI Error [matrix_io_info.h]: Error opening output files in overloaded >> operator." << std::endl;
440  std::abort();
441  }
442 
443  assert((exist_mat.empty()) &&
444  "MUI Error [matrix_io_info.h]: Overloading >> operator can only takes in null matrix or empty (all-zero) matrix");
445 
446  std::string format_store = exist_mat.get_format();
447 
448  std::string rawLine;
449 
450  std::vector<ITYPE> tempRowIndex;
451  std::vector<ITYPE> tempColIndex;
452  std::vector<VTYPE> tempValue;
453 
454  ITYPE row = 0;
455  ITYPE col = 0;
456  while (std::getline(ifile, rawLine)) {
457  std::string line = trim(rawLine);
458  // Skips the line if the first two characters are '//'
459  if (( line[0] == '/' && line[1] == '/' ) || (line.empty())) continue;
460  std::stringstream ss(line);
461  std::string value;
462  ITYPE colCount = 0;
463  while (std::getline(ss, value, ',')) {
464  VTYPE val = static_cast<VTYPE>(std::stod(value));
465  if (std::abs(val) >= std::numeric_limits<VTYPE>::min()) {
466  tempRowIndex.reserve(tempRowIndex.size()+1);
467  tempColIndex.reserve(tempColIndex.size()+1);
468  tempValue.reserve(tempValue.size()+1);
469  tempRowIndex.emplace_back(row);
470  tempColIndex.emplace_back(colCount);
471  tempValue.emplace_back(val);
472  }
473  ++colCount;
474  }
475  if (col == 0){
476  col = colCount;
477  } else {
478  if (col != colCount) {
479  std::cout << "MUI Warning [matrix_io_info.h]: The number of columns of the matrix read in at row " <<
480  row << " is " << colCount << ", which is different from previous row (i.e. " <<
481  col << " columns!" << std::endl;
482  col = colCount;
483  }
484  }
485  ++row;
486  }
487  if ((exist_mat.get_rows() == 0) && (exist_mat.get_cols() == 0)) {
488  sparse_matrix<ITYPE,VTYPE> temp_matrix(row, col, "COO", tempValue, tempRowIndex, tempColIndex);
489  exist_mat.resize(row, col);
490  exist_mat.format_conversion("COO", false, false);
491  exist_mat.copy(temp_matrix);
492  temp_matrix.set_zero();
493  } else {
494  assert(((exist_mat.get_rows() == row) && (exist_mat.get_cols() == col)) &&
495  "MUI Error [matrix_io_info.h]: Matrix size mismatching between existing matrix and read in matrix in overloading >> operator ");
496  sparse_matrix<ITYPE,VTYPE> temp_matrix(row, col, "COO", tempValue, tempRowIndex, tempColIndex);
497  exist_mat.format_conversion("COO", false, false);
498  exist_mat.copy(temp_matrix);
499  temp_matrix.set_zero();
500  }
501 
502  if (format_store != exist_mat.get_format()) {
503  if (format_store == "COO") {
504  exist_mat.format_conversion("COO", true, true, "overwrite");
505  } else if (format_store == "CSR") {
506  exist_mat.format_conversion("CSR", true, true, "overwrite");
507  } else if (format_store == "CSC") {
508  exist_mat.format_conversion("CSC", true, true, "overwrite");
509  } else {
510  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format: " << format_store << " for matrix operator >>" << std::endl;
511  std::cerr << " Please set the format_store as:" << std::endl;
512  std::cerr << " format::COO: COOrdinate format" << std::endl;
513  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
514  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
515  std::abort();
516  }
517  }
518  return ifile;
519 }
520 
521 // Member function to get the value at a given position
522 template<typename ITYPE, typename VTYPE>
523 VTYPE sparse_matrix<ITYPE,VTYPE>::get_value(ITYPE r, ITYPE c) const {
524  assert(((r < rows_) && (r >= 0) && (c < cols_) && (c >= 0)) &&
525  "MUI Error [matrix_io_info.h]: Matrix index out of range in get_value function");
526 
527  if (matrix_format_ == format::COO) {
528  for (ITYPE i = 0; i < static_cast<ITYPE>(matrix_coo.row_indices_.size()); ++i) {
529  if (matrix_coo.row_indices_[i] == r && matrix_coo.col_indices_[i] == c) {
530  return matrix_coo.values_[i];
531  }
532  }
533  // Return 0 if the element is not found
534  return static_cast<VTYPE>(0);
535  } else if (matrix_format_ == format::CSR) {
536  // Find the row range in the row_ptrs_ vector
537  ITYPE row_start = matrix_csr.row_ptrs_[r];
538  ITYPE row_end = matrix_csr.row_ptrs_[r + 1];
539 
540  // Search for the column index within the row range
541  auto it = std::lower_bound(matrix_csr.col_indices_.begin()+row_start, matrix_csr.col_indices_.begin()+row_end, c);
542 
543  // Check if the element exists in the CSR vector
544  if (it != matrix_csr.col_indices_.begin()+row_end && *it == c) {
545  ITYPE index = std::distance(matrix_csr.col_indices_.begin(), it);
546  return matrix_csr.values_[index];
547  }
548  // Return 0 if the element is not found
549  return static_cast<VTYPE>(0);
550  } else if (matrix_format_ == format::CSC) {
551  // Find the column range in the col_ptrs_ vector
552  ITYPE col_start = matrix_csc.col_ptrs_[c];
553  ITYPE col_end = matrix_csc.col_ptrs_[c + 1];
554 
555  // Search for the row index within the column range
556  auto it = std::lower_bound(matrix_csc.row_indices_.begin()+col_start, matrix_csc.row_indices_.begin()+col_end, r);
557 
558  // Check if the element exists in the CSC vector
559  if (it != matrix_csc.row_indices_.begin()+col_end && *it == r) {
560  ITYPE index = std::distance(matrix_csc.row_indices_.begin(), it);
561  return matrix_csc.values_[index];
562  }
563  // Return 0 if the element is not found
564  return static_cast<VTYPE>(0);
565  } else {
566 
567  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix get_value" << std::endl;
568  std::cerr << " Please set the matrix_format_ as:" << std::endl;
569  std::cerr << " format::COO: COOrdinate format" << std::endl;
570  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
571  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
572  std::abort();
573 
574  }
575 }
576 
577 // Member function to get the number of rows
578 template<typename ITYPE, typename VTYPE>
580  return rows_;
581 }
582 
583 // Member function to get the number of cols
584 template<typename ITYPE, typename VTYPE>
586  return cols_;
587 }
588 
589 // Member function to get non-zero elements
590 template<typename ITYPE, typename VTYPE>
591 std::vector<std::pair<ITYPE, ITYPE>> sparse_matrix<ITYPE,VTYPE>::get_non_zero_elements() const {
592  std::vector<std::pair<ITYPE, ITYPE>> vec_temp;
593  if (matrix_format_ == format::COO) {
594  vec_temp.reserve(matrix_coo.values_.size());
595  for (ITYPE i = 0; i < matrix_coo.values_.size(); ++i) {
596  vec_temp.emplace_back(std::make_pair(matrix_coo.row_indices_[i], matrix_coo.col_indices_[i]));
597  }
598  } else if (matrix_format_ == format::CSR) {
599  vec_temp.reserve(matrix_csr.values_.size());
600  for (ITYPE row = 0; row < matrix_csr.row_ptrs_.size()-1; ++row) {
601  ITYPE row_start = matrix_csr.row_ptrs_[row];
602  ITYPE row_end = matrix_csr.row_ptrs_[row + 1];
603 
604  // Iterate over the non-zero elements in the row
605  for (ITYPE i = row_start; i < row_end; ++i) {
606  ITYPE column = matrix_csr.col_indices_[i];
607  vec_temp.emplace_back(std::make_pair(row, column));
608  }
609  }
610  } else if (matrix_format_ == format::CSC) {
611  vec_temp.reserve(matrix_csc.values_.size());
612  for (ITYPE column = 0; column < matrix_csc.col_ptrs_.size()-1; ++column) {
613  ITYPE col_start = matrix_csc.col_ptrs_[column];
614  ITYPE col_end = matrix_csc.col_ptrs_[column + 1];
615 
616  // Iterate over the non-zero elements in the column
617  for (ITYPE i = col_start; i < col_end; ++i) {
618  ITYPE row = matrix_csc.row_indices_[i];
619  vec_temp.emplace_back(std::make_pair(row, column));
620  }
621  }
622  } else {
623  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix operator >>" << std::endl;
624  std::cerr << " Please set the matrix_format_ as:" << std::endl;
625  std::cerr << " format::COO: COOrdinate format" << std::endl;
626  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
627  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
628  std::abort();
629  }
630  return vec_temp;
631 }
632 
633 // Member function to get number of non-zero elements
634 template<typename ITYPE, typename VTYPE>
636  if (matrix_format_ == format::COO) {
637  if (nnz_ != static_cast<ITYPE>(matrix_coo.values_.size())) {
638  std::cerr << "MUI Error [matrix_io_info.h]: Mismatch matrix_coo.values_ size (" << matrix_coo.values_.size() << ") with number of non-zeros (" << nnz_ <<") in non_zero_elements_count()" << std::endl;
639  std::abort();
640  }
641  } else if (matrix_format_ == format::CSR) {
642  if (nnz_ != static_cast<ITYPE>(matrix_csr.values_.size())) {
643  std::cerr << "MUI Error [matrix_io_info.h]: Mismatch matrix_csr.values_ size (" << matrix_csr.values_.size() << ") with number of non-zeros (" << nnz_ <<") in non_zero_elements_count()" << std::endl;
644  std::abort();
645  }
646  } else if (matrix_format_ == format::CSC) {
647  if (nnz_ != static_cast<ITYPE>(matrix_csc.values_.size())) {
648  std::cerr << "MUI Error [matrix_io_info.h]: Mismatch matrix_csc.values_ size (" << matrix_csc.values_.size() << ") with number of non-zeros (" << nnz_ <<") in non_zero_elements_count()" << std::endl;
649  std::abort();
650  }
651  } else {
652  std::cerr << "MUI Error [matrix_io_info.h]: Unrecognised matrix format for matrix non_zero_elements_count()" << std::endl;
653  std::cerr << " Please set the matrix_format_ as:" << std::endl;
654  std::cerr << " format::COO: COOrdinate format" << std::endl;
655  std::cerr << " format::CSR (default): Compressed Sparse Row format" << std::endl;
656  std::cerr << " format::CSC: Compressed Sparse Column format" << std::endl;
657  std::abort();
658  }
659 
660  return nnz_;
661 }
662 
663 // Member function to check whether the matrix contains all zero elements
664 template<typename ITYPE, typename VTYPE>
666  if ((matrix_coo.values_.empty()) &&
667  (matrix_coo.row_indices_.empty()) &&
668  (matrix_coo.col_indices_.empty()) &&
669  (matrix_csr.values_.empty()) &&
670  (matrix_csr.col_indices_.empty()) &&
671  (matrix_csc.values_.empty()) &&
672  (matrix_csc.row_indices_.empty())) {
673  return true;
674  } else {
675  return false;
676  }
677 }
678 
679 // Member function to get the format of the matrix
680 template<typename ITYPE, typename VTYPE>
682 {
683  std::string matrix_format;
684 
685  if (matrix_format_ == format::COO) {
686  matrix_format = "COO";
687  } else if (matrix_format_ == format::CSR) {
688  matrix_format = "CSR";
689  } else if (matrix_format_ == format::CSC) {
690  matrix_format = "CSC";
691  } else {
692  std::cerr << "MUI Error [matrix_io_info.h]: unknown matrix format" << std::endl;
693  std::abort();
694  }
695 
696  return matrix_format;
697 }
698 
699 // Member function to check if the sparse matrix is sorted and deduplicated
700 template<typename ITYPE, typename VTYPE>
701 bool sparse_matrix<ITYPE,VTYPE>::is_sorted_unique(const std::string &file_name_input, const std::string &function_name_input) const {
702 
703  std::string file_name;
704  std::string function_name;
705 
706  if (file_name_input.empty()) {
707  file_name = "matrix_io_info.h";
708  } else {
709  file_name = file_name_input;
710  }
711 
712  if (function_name_input.empty()) {
713  function_name = "is_sorted_unique()";
714  } else {
715  function_name = function_name_input;
716  }
717 
718  if (matrix_format_ == format::COO) {
719  return this->is_coo_sorted_unique(file_name, function_name);
720  } else if (matrix_format_ == format::CSR) {
721  return this->is_csr_sorted_unique(file_name, function_name);
722  } else if (matrix_format_ == format::CSC) {
723  return this->is_csc_sorted_unique(file_name, function_name);
724  } else {
725  std::cerr << "MUI Error [matrix_io_info.h]: unknown matrix format" << std::endl;
726  std::abort();
727  }
728 }
729 
730 // **************************************************
731 // ********** Protected member functions ************
732 // **************************************************
733 
734 // Protected member function to check if the COO matrix is sorted and deduplicated
735 template<typename ITYPE, typename VTYPE>
736 bool sparse_matrix<ITYPE,VTYPE>::is_coo_sorted_unique(const std::string &file_name_input, const std::string &function_name_input) const {
737 
738  std::string file_name;
739  std::string function_name;
740 
741  if (file_name_input.empty()) {
742  file_name = "matrix_io_info.h";
743  } else {
744  file_name = file_name_input;
745  }
746 
747  if (function_name_input.empty()) {
748  function_name = "is_coo_sorted_unique()";
749  } else {
750  function_name = function_name_input;
751  }
752 
753  ITYPE numEntries = matrix_coo.values_.size();
754 
755  if (numEntries > 1) {
756  for (ITYPE i = 1; i < numEntries; ++i) {
757  // Compare the current entry with the previous one
758  if (matrix_coo.row_indices_[i] < matrix_coo.row_indices_[i - 1]) {
759  // Row index is not sorted
760  if (DEBUG) {
761  std::cout << "MUI [" << file_name << "]: The COO type matrix is not sorted (sorted row index check failed) in " << function_name << std::endl;
762  }
763  return false;
764  } else if (matrix_coo.row_indices_[i] == matrix_coo.row_indices_[i - 1]) {
765  // Row index is the same, check column index
766  if (matrix_coo.col_indices_[i] < matrix_coo.col_indices_[i - 1]) {
767  // Column index is not sorted
768  if (DEBUG) {
769  std::cout << "MUI [" << file_name << "]: The COO type matrix is not sorted (sorted column index check failed) in " << function_name << std::endl;
770  }
771  return false;
772  } else if (matrix_coo.col_indices_[i] == matrix_coo.col_indices_[i - 1]) {
773  // Column index has duplicate elements
774  if (DEBUG) {
775  std::cout << "MUI [" << file_name << "]: The COO type matrix exists duplicated elements (unique column index check failed) in " << function_name << std::endl;
776  }
777  return false;
778  }
779  }
780  }
781  }
782  return true;
783 }
784 
785 // Protected member function to check if the CSR matrix is sorted and deduplicated
786 template<typename ITYPE, typename VTYPE>
787 bool sparse_matrix<ITYPE,VTYPE>::is_csr_sorted_unique(const std::string &file_name_input, const std::string &function_name_input) const {
788 
789  std::string file_name;
790  std::string function_name;
791 
792  if (file_name_input.empty()) {
793  file_name = "matrix_io_info.h";
794  } else {
795  file_name = file_name_input;
796  }
797 
798  if (function_name_input.empty()) {
799  function_name = "is_csr_sorted_unique()";
800  } else {
801  function_name = function_name_input;
802  }
803 
804  ITYPE numEntries = matrix_csr.values_.size();
805 
806  if (numEntries > 1) {
807  for(ITYPE i = 0; i < rows_; ++i){
808  if (matrix_csr.row_ptrs_[i] > matrix_csr.row_ptrs_[i+1]) {
809  // Row pointers is not sorted
810  if (DEBUG) {
811  std::cout << "MUI [" << file_name << "]: The CSR type matrix is not sorted (sorted row pointers check failed) in " << function_name << std::endl;
812  }
813  return false;
814  }
815  for(ITYPE j = matrix_csr.row_ptrs_[i] + 1; j < matrix_csr.row_ptrs_[i+1]; ++j){
816  if(matrix_csr.col_indices_[j-1] > matrix_csr.col_indices_[j]){
817  // Column indices is not sorted
818  if (DEBUG) {
819  std::cout << "MUI [" << file_name << "]: The CSR type matrix is not sorted (sorted column index check failed) in " << function_name << std::endl;
820  }
821  return false;
822  } else if (matrix_csr.col_indices_[j-1] == matrix_csr.col_indices_[j]) {
823  // Column indices is not unique
824  if (DEBUG) {
825  std::cout << "MUI [" << file_name << "]: The CSR type matrix is not unique (deduplicated column index check failed) in " << function_name << std::endl;
826  }
827  return false;
828  }
829  }
830  }
831  }
832  return true;
833 }
834 
835 // Protected member function to check if the CSC matrix is sorted and deduplicated
836 template<typename ITYPE, typename VTYPE>
837 bool sparse_matrix<ITYPE,VTYPE>::is_csc_sorted_unique(const std::string &file_name_input, const std::string &function_name_input) const {
838 
839  std::string file_name;
840  std::string function_name;
841 
842  if (file_name_input.empty()) {
843  file_name = "matrix_io_info.h";
844  } else {
845  file_name = file_name_input;
846  }
847 
848  if (function_name_input.empty()) {
849  function_name = "is_csc_sorted_unique()";
850  } else {
851  function_name = function_name_input;
852  }
853 
854  ITYPE numEntries = matrix_csc.values_.size();
855 
856  if (numEntries > 1) {
857  for(ITYPE i = 0; i < cols_; ++i){
858  if (matrix_csc.col_ptrs_[i] > matrix_csc.col_ptrs_[i+1]) {
859  // Column pointers is not sorted
860  if (DEBUG) {
861  std::cout << "MUI [" << file_name << "]: The CSC type matrix is not sorted (sorted column pointers check failed) in " << function_name << std::endl;
862  }
863  return false;
864  }
865  for(ITYPE j = matrix_csc.col_ptrs_[i] + 1; j < matrix_csc.col_ptrs_[i+1]; ++j){
866  if(matrix_csc.row_indices_[j-1] > matrix_csc.row_indices_[j]){
867  // Row indices is not sorted
868  if (DEBUG) {
869  std::cout << "MUI [" << file_name << "]: The CSC type matrix is not sorted (sorted row index check failed) in " << function_name << std::endl;
870  }
871  return false;
872  } else if (matrix_csc.row_indices_[j-1] == matrix_csc.row_indices_[j]) {
873  // Row indices is not unique
874  if (DEBUG) {
875  std::cout << "MUI [" << file_name << "]: The CSC type matrix is not unique (deduplicated row index check failed) in " << function_name << std::endl;
876  }
877  return false;
878  }
879  }
880  }
881  }
882  return true;
883 }
884 
885 } // linalg
886 } // mui
887 
888 #endif /* MUI_MATRIX_IO_INFO_H_ */
Definition: matrix.h:61
ITYPE get_rows() const
Definition: matrix_io_info.h:579
bool is_sorted_unique(const std::string &={}, const std::string &={}) const
Definition: matrix_io_info.h:701
void print() const
Definition: matrix_io_info.h:66
bool is_csc_sorted_unique(const std::string &={}, const std::string &={}) const
Definition: matrix_io_info.h:837
void set_zero()
Definition: matrix_manipulation.h:418
ITYPE non_zero_elements_count() const
Definition: matrix_io_info.h:635
void print_vectors() const
Definition: matrix_io_info.h:78
bool is_csr_sorted_unique(const std::string &={}, const std::string &={}) const
Definition: matrix_io_info.h:787
bool is_coo_sorted_unique(const std::string &={}, const std::string &={}) const
Definition: matrix_io_info.h:736
VTYPE get_value(ITYPE, ITYPE) const
Definition: matrix_io_info.h:523
void write_vectors_to_file(const std::string &, const std::string &={}, const std::string &={}, const std::string &={}) const
Definition: matrix_io_info.h:154
std::string get_format() const
Definition: matrix_io_info.h:681
void read_vectors_from_file(const std::string &, const std::string &={}, const std::string &={}, const std::string &={})
Definition: matrix_io_info.h:252
void resize(ITYPE, ITYPE)
Definition: matrix_manipulation.h:62
ITYPE get_cols() const
Definition: matrix_io_info.h:585
void copy(const sparse_matrix< ITYPE, VTYPE > &)
Definition: matrix_manipulation.h:79
void format_conversion(const std::string &="COO", bool=true, bool=false, const std::string &="overwrite")
Definition: matrix_manipulation.h:639
bool empty() const
Definition: matrix_io_info.h:665
std::vector< std::pair< ITYPE, ITYPE > > get_non_zero_elements() const
Definition: matrix_io_info.h:591
u u u u u u min
Definition: dim.h:289
std::istream & operator>>(std::istream &ifile, sparse_matrix< ITYPE, VTYPE > &exist_mat)
Definition: matrix_io_info.h:435
std::ostream & operator<<(std::ostream &ofile, const sparse_matrix< ITYPE, VTYPE > &exist_mat)
Definition: matrix_io_info.h:410
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