50 explicit Tensor(
const size_t&);
52 explicit Tensor(
const size_t&,
const size_t&);
54 explicit Tensor(
const size_t&,
const size_t&,
const size_t&);
56 explicit Tensor(
const size_t&,
const size_t&,
const size_t&,
const size_t&);
68 inline bool operator == (
const T&);
69 inline bool operator == (
const Tensor<T>&);
71 inline bool operator >= (
const T&);
72 inline bool operator <= (
const T&);
74 inline T& operator()(
const size_t&);
75 inline T& operator()(
const size_t&,
const size_t&);
76 inline T& operator()(
const size_t&,
const size_t&,
const size_t&);
77 inline T& operator()(
const size_t&,
const size_t&,
const size_t&,
const size_t&);
79 inline const T& operator()(
const size_t&)
const;
80 inline const T& operator()(
const size_t&,
const size_t&)
const;
81 inline const T& operator()(
const size_t&,
const size_t&,
const size_t&)
const;
82 inline const T& operator()(
const size_t&,
const size_t&,
const size_t&,
const size_t&)
const;
98 size_t get_dimensions_number()
const;
99 size_t get_dimension(
const size_t&)
const;
101 size_t get_element(
const size_t&,
const size_t&)
const;
106 Vector<T> get_column(
const size_t&)
const;
109 Tensor<T> get_tensor(
const size_t&)
const;
110 Matrix<T> get_matrix(
const size_t&)
const;
111 Matrix<T> get_matrix(
const size_t&,
const size_t&)
const;
113 void embed(
const size_t&,
const size_t&,
const Matrix<T>&);
115 void embed(
const size_t&,
const size_t&,
const Tensor<T>&);
129 void set(
const size_t&);
130 void set(
const size_t&,
const size_t&);
134 void set_row(
const size_t&,
const Vector<T>&);
135 void set_matrix(
const size_t&,
const size_t&,
const Matrix<T>&);
136 void set_matrix(
const size_t&,
const Matrix<T>&);
137 void set_tensor(
const size_t&,
const Tensor<T>&);
139 void embed(
const size_t&,
const Vector<T>&);
141 void initialize(
const T&);
142 void initialize_sequential();
144 void randomize_uniform(
const T&,
const T&);
145 void randomize_normal(
const double & = 0.0,
const double & = 1.0);
147 T calculate_sum()
const;
176 dimensions = new_dimensions;
188 dimensions = new_dimensions;
209 Tensor<T>::Tensor(
const size_t& dimension_1,
const size_t& dimension_2) : vector<T>(dimension_1*dimension_2)
222 Tensor<T>::Tensor(
const size_t& dimension_1,
const size_t& dimension_2,
const size_t& dimension_3) : vector<T>(dimension_1*dimension_2*dimension_3)
224 dimensions =
Vector<size_t>({dimension_1, dimension_2, dimension_3});
236 Tensor<T>::Tensor(
const size_t& dimension_1,
const size_t& dimension_2,
const size_t& dimension_3,
const size_t& dimension_4) : vector<T>(dimension_1*dimension_2*dimension_3*dimension_4)
238 dimensions =
Vector<size_t>({dimension_1, dimension_2, dimension_3, dimension_4});
251 for(
size_t i = 0; i < matrix.size(); i++)
253 (*this)[i] = matrix[i];
271 ostream& operator << (ostream& os,
const Tensor<T>& tensor)
275 os <<
"Dimensions number: " << dimensions_number << endl;
277 os <<
"Values: " << endl;
279 if(dimensions_number == 1)
283 for(
size_t i = 0; i < size; i ++)
285 os << tensor[i] <<
" ";
290 else if(dimensions_number == 2)
295 for(
size_t i = 0; i < rows_number; i ++)
297 for(
size_t j = 0; j < columns_number; j++)
299 os << tensor(i,j) <<
" ";
305 else if(dimensions_number == 3)
311 for(
size_t k = 0; k < rank; k ++)
313 os <<
"submatrix_" << k <<
"\n";
315 for(
size_t i = 0; i < rows_number; i ++)
317 for(
size_t j = 0; j < columns_number; j++)
319 os << tensor(i,j,k) <<
"\t";
326 else if(dimensions_number > 3)
333 for(
size_t l = 0; l < rank_1; l++)
335 for(
size_t k = 0; k < rank_2; k ++)
337 os <<
"submatrix_" << l <<
"_" << k <<
"\n";
339 for(
size_t i = 0; i < rows_number; i ++)
341 for(
size_t j = 0; j < columns_number; j++)
343 os << tensor(i,j,k,l) <<
"\t";
362 if(other_tensor.dimensions != this->dimensions)
364 set(other_tensor.dimensions);
367 copy(other_tensor.begin(), other_tensor.end(), this->begin());
379 const size_t size = this->size();
381 for(
size_t i = 0; i < size; i++)
382 if((*
this)[i] != other[i])
return false;
394 const size_t size = this->size();
396 for(
size_t i = 0; i < size; i++)
397 if((*
this)[i] != value)
return false;
409 const size_t size = this->size();
411 for(
size_t i = 0; i < size; i++)
412 if((*
this)[i] < value)
return false;
424 const size_t size = this->size();
426 for(
size_t i = 0; i < size; i++)
427 if((*
this)[i] > value)
return false;
436 #ifdef __OPENNN_DEBUG__
438 const size_t dimensions_number = get_dimensions_number();
440 if(dimensions_number != 2)
442 ostringstream buffer;
444 buffer <<
"OpenNN Exception: Tensor template.\n"
445 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
446 <<
"Number of dimensions (" << dimensions_number <<
") must be 2.\n";
448 throw logic_error(buffer.str());
451 if(row >= dimensions[0])
453 ostringstream buffer;
455 buffer <<
"OpenNN Exception: Tensor template.\n"
456 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
457 <<
"Row index (" << row <<
") must be less than rows number (" << dimensions[0] <<
").\n";
459 throw logic_error(buffer.str());
462 if(column >= dimensions[1])
464 ostringstream buffer;
466 buffer <<
"OpenNN Exception: Tensor template.\n"
467 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
468 <<
"Column index (" << column <<
") must be less than columns number (" << dimensions[1] <<
").\n";
470 throw logic_error(buffer.str());
475 return (*
this)[dimensions[0]*column + row];
480 inline const T& Tensor<T>::operator()(
const size_t& index_0 ,
const size_t& index_1,
const size_t& index_2)
const
482 #ifdef __OPENNN_DEBUG__
484 const size_t dimensions_number = get_dimensions_number();
486 if(dimensions_number != 3)
488 ostringstream buffer;
490 buffer <<
"OpenNN Exception: Tensor template.\n"
491 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&, const size_t&) const.\n"
492 <<
"Number of dimensions (" << dimensions_number <<
") must be 3.\n";
494 throw logic_error(buffer.str());
499 return (*
this)[index_2 * dimensions[0] * dimensions[1] + index_1 * dimensions[0] + index_0];
504 inline const T& Tensor<T>::operator()(
const size_t& index_0 ,
const size_t& index_1,
const size_t& index_2,
const size_t& index_3)
const
506 #ifdef __OPENNN_DEBUG__
508 const size_t dimensions_number = get_dimensions_number();
510 if(dimensions_number != 4)
512 ostringstream buffer;
514 buffer <<
"OpenNN Exception: Tensor template.\n"
515 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&, const size_t&, const size_t&) const.\n"
516 <<
"Number of dimensions (" << dimensions_number <<
") must be 4.\n";
518 throw logic_error(buffer.str());
523 return (*
this)[index_3 * dimensions[0] * dimensions[1] * dimensions[2] + index_2 *dimensions[0] * dimensions[1] + index_1 * dimensions[0] + index_0];
528 T& Tensor<T>::operator()(
const size_t& row,
const size_t& column)
530 #ifdef __OPENNN_DEBUG__
532 const size_t dimensions_number = get_dimensions_number();
534 if(dimensions_number != 2)
536 ostringstream buffer;
538 buffer <<
"OpenNN Exception: Tensor template.\n"
539 <<
"T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
540 <<
"Number of dimensions (" << dimensions_number <<
") must be 2.\n";
542 throw logic_error(buffer.str());
545 if(row >= dimensions[0])
547 ostringstream buffer;
549 buffer <<
"OpenNN Exception: Tensor template.\n"
550 <<
"T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
551 <<
"Row index (" << row <<
") must be less than rows number (" << dimensions[0] <<
").\n";
553 throw logic_error(buffer.str());
556 if(column >= dimensions[1])
558 ostringstream buffer;
560 buffer <<
"OpenNN Exception: Tensor template.\n"
561 <<
"T& Tensor<T>::operator()(const size_t&, const size_t&) const.\n"
562 <<
"Column index (" << column <<
") must be less than columns number (" << dimensions[1] <<
").\n";
564 throw logic_error(buffer.str());
569 return (*
this)[dimensions[0]*column+row];
574 T& Tensor<T>::operator()(
const size_t& index_0 ,
const size_t& index_1,
const size_t& index_2)
576 #ifdef __OPENNN_DEBUG__
578 const size_t dimensions_number = get_dimensions_number();
580 if(dimensions_number != 3)
582 ostringstream buffer;
584 buffer <<
"OpenNN Exception: Tensor template.\n"
585 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&, const size_t&) const.\n"
586 <<
"Number of dimensions (" << dimensions_number <<
") must be 3.\n";
588 throw logic_error(buffer.str());
593 return (*
this)[index_2 * (dimensions[0] * dimensions[1]) + index_1 * dimensions[0] + index_0];
598 T& Tensor<T>::operator()(
const size_t& index_0 ,
const size_t& index_1,
const size_t& index_2,
const size_t& index_3)
600 #ifdef __OPENNN_DEBUG__
602 const size_t dimensions_number = get_dimensions_number();
604 if(dimensions_number != 4)
606 ostringstream buffer;
608 buffer <<
"OpenNN Exception: Tensor template.\n"
609 <<
"const T& Tensor<T>::operator()(const size_t&, const size_t&, const size_t&, const size_t&) const.\n"
610 <<
"Number of dimensions (" << dimensions_number <<
") must be 4.\n";
612 throw logic_error(buffer.str());
617 return (*
this)[index_3 * dimensions[0] * dimensions[1] * dimensions[2] + index_2 *dimensions[0] * dimensions[1] + index_1 * dimensions[0] + index_0];
629 for(
size_t i = 0; i < this->size(); i++)
631 output[i] = (*this)[i] + value;
646 for(
size_t i = 0; i < other.size(); i++)
648 output[i] = (*this)[i] + other[i];
663 for(
size_t i = 0; i < this->size(); i++)
665 output[i] = (*this)[i] - value;
680 for(
size_t i = 0; i < other.size(); i++)
682 output[i] = (*this)[i]-other[i];
697 for(
size_t i = 0; i < this->size(); i++)
699 output[i] = (*this)[i] * value;
714 for(
size_t i = 0; i < other.size(); i++)
716 output[i] = (*this)[i]*other[i];
731 for(
size_t i = 0; i < this->size(); i++)
733 output[i] = (*this)[i] / value;
748 for(
size_t i = 0; i < other.size(); i++)
750 output[i] = (*this)[i]/other[i];
763 for(
size_t i = 0; i < this->size(); i++)
765 (*this)[i] *= other[i];
786 return dimensions[index_dimension];
795 return dimensions.size();
807 return (*
this)[dimensions[0]*column+row];
820 for(
size_t j = 0; j < dimensions[1]; j++)
822 row[j] = (*this)(i,j);
838 for(
size_t i = 0; i < dimensions[0]; i++)
840 column[i] = (*this)(i,j);
854 for(
size_t j = 0; j < dimensions[1]; j++)
856 header[j] = (*this)(0,j);
870 for(
size_t i = 0; i < dimensions[1]; i++)
871 for(
size_t j = 0; j < dimensions[2]; j++)
872 for(
size_t k = 0; k < dimensions[3]; k++)
873 tensor(i,j,k) = (*this)(index_0,i,j,k);
885 const size_t dimensions_number = get_dimensions_number();
887 if(dimensions_number == 2)
889 const size_t rows_number = dimensions[0];
890 const size_t columns_number = dimensions[1];
891 const size_t elements_number = rows_number * columns_number;
893 Matrix<T> matrix(rows_number, columns_number);
895 for(
size_t i = 0; i < elements_number; i++)
897 matrix[i] = (*this)[i];
902 else if(dimensions_number > 2)
905 if(matrix_index > dimensions[2])
910 const size_t rows_number = dimensions[0];
911 const size_t columns_number = dimensions[1];
913 const size_t elements_number = rows_number * columns_number;
915 Matrix<T> matrix(rows_number, columns_number);
917 for(
size_t i = 0; i < elements_number; i ++)
918 matrix[i] = (*
this)[matrix_index * elements_number + i];
936 const size_t dimension_2 = dimensions[2];
937 const size_t dimension_3 = dimensions[3];
939 Matrix<T> matrix(dimension_2, dimension_3);
941 for(
size_t i = 0; i < dimension_2; i++)
943 for(
size_t j = 0; j < dimension_3; j++)
945 matrix(i,j) = (*this)(index_0, index_1, i, j);
956 const size_t order = 2;
966 this->insert(this->end(), a_matrix.begin(), a_matrix.end());
968 dimensions = Vector<size_t>({ dimensions[0], dimensions[1], 2} );
975 this->insert(this->end(), a_matrix.begin(), a_matrix.end());
979 cout << *
this << endl;
1004 dimensions.
set({size});
1023 dimensions = new_dimensions;
1036 dimensions = new_dimensions;
1040 this->initialize(value);
1047 if(other_tensor.dimensions != this->dimensions)
1049 set(other_tensor.dimensions);
1052 copy(other_tensor.begin(), other_tensor.end(), this->begin());
1063 const size_t size = new_row.size();
1065 for(
size_t i = 0; i < size; i++)
1067 (*this)(row_index, i) = new_row[i];
1084 #ifdef __OPENNN_DEBUG__
1087 if(row_position + other_rows_number > this->get_dimensions()[0])
1089 ostringstream buffer;
1091 buffer <<
"OpenNN Exception: Tensor Template.\n"
1092 <<
"void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1093 <<
"Cannot tuck in matrix.\n";
1095 throw logic_error(buffer.str());
1099 if(row_position + other_rows_number > this->get_dimensions()[0])
1101 ostringstream buffer;
1103 buffer <<
"OpenNN Exception: Tensor Template.\n"
1104 <<
"void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1105 <<
"Cannot tuck in matrix.\n";
1107 throw logic_error(buffer.str());
1112 for(
size_t i = 0; i < other_rows_number; i++)
1114 for(
size_t j = 0; j < other_columns_number; j++)
1116 (*this)(row_position+i,column_position+j) = other_matrix(i,j);
1131 const size_t other_rows_number = other_tensor.get_rows_number();
1132 const size_t other_columns_number = other_tensor.get_columns_number();
1134 #ifdef __OPENNN_DEBUG__
1137 if(row_position + other_rows_number > this->get_dimensions()[1])
1139 ostringstream buffer;
1141 buffer <<
"OpenNN Exception: Tensor Template.\n"
1142 <<
"void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1143 <<
"Cannot tuck in matrix.\n";
1145 throw logic_error(buffer.str());
1149 if(row_position + other_rows_number > this->get_dimensions()[1])
1151 ostringstream buffer;
1153 buffer <<
"OpenNN Exception: Tensor Template.\n"
1154 <<
"void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1155 <<
"Cannot tuck in matrix.\n";
1157 throw logic_error(buffer.str());
1162 for(
size_t i = 0; i < other_rows_number; i++)
1164 for(
size_t j = 0; j < other_columns_number; j++)
1166 (*this)(row_position+i,column_position+j) = other_tensor(i,j);
1177 return Vector<T>(this->begin(),this->end());
1186 const size_t dimensions_number = get_dimensions_number();
1188 #ifdef __OPENNN_DEBUG__
1190 if(dimensions_number != 2)
1192 ostringstream buffer;
1194 buffer <<
"OpenNN Exception: Tensor Template.\n"
1195 <<
"Matrix<T> to_matrix() const method.\n"
1196 <<
"Dimension of tensor ("<< dimensions_number <<
") must be 2.\n";
1198 throw logic_error(buffer.str());
1203 Matrix<T> matrix(dimensions[0], dimensions[1]);
1205 for(
size_t i = 0; i < this->size(); i++)
1206 matrix[i] = (*
this)[i];
1219 const size_t size = this->size();
1221 if(get_dimensions_number() == 1)
1224 for(
size_t s = 0; s < size; s++)
1226 tensor(0, s) = (*this)[s];
1229 else if(get_dimensions_number() == 2)
1233 else if(get_dimensions_number() == 3)
1236 for(
size_t s = 0; s < size; s++)
1238 tensor(0, s) = (*this)(s%get_dimension(0), s/get_dimension(0), s/(get_dimension(0)*get_dimension(1)));
1241 else if(get_dimensions_number() == 4)
1243 tensor.
set(
Vector<size_t>({get_dimension(0), get_dimension(1) * get_dimension(2)* get_dimension(3)}));
1244 for(
size_t s = 0; s < get_dimension(1) * get_dimension(2) * get_dimension(3); s++)
1246 for(
size_t n = 0; n < get_dimension(0); n++)
1248 tensor(n, s) = (*this)(n, s%get_dimension(1), (s/get_dimension(1))%get_dimension(2), s/(get_dimension(1) * get_dimension(2)));
1252 else if (get_dimensions_number() > 4)
1254 ostringstream buffer;
1256 buffer <<
"OpenNN Exception: Tensor template.\n"
1257 <<
"void Tensor<T>::set_new_dimensions(const Vector<size_t>&) method.\n"
1258 <<
"The number of dimensions of tensor (" << get_dimensions_number() <<
") must not be greater than four.\n";
1260 throw logic_error(buffer.str());
1275 #ifdef __OPENNN_DEBUG__
1277 const size_t dimensions_number = get_dimensions_number();
1279 if(dimensions_number != 4)
1281 ostringstream buffer;
1283 buffer <<
"OpenNN Exception: Tensor Template.\n"
1284 <<
"Matrix<T> set_matrix(const size_t&, const size_t&, const Matrix<double>&) const method.\n"
1285 <<
"Number of dimension of tensor must be 4.\n";
1287 throw logic_error(buffer.str());
1292 const size_t rows_number = dimensions[2];
1293 const size_t columns_number = dimensions[3];
1295 for(
size_t i = 0; i < rows_number; i++)
1297 for(
size_t j = 0; j < columns_number; j++)
1299 (*this)(index_0, index_1, i, j) = matrix(i,j);
1313 const size_t rows_number = dimensions[0];
1314 const size_t columns_number = dimensions[1];
1316 for(
size_t i = 0; i < rows_number; i++)
1318 for(
size_t j = 0; j < columns_number; j++)
1320 (*this)(i, j, index_0) = matrix(i,j);
1333 for(
size_t i = 0; i < dimensions[1]; i++)
1334 for(
size_t j = 0; j < dimensions[2]; j++)
1335 for(
size_t k = 0; k < dimensions[3]; k++)
1336 (*
this)(index_0,i,j,k) = tensor(i,j,k);
1348 const size_t dimension_0 = dimensions[0];
1350 const size_t vector_size = vector.size();
1352 for(
size_t i = 0; i < vector_size; i++)
1354 (*this)[index+i*dimension_0] = vector[i];
1365 fill(this->begin(),this->end(), value);
1373 for(
size_t i = 0; i < this->size(); i++) {
1374 (*this)[i] = static_cast<T>(i);
1387 #ifdef __OPENNN_DEBUG__
1389 if(minimum > maximum) {
1390 ostringstream buffer;
1392 buffer <<
"OpenNN Exception: Tensor Template.\n"
1393 <<
"void randomize_uniform(const double&, const double&) method.\n"
1394 <<
"Minimum value must be less or equal than maximum value.\n";
1396 throw logic_error(buffer.str());
1401 const size_t this_size = this->size();
1403 for(
size_t i = 0; i < this_size; i++)
1405 (*this)[i] = calculate_random_uniform(minimum, maximum);
1418 const double &standard_deviation)
1420 #ifdef __OPENNN_DEBUG__
1422 if(standard_deviation < 0.0) {
1423 ostringstream buffer;
1425 buffer <<
"OpenNN Exception: Tensor Template.\n"
1426 <<
"void randomize_normal(const double&, const double&) method.\n"
1427 <<
"Standard deviation must be equal or greater than zero.\n";
1429 throw logic_error(buffer.str());
1434 const size_t this_size = this->size();
1436 for(
size_t i = 0; i < this_size; i++) {
1437 (*this)[i] = calculate_random_normal(mean, standard_deviation);
1449 for(
size_t i = 0; i < this->size(); i++)