37 #define Tensor4_check_enabled
45 std::string name_ =
"";
57 std::string name_ =
"";
68 Tensor4(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
70 allocate(num_i, num_j, num_k, num_l);
76 if (data_ !=
nullptr) {
86 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
89 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
90 memcpy(data_, rhs.data_, size_*
sizeof(T));
93 int num_i() {
return ni_; }
94 int num_j() {
return nj_; }
95 int num_k() {
return nk_; }
96 int num_l() {
return nl_; }
106 if (rhs.ni_ <= 0 || rhs.nj_ <= 0 || rhs.nk_ <= 0 || rhs.nl_ <= 0) {
110 if (ni_ != rhs.ni_ || nj_ != rhs.nj_ || nk_ != rhs.nk_ || nl_ != rhs.nl_ <= 0) {
114 allocate(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
117 memcpy(data_, rhs.data_,
sizeof(T) * size_);
121 Tensor4& operator=(
const double value)
123 for (
int i = 0; i < size_; i++) {
129 void write(
const std::string& label,
bool memory=
true, T offset={})
const
132 char file_prefix[1000];
133 for (
auto c : label) {
138 file_prefix[n] =
'_';
151 file_prefix[n] =
'\0';
154 std::string file_name;
157 file_name = std::string(file_prefix) +
"_cm.bin";
158 std::cout <<
"[Tensor4::write] file_name: " << file_name << std::endl;
159 fp = fopen(file_name.c_str(),
"wb");
160 fwrite(&size_,
sizeof(
int), 1, fp);
161 fwrite(data_,
sizeof(
double), size_, fp);
165 friend std::ostream& operator << (std::ostream& out,
const Tensor4<T>& lhs)
167 for (
int i = 0; i < lhs.size_; i++) {
169 if (i != lhs.size_-1) {
180 void allocate(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
189 size_ = ni_ * nj_ * nk_ * nl_;
190 data_ =
new T [size_];
191 memset(data_, 0,
sizeof(T)*size_);
199 void check_index(
const int i,
const int j,
const int k,
const int l)
const
201 if (data_ ==
nullptr) {
202 throw std::runtime_error(name_+
"Accessing null data in Tensor4.");
204 if ((i < 0) || (i >= ni_) || (j < 0) || (j >= nj_) || (k < 0) || (k >= nk_) || (l < 0) || (l >= nl_)) {
205 auto i_str = std::to_string(ni_);
206 auto j_str = std::to_string(nj_);
207 auto k_str = std::to_string(nk_);
208 auto l_str = std::to_string(nl_);
209 auto dims = i_str +
" x " + j_str +
" x " + k_str +
" x " + l_str;
210 auto index_str =
" " + std::to_string(i) +
"," + std::to_string(j) +
"," + std::to_string(k) +
"," + std::to_string(l);
211 throw std::runtime_error(
"Index (i,j,k,l)=" + index_str +
" is out of bounds for " + dims +
" array.");
225 if (data_ !=
nullptr) {
245 void resize(
const int num_i,
const int num_j,
const int num_k,
const int num_l)
247 if (data_ !=
nullptr) {
253 allocate(num_i, num_j, num_k, num_l);
260 const T& operator()(
const int i,
const int j,
const int k,
const int l)
const
262 #ifdef Tensor4_check_enabled
263 check_index(i, j, k , l);
265 return data_[i + j*ni_ + p1_*k + p2_*l ];
268 T& operator()(
const int i,
const int j,
const int k,
const int l)
270 #ifdef Tensor4_check_enabled
271 check_index(i, j, k , l);
273 return data_[i + j*ni_ + p1_*k + p2_*l ];
285 for (
int i = 0; i < size_; i++) {
286 result.data_[i] = value * data_[i];
293 if (rhs.data_ ==
nullptr) {
294 throw std::runtime_error(
"Null data for rhs Tensor4.");
296 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
297 for (
int i = 0; i < rhs.size_; i++) {
298 result.data_[i] = value * rhs.data_[i];
307 for (
int i = 0; i < size_; i++) {
308 data_[i] += rhs.data_[i];
317 for (
int i = 0; i < size_; i++) {
318 data_[i] -= rhs.data_[i];
327 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
328 for (
int i = 0; i < size_; i++) {
329 result.data_[i] = data_[i] + rhs.data_[i];
336 Tensor4<T> result(rhs.ni_, rhs.nj_, rhs.nk_, rhs.nl_);
337 for (
int i = 0; i < size_; i++) {
338 result.data_[i] = data_[i] - rhs.data_[i];
The Tensor4 template class implements a simple interface to 4th order tensors.
Definition: Tensor4.h:43