28 static int num_allocated;
30 static bool show_index_check_message;
31 static double memory_in_use;
32 static double memory_returned;
33 static bool write_enabled;
34 static void memory(
const std::string& prefix=
"");
35 static void stats(
const std::string& prefix=
"");
49 Array3(
const int num_rows,
const int num_cols,
const int num_slices,
bool row_major=
true)
54 nslices_ = num_slices;
56 if ((num_rows <= 0) || (num_cols <= 0) || (num_slices <= 0)) {
61 allocate(num_rows, num_cols, num_slices, row_major);
69 if ((rhs.nrows_ <= 0) || (rhs.ncols_ <= 0) || (rhs.nslices_ <= 0)) {
73 allocate(rhs.nrows_, rhs.ncols_, rhs.nslices_);
74 memcpy(data_, rhs.data_, size_*
sizeof(T));
81 if (data_ !=
nullptr) {
82 memory_in_use -=
sizeof(T) * size_;;
83 memory_returned +=
sizeof(T) * size_;;
90 int ncols()
const {
return ncols_; }
91 int nrows()
const {
return nrows_; }
92 int nslices()
const {
return nslices_; }
94 void allocate(
const int num_rows,
const int num_cols,
const int num_slices,
const bool row_major=
true)
98 nslices_ = num_slices;
99 slice_size_ = ncols_ * nrows_;
100 size_ = nrows_ * ncols_ * nslices_;
101 data_ =
new T [size_];
102 memset(data_, 0,
sizeof(T)*size_);
103 memory_in_use +=
sizeof(T) * size_;;
106 void check_index(
const int i,
const int j,
const int k)
const
108 if (show_index_check_message) {
109 std::cout <<
"[Array3] **********************************" << std::endl;
110 std::cout <<
"[Array3] WARNING: Index checking is enabled " << std::endl;
111 std::cout <<
"[Array3] **********************************" << std::endl;
112 show_index_check_message =
false;
115 if (data_ ==
nullptr) {
116 throw std::runtime_error(+
"Accessing null data in Array3.");
119 if ((i < 0) || (i >= nrows_) or (j < 0) || (j >= ncols_) or (k < 0) || (k >= nslices_)) {
120 auto i_str = std::to_string(nrows_);
121 auto j_str = std::to_string(ncols_);
122 auto k_str = std::to_string(nslices_);
123 auto dims = i_str +
" x " + j_str +
" x " + k_str;
124 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
" ";
125 throw std::runtime_error(
"Index (i,j,k)=" + index_str +
" is out of bounds for " + dims +
" array.");
129 friend std::ostream& operator << (std::ostream& out,
const Array3<T>& lhs)
131 if (lhs.data_ ==
nullptr) {
132 throw std::runtime_error(
"[Array3] Accessing null data in ostream.");
135 for (
int i = 0; i < lhs.size(); i++) {
137 if (i != lhs.size()-1) {
149 if (data_ !=
nullptr) {
151 memory_in_use -=
sizeof(T) * size_;;
152 memory_returned +=
sizeof(T) * size_;;
168 #ifdef Array3_check_enabled
169 check_index(0, 0,
slice);
172 Array<T> array_slice(nrows_, ncols_, &data_[
slice*slice_size_]);
177 T* slice_data(
const int slice) {
178 return &data_[
slice*slice_size_];
181 void print(
const std::string& label)
183 printf(
"%s (%d): \n", label.c_str(), size_);
184 for (
int i = 0; i < size_; i++) {
185 if (data_[i] != 0.0) {
186 printf(
"%s %d %g\n", label.c_str(), i+1, data_[i]);
194 #ifdef Array3_check_enabled
195 check_index(0, 0,
slice);
197 Array<T> array_slice(nrows_, ncols_);
199 for (
int col = 0; col < ncols_; col++) {
200 for (
int row = 0; row < nrows_; row++) {
201 array_slice(row, col) = data_[row + col*nrows_ +
slice*slice_size_];
208 void set_row(
const int col,
const int slice,
const std::vector<T>& values)
const
210 #ifdef Array3_check_enabled
211 check_index(0, col,
slice);
213 for (
int row = 0; row < values.size(); row++) {
214 data_[row + col*nrows_ +
slice*slice_size_] = values[row];
218 void set_slice(
const int slice,
const Array<T>& values)
const
220 #ifdef Array3_check_enabled
221 check_index(0, 0,
slice);
223 for (
int col = 0; col < ncols_; col++) {
224 for (
int row = 0; row < nrows_; row++) {
225 data_[row + col*nrows_ +
slice*slice_size_] = values(row,col);
240 if ((nrows_ > 0) || (ncols_ > 0) || nslices_ > 0) {
249 return size_ *
sizeof(T);
253 void resize(
const int num_rows,
const int num_cols,
const int num_slices)
258 nslices_ = num_slices;
260 if ((num_rows <= 0) || (num_cols <= 0) || (num_slices <= 0)) {
264 if (data_ !=
nullptr) {
266 memory_in_use -=
sizeof(T) * size_;;
267 memory_returned +=
sizeof(T) * size_;;
271 allocate(num_rows, num_cols, num_slices);
279 int rhs_size = rhs.size();
281 if (size_ != rhs_size) {
282 throw std::runtime_error(
"The RHS size " + std::to_string(rhs_size) +
" does not have the same size " +
283 std::to_string(size_) +
" of this array.");
286 auto rhs_data = rhs.data();
288 for (
int i = 0; i < size_; i++) {
289 data_[i] = rhs_data[i];
293 void read(
const std::string& file_name)
295 auto fp = fopen(file_name.c_str(),
"rb");
296 fread(&size_,
sizeof(
int), 1, fp);
297 fread(data_,
sizeof(
double), size_, fp);
301 void write(
const std::string& label,
bool memory=
true)
303 if (!write_enabled) {
307 auto file_prefix = build_file_prefix(label);
308 auto file_name = file_prefix +
"_cm.bin";
311 auto fp = fopen(file_name.c_str(),
"wb");
312 fwrite(&size_,
sizeof(
int), 1, fp);
313 fwrite(data_,
sizeof(
double), size_, fp);
317 void append(
const std::string& label,
bool memory=
true)
319 if (!write_enabled) {
323 auto file_prefix = build_file_prefix(label);
324 auto file_name = file_prefix +
"_cm.bin";
327 auto fp = fopen(file_name.c_str(),
"ab");
328 fwrite(data_,
sizeof(
double), size_, fp);
341 if ((rhs.nrows_ <= 0) || (rhs.ncols_ <= 0) || (rhs.nslices_ <= 0)) {
345 if (rhs.data_ ==
nullptr) {
346 throw std::runtime_error(+
"RHS has null data.");
353 if (size_ != rhs.size_) {
355 allocate(rhs.nrows_, rhs.ncols_, rhs.nslices_);
358 memcpy(data_, rhs.data_,
sizeof(T) * size_);
366 #ifdef Array3_check_enabled
367 check_index(row, col,
slice);
369 return data_[row + col*nrows_ +
slice*slice_size_];
375 #ifdef Array3_check_enabled
376 check_index(row, col,
slice);
378 return data_[row + col*nrows_ +
slice*slice_size_];
383 for (
int i = 0; i < size_; i++) {
396 Array3<T> result(nrows_, ncols_, nslices_);
397 for (
int i = 0; i < size_; i++) {
398 result.data_[i] = value * data_[i];
405 for (
int i = 0; i < size_; i++) {
413 if (rhs.data_ ==
nullptr) {
414 throw std::runtime_error(
"Null data for rhs Array3.");
416 Array3<T> result(rhs.nrows_, rhs.ncols_, rhs.nslices_);
417 for (
int i = 0; i < rhs.size_; i++) {
418 result.data_[i] = value * rhs.data_[i];
const T & operator()(const int row, const int col, const int slice) const
Get the array value at (row,col).
Definition Array3.h:364
T & operator()(const int row, const int col, const int slice)
Set the array value at (row,col).
Definition Array3.h:373