37 #ifdef ENABLE_ARRAY_INDEX_CHECKING
38 #define Tensor4_check_enabled
46 static bool show_index_check_message;
49 std::string name_ =
"";
61 std::string name_ =
"";
72 Tensor4(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
74 allocate(num_i, num_j, num_k, num_l);
80 if (data_ !=
nullptr) {
90 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
93 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
94 memcpy(data_, rhs.data_, size_*
sizeof(T));
97 int num_i() {
return ni_; }
98 int num_j() {
return nj_; }
99 int num_k() {
return nk_; }
100 int num_l() {
return nl_; }
110 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
114 if (ni_ != rhs.ni_ || nj_ != rhs.nj_ || nk_ != rhs.nk_ || nl_ != rhs.nl_ <= 0) {
118 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
121 memcpy(data_, rhs.data_,
sizeof(T) * size_);
125 Tensor4& operator=(
const double value)
127 for (
int i = 0; i < size_; i++) {
133 void write(
const std::string& label,
bool memory=
true, T offset={})
const
136 char file_prefix[1000];
137 for (
auto c : label) {
142 file_prefix[n] =
'_';
155 file_prefix[n] =
'\0';
158 std::string file_name;
161 file_name = std::string(file_prefix) +
"_cm.bin";
162 std::cout <<
"[Tensor4::write] file_name: " << file_name << std::endl;
163 fp = fopen(file_name.c_str(),
"wb");
164 fwrite(&size_,
sizeof(
int), 1, fp);
165 fwrite(data_,
sizeof(
double), size_, fp);
169 friend std::ostream& operator << (std::ostream& out,
const Tensor4<T>& lhs)
171 for (
int i = 0; i < lhs.size_; i++) {
173 if (i != lhs.size_-1) {
184 void allocate(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
193 size_ = ni_ * nj_ * nk_ * nl_;
194 data_ =
new T [size_];
195 memset(data_, 0,
sizeof(T)*size_);
203 void check_index(
const int i,
const int j,
const int k,
const int l)
const
205 if (show_index_check_message) {
206 std::cout <<
"[Tensor4] **********************************" << std::endl;
207 std::cout <<
"[Tensor4] WARNING: Index checking is enabled " << std::endl;
208 std::cout <<
"[Tensor4] **********************************" << std::endl;
209 show_index_check_message =
false;
212 if (data_ ==
nullptr) {
213 throw std::runtime_error(name_+
"Accessing null data in Tensor4.");
215 if ((i < 0) || (i >= ni_) || (j < 0) || (j >= nj_) || (k < 0) || (k >= nk_) || (l < 0) || (l >= nl_)) {
216 auto i_str = std::to_string(ni_);
217 auto j_str = std::to_string(nj_);
218 auto k_str = std::to_string(nk_);
219 auto l_str = std::to_string(nl_);
220 auto dims = i_str +
" x " + j_str +
" x " + k_str +
" x " + l_str;
221 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
"," + std::to_string(l);
222 throw std::runtime_error(
"Index (i,j,k,l)=" + index_str +
" is out of bounds for " + dims +
" array.");
236 if (data_ !=
nullptr) {
256 void resize(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
258 if (data_ !=
nullptr) {
264 allocate(num_i, num_j, num_k, num_l);
271 const T& operator()(
const int i,
const int j,
const int k,
const int l)
const
273 #ifdef Tensor4_check_enabled
274 check_index(i, j, k , l);
276 return data_[i + j*ni_ + p1_*k + p2_*l ];
279 T& operator()(
const int i,
const int j,
const int k,
const int l)
281 #ifdef Tensor4_check_enabled
282 check_index(i, j, k , l);
284 return data_[i + j*ni_ + p1_*k + p2_*l ];
296 for (
int i = 0; i < size_; i++) {
297 result.data_[i] = value * data_[i];
304 if (rhs.data_ ==
nullptr) {
305 throw std::runtime_error(
"Null data for rhs Tensor4.");
307 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
308 for (
int i = 0; i < rhs.size_; i++) {
309 result.data_[i] = value * rhs.data_[i];
318 for (
int i = 0; i < size_; i++) {
319 data_[i] += rhs.data_[i];
328 for (
int i = 0; i < size_; i++) {
329 data_[i] -= rhs.data_[i];
338 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
339 for (
int i = 0; i < size_; i++) {
340 result.data_[i] = data_[i] + rhs.data_[i];
347 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
348 for (
int i = 0; i < size_; i++) {
349 result.data_[i] = data_[i] - rhs.data_[i];
The Tensor4 template class implements a simple interface to 4th order tensors.
Definition: Tensor4.h:45