roadrunner  2.6.0
Fast simulator for SBML models
Matrix3D.h
1 //
2 // Created by Ciaran on 08/07/2021.
3 //
4 
5 #ifndef ROADRUNNER_MATRIX3D_H
6 #define ROADRUNNER_MATRIX3D_H
7 
8 #include "Matrix.h"
9 
10 namespace rr {
11 
16  template<typename IndexType, typename DataType>
17  class Matrix3D {
18  using Matrix3DInitializer = std::initializer_list<std::initializer_list<std::initializer_list<DataType>>>;
19  public:
20 
24  Matrix3D() = default;
25 
29  Matrix3D(int numRows, int numCols, int numZ) :
30  index_(std::vector<IndexType>(numZ)),
31  data_(std::vector<Matrix < DataType>>(numZ)) {
32  for (int i = 0; i < numZ; i++) {
33  data_[i].resize(numRows, numCols);
34  }
35  }
36 
37  Matrix3D(std::initializer_list<IndexType> idx, Matrix3DInitializer data)
38  : index_(idx.begin(), idx.end()), data_(data.begin(), data.end()) {
39  if (index_.size() != data.size()) {
40  throw std::logic_error("The size of index != size of 3D data in Matrix3D initializer list. ");
41  }
42  }
43 
44  void insert(IndexType idx, Matrix <DataType> mat) {
45  // enforce unique indexes by override existing idx
46  auto it = std::find(index_.begin(), index_.end(), idx);
47  if (it != index_.end()) {
48  auto pos = std::distance(index_.begin(), it);
49  data_[pos] = mat;
50  return;
51  }
52  if (!index_.empty()) {
53  // All sizes are compared to index 0, so when initializing
54  // from empty, we do not check integrity of user input
55  // need to check that all Z have dimensions x and y
56  if (mat.numRows() != numRows()) {
57  std::ostringstream err;
58  err << "Cannot insert a matrix with " << mat.numRows();
59  err << " rows into a Matrix3D that has " << numRows() << "rows";
60  throw std::invalid_argument(err.str());
61  }
62  if (mat.numCols() != numCols()) {
63  std::ostringstream err;
64  err << "Cannot insert a matrix with " << mat.numCols();
65  err << " rows into a Matrix3D that has " << numCols() << "rows";
66  throw std::invalid_argument(err.str());
67  }
68  }
69  index_.push_back(idx);
70  data_.push_back(mat);
71  }
72 
73  void pushBack(IndexType idx, Matrix <DataType> mat) {
74  if (numRows() != mat.numRows() || numCols() != mat.numCols()) {
75  std::ostringstream err;
76  err << "Number of rows and columns in mat are invalid for this Matrix3D (";
77  err << numRows() << ", " << numCols() << ")" << std::endl;
78  throw std::invalid_argument(err.str());
79  }
80  index_.push_back(idx);
81  data_.push_back(mat);
82  }
83 
89  if (idx > numZ()) {
90  std::ostringstream err;
91  err << "requested idx " << idx << " from a Matrix3D with " << numZ() << " elements";
92  throw std::invalid_argument(err.str());
93  }
94  return data_[idx];
95  }
96 
106  if (k > numZ()) {
107  std::ostringstream err;
108  err << "requested kth index " << k << " from a Matrix3D with " << numZ()
109  << " elements in the depth direction";
110  throw std::invalid_argument(err.str());
111  }
112  return data_[k];
113  }
114 
120  rr::Matrix3D<DataType, IndexType> &colSliceByName(const std::vector<std::string> &rowNames) {
121 
122  }
123 
133  std::vector<DataType> slice(int k, int j) {
134  if (k > numZ()) {
135  std::ostringstream err;
136  err << "requested kth index " << k << " from a Matrix3D with " << numZ()
137  << " elements in the depth direction";
138  throw std::invalid_argument(err.str());
139  }
140  if (j > numRows()) {
141  std::ostringstream err;
142  err << "requested jth index " << j << " from a Matrix3D with " << numRows()
143  << " elements in the height (y) direction";
144  throw std::invalid_argument(err.str());
145  }
146  auto submatrix = data_[k].getValues();
147  return submatrix[j];
148  }
149 
159  DataType slice(int k, int j, int i) {
160  if (k > numZ()) {
161  std::ostringstream err;
162  err << "requested kth index " << k << " from a Matrix3D with " << numZ()
163  << " elements in the depth direction";
164  throw std::invalid_argument(err.str());
165  }
166  if (j > numRows()) {
167  std::ostringstream err;
168  err << "requested jth index " << j << " from a Matrix3D with " << numRows()
169  << " elements in the width (x) direction";
170  throw std::invalid_argument(err.str());
171  }
172  if (i > numCols()) {
173  std::ostringstream err;
174  err << "requested ith index " << i << " from a Matrix3D with " << numCols()
175  << " elements in the hight (y) direction";
176  throw std::invalid_argument(err.str());
177  }
178  std::vector<std::vector<DataType>> submatrix = data_[k].getValues();
179  // j indicates which row, i indicates which column
180  return submatrix[j][i];
181  }
182 
188  Matrix <DataType> &getItem(IndexType idx) {
189  // first check if idx in index
190  if (std::find(index_.begin(), index_.end(), idx) == index_.end()) {
191  std::ostringstream err;
192  err << "Index \"" << idx << "\" has been requested but is not present in this Matrix3D.";
193  throw std::invalid_argument(err.str());
194  }
195  // get index of idx
196  int pos = std::distance(index_.begin(), std::find(index_.begin(), index_.end(), idx));
197  return data_[pos];
198  }
199 
204  const std::vector<IndexType> &getIndex() const {
205  return index_;
206  }
207 
208  void setKthMatrix(int k, IndexType idx, Matrix <DataType> data) {
209  if (k > numZ()) {
210  throw std::invalid_argument("k is too big");
211  }
212  if (numRows() != data.numRows() || numCols() != data.numCols()) {
213  throw std::invalid_argument("wrong dimensions");
214  }
215  index_[k] = idx;
216  data_[k] = data;
217 
218  }
219 
224  int numRows() {
225  if (data_.empty())
226  return 0;
227  return data_[0].numRows();
228  }
229 
234  int numCols() {
235  if (data_.empty())
236  return 0;
237  return data_[0].numCols();
238  }
239 
244  int numZ() {
245  if (index_.empty())
246  return 0;
247  return index_.size();
248  }
249 
253  void setRowNames(const std::vector<std::string> &rowNames) {
254  rowNames_ = rowNames;
255  for (int i = 0; i < numZ(); i++) {
256  data_[i].setRowNames(rowNames);
257  }
258  }
259 
263  void setColNames(const std::vector<std::string> &colNames) {
264  colNames_ = colNames;
265  for (int i = 0; i < numZ(); i++) {
266  data_[i].setColNames(colNames);
267  }
268  }
269 
273  std::vector<std::string> getRowNames() {
274  return slice(0).rowNames;
275  }
276 
280  std::vector<std::string> getColNames() {
281  return slice(0).colNames;
282  }
283 
288  if (numRows() != other.numRows() || numCols() != other.numCols() || numZ() != other.numZ()) {
289  return false;
290  }
291  bool equal = true;
292  for (int i = 0; i < numZ(); i++) {
293  if (index_[i] != other.index_[i]) {
294  equal = false;
295  break;
296  }
297  if (data_[i] != other.data_[i]) {
298  equal = false;
299  break;
300  }
301  }
302  return equal;
303  }
304 
309  return !(*this == other);
310  }
311 
315  bool almostEquals(Matrix3D<double, double> &other, double tol) {
316  if (numRows() != other.numRows() || numCols() != other.numCols() || numZ() != other.numZ()) {
317  return false;
318  }
319  bool equal = true;
320  for (int i = 0; i < numZ(); i++) {
321  if ((index_[i] - other.index_[i]) > tol) {
322  equal = false;
323  break;
324  }
325  if (!data_[i].almostEquals(other.data_[i], tol)) {
326  equal = false;
327  break;
328  }
329  }
330  return equal;
331  }
332 
333  template<typename IndexType_, typename DataType_>
334  friend std::ostream &operator<<(std::ostream &os, Matrix3D<IndexType_, DataType_> &matrix3D);
335 
341  void deleteRow(const int& which){
342  // iterate over each submatrix
343  for (int k=0; k<numZ(); k++){
344  Matrix<DataType>& submatrix = data_[k];
345  submatrix.deleteRow(which);
346  }
347  }
348 
354  void deleteRow(const std::string& which){
355  // iterate over each submatrix
356  for (int k=0; k<numZ(); k++){
357  Matrix<DataType>& submatrix = data_[k];
358  submatrix.deleteRow(which);
359  }
360  }
361 
367  void deleteCol(const int& which){
368  // iterate over each submatrix
369  for (int k=0; k<numZ(); k++){
370  Matrix<DataType>& submatrix = data_[k];
371  submatrix.deleteCol(which);
372  }
373  }
374 
380  void deleteCol(const std::string& which){
381  // iterate over each submatrix
382  for (int k=0; k<numZ(); k++){
383  Matrix<DataType>& submatrix = data_[k];
384  submatrix.deleteCol(which);
385  }
386  }
387 
388  private:
389  std::vector<IndexType> index_;
390  std::vector<Matrix < DataType>> data_;
391  std::vector<std::string> rowNames_{};
392  std::vector<std::string> colNames_{};
393  };
394 
395  template<typename IndexType_, typename DataType_>
396  std::ostream &operator<<(std::ostream &os, Matrix3D<IndexType_, DataType_> &matrix3D) {
397  for (int i = 0; i < matrix3D.numZ(); i++) {
398  os << "\t\t" << matrix3D.index_[i] << std::endl;
399  os << matrix3D[i] << std::endl;
400  }
401  return os;
402  }
403 
404 }
405 
406 #endif //ROADRUNNER_MATRIX3D_H
A basic local 3D version of the Matrix class, based on initializer_list.
Definition: Matrix3D.h:17
int numCols()
get number of columns in this 3D matrix
Definition: Matrix3D.h:234
rr::Matrix< DataType > & slice(int k)
1D Matrix slicer.
Definition: Matrix3D.h:105
rr::Matrix3D< DataType, IndexType > & colSliceByName(const std::vector< std::string > &rowNames)
slice a Matrix3D by colnames.
Definition: Matrix3D.h:120
DataType slice(int k, int j, int i)
3D Matrix slicer.
Definition: Matrix3D.h:159
std::vector< DataType > slice(int k, int j)
2D Matrix slicer.
Definition: Matrix3D.h:133
const std::vector< IndexType > & getIndex() const
getter for the index data field of the Matrix3D.
Definition: Matrix3D.h:204
void deleteCol(const std::string &which)
delete the col indexed by
Definition: Matrix3D.h:380
std::vector< std::string > getColNames()
return the column names for this Matrix3D
Definition: Matrix3D.h:280
void setColNames(const std::vector< std::string > &colNames)
set col names for each of the z matrices
Definition: Matrix3D.h:263
int numRows()
get number of rows in this 3D matrix
Definition: Matrix3D.h:224
Matrix3D()=default
default construct a 3D matrix
bool operator!=(Matrix3D< IndexType, DataType > &other)
inequality operator
Definition: Matrix3D.h:308
std::vector< std::string > getRowNames()
return the row names for this Matrix3D
Definition: Matrix3D.h:273
int numZ()
get number of matrices in this 3D matrix
Definition: Matrix3D.h:244
bool almostEquals(Matrix3D< double, double > &other, double tol)
equality operator for double IndexType and DataType types only
Definition: Matrix3D.h:315
bool operator==(Matrix3D< IndexType, DataType > &other)
equality operator
Definition: Matrix3D.h:287
Matrix3D(int numRows, int numCols, int numZ)
construct an empty 3D matrix with numRows x numCols x numZ dimensions.
Definition: Matrix3D.h:29
void setRowNames(const std::vector< std::string > &rowNames)
set row names for each of the z matrices
Definition: Matrix3D.h:253
Matrix< DataType > & operator[](int idx)
Indexer to slice a Matrix3D and index value and data at idx.
Definition: Matrix3D.h:88
void deleteRow(const std::string &which)
delete the row indexed by
Definition: Matrix3D.h:354
void deleteCol(const int &which)
delete the col indexed by
Definition: Matrix3D.h:367
Matrix< DataType > & getItem(IndexType idx)
slicing operator that uses the user provided index.
Definition: Matrix3D.h:188
void deleteRow(const int &which)
delete the row indexed by
Definition: Matrix3D.h:341
A basic local matrix class, based on the libstruct version.
Definition: Matrix.h:18
void deleteCol(int which)
delete col
Definition: Matrix.h:364
void deleteRow(int which)
delete row
Definition: Matrix.h:314