UQTk: Uncertainty Quantification Toolkit  3.1.1
Array2D.h
Go to the documentation of this file.
1 /* =====================================================================================
2 
3  The UQ Toolkit (UQTk) version 3.1.1
4  Copyright (2021) NTESS
5  https://www.sandia.gov/UQToolkit/
6  https://github.com/sandialabs/UQTk
7 
8  Copyright 2021 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
9  Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government
10  retains certain rights in this software.
11 
12  This file is part of The UQ Toolkit (UQTk)
13 
14  UQTk is open source software: you can redistribute it and/or modify
15  it under the terms of BSD 3-Clause License
16 
17  UQTk is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  BSD 3 Clause License for more details.
21 
22  You should have received a copy of the BSD 3 Clause License
23  along with UQTk. If not, see https://choosealicense.com/licenses/bsd-3-clause/.
24 
25  Questions? Contact the UQTk Developers at <uqtk-developers@software.sandia.gov>
26  Sandia National Laboratories, Livermore, CA, USA
27 ===================================================================================== */
30 
31 
32 #ifndef ARRAY2D_H_SEEN
33 #define ARRAY2D_H_SEEN
34 
35 #include <stddef.h>
36 #include <cstdio>
37 #include <vector>
38 #include <iostream>
39 #include <fstream>
40 #include <iterator>
41 #include <algorithm>
42 #include <typeinfo>
43 #include "Array1D.h"
44 
45 using namespace std;
46 
57 // COLUMN MAJOR FORMAT
58 
59 template<typename T>
60 class Array2D{
61 private:
62 
63 public:
64  // These two quantities used to be private but making them public
65  // allows for easy access to python interface as a "list"
66  int xsize_;
67  int ysize_;
68  vector<T> data_;
71 
73  Array2D(): xsize_(0), ysize_(0) {};
74 
76  Array2D(const int& nx, const int& ny): xsize_(nx), ysize_(ny){
77  data_.resize(xsize_*ysize_);
78  }
79 
81  Array2D(const int& nx, const int& ny, const T& t): xsize_(nx), ysize_(ny){
82  data_.resize(xsize_*ysize_ , t);
83  }
84 
86  Array2D(const Array2D &obj): xsize_(obj.xsize_), ysize_(obj.ysize_), data_(obj.data_) {};
87 
89  ~Array2D() {data_.clear();}
90 
92  void Clear() {
93  xsize_ = 0;
94  ysize_ = 0;
95  data_.clear();
96  }
97 
99  int XSize() const {return xsize_;}
101  int YSize() const {return ysize_;}
102 
105  void Resize(const int& nx, const int& ny) {
106  xsize_ = nx;
107  ysize_ = ny;
108  data_.resize(xsize_*ysize_);
109  }
110 
113  void Resize(const int& nx, const int& ny, const T& t) {
114  data_.clear();
115  xsize_ = nx;
116  ysize_ = ny;
117  data_.resize(xsize_*ysize_, t);
118  }
119 
121  void SetValue(const T& t){
122  for(int i=0; i < data_.size(); i++){
123  data_[i] = t;
124  }
125  }
126 
131  return &(data_[0]);
132  }
133 
137  const T* GetConstArrayPointer() const {
138  return &(data_[0]);
139  }
140 
142  // values accessed in a row-major format
143  T& operator()(int ix,int iy) {return data_[ix + xsize_*iy];}
144  const T& operator()(int ix,int iy) const {return data_[ix + xsize_*iy];}
145 
147  void insertRow(Array1D<T>& insarr,int ix){
148  if (ix<0 || ix>xsize_)
149  throw Tantrum("Array2D:insertRow():: insert index out of bounds.");
150  if ( insarr.Length() != ysize_ )
151  throw Tantrum("Array2D:insertRow():: insert row size does not match.");
152 
153  vector<T> data_old;
154  data_old=data_;
155 
156  xsize_ += 1; // new number of rows
157  data_.resize(xsize_*ysize_);
158 
159  for(int iy=0;iy<ysize_;iy++){
160  for(int i=0; i < ix; i++)
161  data_[i+xsize_*iy] = data_old[i+(xsize_-1)*iy];
162  data_[ix+xsize_*iy]=insarr(iy);
163  for(int i=ix+1; i < xsize_; i++)
164  data_[i+xsize_*iy] = data_old[i-1+(xsize_-1)*iy];
165  }
166  }
167 
169  void insertRow(Array2D<T>& insarr,int ix){
170  if (ix<0 || ix>xsize_)
171  throw Tantrum("Array2D:insertRow():: insert index out of bounds.");
172  if ( insarr.YSize() != ysize_ )
173  throw Tantrum("Array2D:insertRow():: insert row size does not match.");
174 
175  vector<T> data_old;
176  data_old=data_;
177 
178  int insx=insarr.XSize();
179 
180  xsize_ += insx;
181  data_.resize(xsize_*ysize_);
182 
183  for(int iy=0;iy<ysize_;iy++){
184  for(int i=0; i < ix; i++)
185  data_[i+xsize_*iy] = data_old[i+(xsize_-insx)*iy];
186  for(int i=ix; i < ix+insx; i++)
187  data_[i+xsize_*iy]=insarr(i-ix,iy);
188  for(int i=ix+insx; i < xsize_; i++)
189  data_[i+xsize_*iy] = data_old[i-insx+(xsize_-insx)*iy];
190  }
191  }
192 
194  void eraseRow(int ix){
195  if (ix<0 || ix>=xsize_)
196  throw Tantrum("Array2D:eraseRow():: erase index out of bounds.");
197 
198  vector<T> data_old;
199  data_old=data_;
200 
201  xsize_-=1;
202  data_.resize(xsize_*ysize_);
203 
204  for(int iy=0;iy<ysize_;iy++){
205  for(int i=0; i < ix; i++)
206  data_[i+xsize_*iy] = data_old[i+(xsize_+1)*iy];
207  for(int i=ix; i < xsize_; i++)
208  data_[i+xsize_*iy] = data_old[i+1+(xsize_+1)*iy];
209  }
210 
211  //if (xsize_==0)
212  // printf("eraseRow(): WARNING: the xsize is zeroed!");
213 
214  }
215 
216  // /// \brief Insert array insarr as a column into position iy
217  void insertCol(Array1D<T>& insarr,int iy){
218  if (iy<0 || iy>ysize_)
219  throw Tantrum("Array2D:insertCol():: insert index out of bounds.");
220  if ( insarr.Length() != xsize_ )
221  throw Tantrum("Array2D:insertCol():: insert column size does not match.");
222 
223 
224  T* ptr=insarr.GetArrayPointer();
225  data_.insert(data_.begin()+xsize_*iy,ptr,ptr+xsize_);
226 
227  ysize_+=1;
228 
229  }
230 
232  void insertCol(Array2D<T>& insarr,int iy){
233  if (iy<0 || iy>ysize_)
234  throw Tantrum("Array2D:insertCol():: insert index out of bounds.");
235  if ( insarr.XSize() != xsize_ )
236  throw Tantrum("Array2D:insertRow():: insert column size does not match.");
237 
238  int insy=insarr.YSize();
239 
240  T* ptr=insarr.GetArrayPointer();
241  data_.insert(data_.begin()+xsize_*iy,ptr,ptr+xsize_*insy);
242 
243  ysize_+=insy;
244  }
245 
247  void eraseCol(int iy){
248  if (iy<0 || iy>=ysize_)
249  throw Tantrum("Array2D:eraseCol():: erase index out of bounds.");
250 
251  data_.erase(data_.begin()+xsize_*iy,data_.begin()+xsize_*(iy+1));
252 
253  ysize_-=1;
254 
255  //if (ysize_==0)
256  // printf("eraseCol(): WARNING: the ysize is zeroed!");
257 
258  }
259 
261  void DumpBinary(FILE* f_out) const {
262  fwrite(&xsize_,sizeof(xsize_),1,f_out);
263  fwrite(&ysize_,sizeof(ysize_),1,f_out);
264  fwrite(this->GetConstArrayPointer(),sizeof(T),xsize_*ysize_,f_out);
265  }
266 
267 
269  void ReadBinary(FILE* f_in){
270  fread(&xsize_,sizeof(xsize_),1,f_in);
271  fread(&ysize_,sizeof(ysize_),1,f_in);
272  data_.resize(xsize_*ysize_);
273  fread(this->GetArrayPointer(),sizeof(T),xsize_*ysize_,f_in);
274  }
275 
276  /********************************************************
277  // Methods for interfacing with python
278  ********************************************************/
279 
280  // assignment operator []
281  // allows for calling Array2D using [i][j] notation
282  // make more efficient by setting two vectors equal
284  // get the ith row
285  int stride = xsize_;
286  rowvec.Resize(ysize_);
287  for (int iy = 0; iy < ysize_; iy++){
288  rowvec(iy) = data_[ix + stride*iy];
289  }
290  return rowvec;
291  }
292 
293  void getRow(int row){
294  arraycopy.Resize(ysize_,0);
295  int stride = xsize_;
296  for (int i = 0; i < ysize_; i++){
297  arraycopy[i] = data_[i*stride + row];
298  }
299  }
300 
301  // read binary file created with DumpBinary
302  // Cannot use numpy's from files
303  // only for use in c++
304  void DumpBinary(char *filename){
305  FILE *f_out;
306  f_out = fopen(filename,"wb");
307  fwrite(&xsize_,sizeof(xsize_),1,f_out);
308  fwrite(&ysize_,sizeof(ysize_),1,f_out);
309  fwrite(this->GetConstArrayPointer(),sizeof(T),xsize_*ysize_,f_out);
310  fclose(f_out);
311  }
312 
313  // Only for use if DumpBinary was used
314  // can only be read in c++
315  // can be opened with ReadBinary(FILE* file) above
316  void ReadBinary(char *filename){
317  FILE *f_in;
318  f_in = fopen(filename,"rb");
319  fread(&xsize_,sizeof(xsize_),1,f_in);
320  fread(&ysize_,sizeof(ysize_),1,f_in);
321  data_.resize(xsize_*ysize_);
322  fread(this->GetArrayPointer(),sizeof(T),xsize_*ysize_,f_in);
323  fclose(f_in);
324  }
325 
326  // creates binary file that can be read with numpy's fromfile
327  void DumpBinary4py(char *filename){
328  ofstream f_out;
329  f_out.open(filename, ios::out | ios::binary);
330  f_out.write((char*)this->GetArrayPointer(),sizeof(T[xsize_*ysize_])); // convert array pointer to char string
331  f_out.close();
332  }
333 
334  // can read in DumpBinary4py output, but needs size of vector
335  // fromfile can automatically detect size file, so, if need by, one can use numpy's fromfile to determine # of elements
336  void ReadBinary4py(char *filename, int n1, int n2){
337  xsize_ = n1;
338  ysize_ = n2;
339  ifstream f_in;
340  f_in.open(filename, ios::in | ios::binary);
341  f_in.read((char*)this->GetArrayPointer(),sizeof(T[xsize_*ysize_])); // convert array pointer to char string
342  f_in.close();
343  }
344 
345  // Set user-defined list to data_ vector
346  // This will work even for string type
347  void setArray(vector<T> inarray){
348  data_ = inarray;
349  // xsize_ = inarray.size();
350  }
351 
352  // Sets user-defined 2d numpy array to data_ vector
353  // This is not to be used for a string type
354  void setnpdblArray(double* inarray, int n1, int n2){
355  xsize_ = n1;
356  ysize_ = n2;
357  data_.assign(inarray,inarray+n1*n2);
358  }
359 
360  // get numpy double array from data_ vector
361  void getnpdblArray(double* outarray, int n1, int n2){
362  copy(data_.begin(), data_.end(), outarray);
363  }
364 
365  // Sets user-defined 2d numpy array to data_ vector
366  // This is not to be used for a string type
367  void setnpintArray(long* inarray, int n1, int n2){
368  xsize_ = n1;
369  ysize_ = n2;
370  data_.assign(inarray,inarray+n1*n2);
371  }
372 
373  // get numpy double array from data_ vector
374  void getnpintArray(long* outarray, int n1, int n2){
375  copy(data_.begin(), data_.end(), outarray);
376  }
377 
378  // Returns data_ vector as a list in python in row-major (?)
379  // Also acts as a print to see individual elements
380  vector<T> flatten(){
381  return data_;
382  }
383 
384  string type(){
385  const char* s = typeid(data_[0]).name();
386  if (string(s) == string("Ss") ){
387  return "string";
388  }
389  else if (strcmp(s,"i") == 0){
390  return "int";
391  }
392  else {
393  return "double";
394  }
395  }
396 };
397 
398 #endif /* ARRAY2D_H_SEEN */
1D Array class for any type T
Array1D< double > copy(Array1D< double > &in_array)
Returns a copy of 1D array.
Definition: arraytools.cpp:1604
Stores data of any type T in a 1D array.
Definition: Array1D.h:61
T * GetArrayPointer()
Return a pointer to the first element of the data in the vector so we can use it access the data in a...
Definition: Array1D.h:138
void Resize(const int &nx)
Resizes the array.
Definition: Array1D.h:109
int Length() const
Returns length (i.e. size in the x-direction)
Definition: Array1D.h:106
Stores data of any type T in a 2D array.
Definition: Array2D.h:60
Array1D< T > & operator[](int ix)
Definition: Array2D.h:283
void Resize(const int &nx, const int &ny)
Resizes the array.
Definition: Array2D.h:105
vector< T > flatten()
Definition: Array2D.h:380
Array2D(const int &nx, const int &ny)
Constructor that allocates the memory.
Definition: Array2D.h:76
void ReadBinary4py(char *filename, int n1, int n2)
Definition: Array2D.h:336
void getRow(int row)
Definition: Array2D.h:293
void insertRow(Array2D< T > &insarr, int ix)
Insert a 2d-array insarr into a row position ix.
Definition: Array2D.h:169
void eraseRow(int ix)
Erase the row ix.
Definition: Array2D.h:194
void setArray(vector< T > inarray)
Definition: Array2D.h:347
void setnpintArray(long *inarray, int n1, int n2)
Definition: Array2D.h:367
const T & operator()(int ix, int iy) const
Definition: Array2D.h:144
~Array2D()
Destructor that frees up the memory.
Definition: Array2D.h:89
void insertRow(Array1D< T > &insarr, int ix)
Insert array insarr as a row into position ix.
Definition: Array2D.h:147
Array2D(const Array2D &obj)
Copy constructor.
Definition: Array2D.h:86
int ysize_
Definition: Array2D.h:67
const T * GetConstArrayPointer() const
Return a cont point to the first element of the data in the vector so we can use it access the data i...
Definition: Array2D.h:137
void getnpdblArray(double *outarray, int n1, int n2)
Definition: Array2D.h:361
void setnpdblArray(double *inarray, int n1, int n2)
Definition: Array2D.h:354
void DumpBinary(char *filename)
Definition: Array2D.h:304
Array2D(const int &nx, const int &ny, const T &t)
Constructor that allocates and initializes the data to a constant t.
Definition: Array2D.h:81
Array2D()
Default constructor, which does not allocate any memory.
Definition: Array2D.h:73
void ReadBinary(FILE *f_in)
Read contents of the array from a file in binary format.
Definition: Array2D.h:269
int xsize_
Definition: Array2D.h:66
vector< T > data_
Definition: Array2D.h:68
void insertCol(Array1D< T > &insarr, int iy)
Definition: Array2D.h:217
T & operator()(int ix, int iy)
C-like () operator to access values in the 2D data array.
Definition: Array2D.h:143
int YSize() const
Returns size in the y-direction.
Definition: Array2D.h:101
Array1D< T > arraycopy
Definition: Array2D.h:69
void ReadBinary(char *filename)
Definition: Array2D.h:316
void insertCol(Array2D< T > &insarr, int iy)
Insert a 2d-array insarr into a column position iy.
Definition: Array2D.h:232
string type()
Definition: Array2D.h:384
Array1D< T > rowvec
Definition: Array2D.h:70
void DumpBinary(FILE *f_out) const
Dump contents of the array to a file in binary format.
Definition: Array2D.h:261
void eraseCol(int iy)
Erase the column iy.
Definition: Array2D.h:247
void SetValue(const T &t)
Set all values in the array to the given value.
Definition: Array2D.h:121
void Clear()
Function to clear the memory.
Definition: Array2D.h:92
void getnpintArray(long *outarray, int n1, int n2)
Definition: Array2D.h:374
void DumpBinary4py(char *filename)
Definition: Array2D.h:327
T * GetArrayPointer()
Return a pointer to the first element of the data in the vector so we can use it access the data in a...
Definition: Array2D.h:130
int XSize() const
Returns size in the x-direction.
Definition: Array2D.h:99
void Resize(const int &nx, const int &ny, const T &t)
Resizes the array and sets ALL entries to the specified value.
Definition: Array2D.h:113