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