28 static int num_allocated;
30 static double memory_in_use;
31 static double memory_returned;
32 static bool write_enabled;
33 static void memory(
const std::string& prefix=
"");
34 static void stats(
const std::string& prefix=
"");
48 Array3(
const int num_rows,
const int num_cols,
const int num_slices,
bool row_major=
true)
53 nslices_ = num_slices;
55 if ((num_rows <= 0) || (num_cols <= 0) || (num_slices <= 0)) {
60 allocate(num_rows, num_cols, num_slices, row_major);
68 if ((rhs.nrows_ <= 0) || (rhs.ncols_ <= 0) || (rhs.nslices_ <= 0)) {
72 allocate(rhs.nrows_, rhs.ncols_, rhs.nslices_);
73 memcpy(data_, rhs.data_, size_*
sizeof(T));
80 if (data_ !=
nullptr) {
81 memory_in_use -=
sizeof(T) * size_;;
82 memory_returned +=
sizeof(T) * size_;;
89 int ncols()
const {
return ncols_; }
90 int nrows()
const {
return nrows_; }
91 int nslices()
const {
return nslices_; }
93 void allocate(
const int num_rows,
const int num_cols,
const int num_slices,
const bool row_major=
true)
97 nslices_ = num_slices;
98 slice_size_ = ncols_ * nrows_;
99 size_ = nrows_ * ncols_ * nslices_;
100 data_ =
new T [size_];
101 memset(data_, 0,
sizeof(T)*size_);
102 memory_in_use +=
sizeof(T) * size_;;
105 void check_index(
const int i,
const int j,
const int k)
const
107 if (data_ ==
nullptr) {
108 throw std::runtime_error(+
"Accessing null data in Array3.");
111 if ((i < 0) || (i >= nrows_) or (j < 0) || (j >= ncols_) or (k < 0) || (k >= nslices_)) {
112 auto i_str = std::to_string(nrows_);
113 auto j_str = std::to_string(ncols_);
114 auto k_str = std::to_string(nslices_);
115 auto dims = i_str +
" x " + j_str +
" x " + k_str;
116 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
" ";
117 throw std::runtime_error(
"Index (i,j,k)=" + index_str +
" is out of bounds for " + dims +
" array.");
121 friend std::ostream& operator << (std::ostream& out,
const Array3<T>& lhs)
123 if (lhs.data_ ==
nullptr) {
124 throw std::runtime_error(
"[Array3] Accessing null data in ostream.");
127 for (
int i = 0; i < lhs.size(); i++) {
129 if (i != lhs.size()-1) {
141 if (data_ !=
nullptr) {
143 memory_in_use -=
sizeof(T) * size_;;
144 memory_returned +=
sizeof(T) * size_;;
160 #ifdef Array3_check_enabled
161 check_index(0, 0,
slice);
164 Array<T> array_slice(nrows_, ncols_, &data_[
slice*slice_size_]);
169 T* slice_data(
const int slice) {
170 return &data_[
slice*slice_size_];
173 void print(
const std::string& label)
175 printf(
"%s (%d): \n", label.c_str(), size_);
176 for (
int i = 0; i < size_; i++) {
177 if (data_[i] != 0.0) {
178 printf(
"%s %d %g\n", label.c_str(), i+1, data_[i]);
186 #ifdef Array3_check_enabled
187 check_index(0, 0,
slice);
189 Array<T> array_slice(nrows_, ncols_);
191 for (
int col = 0; col < ncols_; col++) {
192 for (
int row = 0; row < nrows_; row++) {
193 array_slice(row, col) = data_[row + col*nrows_ +
slice*slice_size_];
200 void set_row(
const int col,
const int slice,
const std::vector<T>& values)
const
202 #ifdef Array3_check_enabled
203 check_index(0, col,
slice);
205 for (
int row = 0; row < values.size(); row++) {
206 data_[row + col*nrows_ +
slice*slice_size_] = values[row];
210 void set_slice(
const int slice,
const Array<T>& values)
const
212 #ifdef Array3_check_enabled
213 check_index(0, 0,
slice);
215 for (
int col = 0; col < ncols_; col++) {
216 for (
int row = 0; row < nrows_; row++) {
217 data_[row + col*nrows_ +
slice*slice_size_] = values(row,col);
232 if ((nrows_ > 0) || (ncols_ > 0) || nslices_ > 0) {
241 return size_ *
sizeof(T);
245 void resize(
const int num_rows,
const int num_cols,
const int num_slices)
250 nslices_ = num_slices;
252 if ((num_rows <= 0) || (num_cols <= 0) || (num_slices <= 0)) {
256 if (data_ !=
nullptr) {
258 memory_in_use -=
sizeof(T) * size_;;
259 memory_returned +=
sizeof(T) * size_;;
263 allocate(num_rows, num_cols, num_slices);
271 int rhs_size = rhs.size();
273 if (size_ != rhs_size) {
274 throw std::runtime_error(
"The RHS size " + std::to_string(rhs_size) +
" does not have the same size " +
275 std::to_string(size_) +
" of this array.");
278 auto rhs_data = rhs.data();
280 for (
int i = 0; i < size_; i++) {
281 data_[i] = rhs_data[i];
285 void read(
const std::string& file_name)
287 auto fp = fopen(file_name.c_str(),
"rb");
288 fread(&size_,
sizeof(
int), 1, fp);
289 fread(data_,
sizeof(
double), size_, fp);
293 void write(
const std::string& label,
bool memory=
true)
295 if (!write_enabled) {
299 auto file_prefix = build_file_prefix(label);
300 auto file_name = file_prefix +
"_cm.bin";
303 auto fp = fopen(file_name.c_str(),
"wb");
304 fwrite(&size_,
sizeof(
int), 1, fp);
305 fwrite(data_,
sizeof(
double), size_, fp);
309 void append(
const std::string& label,
bool memory=
true)
311 if (!write_enabled) {
315 auto file_prefix = build_file_prefix(label);
316 auto file_name = file_prefix +
"_cm.bin";
319 auto fp = fopen(file_name.c_str(),
"ab");
320 fwrite(data_,
sizeof(
double), size_, fp);
333 if ((rhs.nrows_ <= 0) || (rhs.ncols_ <= 0) || (rhs.nslices_ <= 0)) {
337 if (rhs.data_ ==
nullptr) {
338 throw std::runtime_error(+
"RHS has null data.");
345 if (size_ != rhs.size_) {
347 allocate(rhs.nrows_, rhs.ncols_, rhs.nslices_);
350 memcpy(data_, rhs.data_,
sizeof(T) * size_);
358 #ifdef Array3_check_enabled
359 check_index(row, col,
slice);
361 return data_[row + col*nrows_ +
slice*slice_size_];
367 #ifdef Array3_check_enabled
368 check_index(row, col,
slice);
370 return data_[row + col*nrows_ +
slice*slice_size_];
375 for (
int i = 0; i < size_; i++) {
388 Array3<T> result(nrows_, ncols_, nslices_);
389 for (
int i = 0; i < size_; i++) {
390 result.data_[i] = value * data_[i];
397 for (
int i = 0; i < size_; i++) {
405 if (rhs.data_ ==
nullptr) {
406 throw std::runtime_error(
"Null data for rhs Array3.");
408 Array3<T> result(rhs.nrows_, rhs.ncols_, rhs.nslices_);
409 for (
int i = 0; i < rhs.size_; i++) {
410 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:356
T & operator()(const int row, const int col, const int slice)
Set the array value at (row,col).
Definition Array3.h:365