40 #ifndef __VMML__TENSOR3__HPP__
41 #define __VMML__TENSOR3__HPP__
44 #include <vmmlib/tensor3_iterator.hpp>
45 #include <vmmlib/enable_if.hpp>
46 #include <vmmlib/blas_dot.hpp>
49 #ifdef VMMLIB_USE_OPENMP
61 template<
size_t I1,
size_t I2,
size_t I3,
typename T =
float >
69 typedef typename matrix< I1, I2, T>::iterator matrix_iterator;
94 static const size_t ROWS = I1;
95 static const size_t COLS = I2;
96 static const size_t SLICES = I3;
97 static const size_t MATRIX_SIZE = I1 * I2;
98 static const size_t SIZE = MATRIX_SIZE * I3;
101 static size_t get_array_size_in_bytes();
105 void clear_array_pointer();
108 inline T& operator()(
size_t i1,
size_t i2,
size_t i3);
109 inline const T& operator()(
size_t i1,
size_t i2,
size_t i3)
const;
111 inline T& at(
size_t i1,
size_t i2,
size_t i3);
112 inline const T& at(
size_t i1,
size_t i2,
size_t i3)
const;
131 explicit tensor3(
void* memory);
135 template<
typename U >
138 template<
size_t J1,
size_t J2,
size_t J3>
145 template<
size_t J1,
size_t J2,
size_t J3 >
147 get_sub_tensor3(
size_t row_offset,
size_t col_offset,
size_t slice_offset = 0,
148 typename enable_if< J1 <= I1 && J2 <= I2 && J3 <= I3 >::type* = 0)
const;
150 template<
size_t J1,
size_t J2,
size_t J3 >
153 size_t row_offset = 0,
size_t col_offset = 0,
size_t slice_offset = 0)
const;
155 template<
size_t J1,
size_t J2,
size_t J3 >
158 size_t row_offset = 0,
size_t col_offset = 0,
size_t slice_offset = 0);
160 void get_sub_tensor3(
char* data_,
161 const size_t i1_start,
const size_t i1_end,
162 const size_t i2_start,
const size_t i2_end,
163 const size_t i3_start,
const size_t i3_end )
const;
165 void set_sub_tensor3(
const char* data_,
166 const size_t i1_start,
const size_t i1_end,
167 const size_t i2_start,
const size_t i2_end,
168 const size_t i3_start,
const size_t i3_end );
170 inline void get_I1_vector(
size_t i2,
size_t i3,
vector< I1, T >& data)
const;
171 inline void get_I2_vector(
size_t i1,
size_t i3,
vector< I2, T >& data)
const;
172 inline void get_I3_vector(
size_t i1,
size_t i2,
vector< I3, T >& data)
const;
174 inline void get_row(
size_t i1,
size_t i3,
vector< I2, T >& data)
const;
175 inline void get_column(
size_t i2,
size_t i3,
vector< I1, T >& data)
const;
176 inline void get_tube(
size_t i1,
size_t i2,
vector< I3, T >& data)
const;
178 inline void set_I1_vector(
size_t i2,
size_t i3,
const vector< I1, T >& data);
179 inline void set_I2_vector(
size_t i1,
size_t i3,
const vector< I2, T >& data);
180 inline void set_I3_vector(
size_t i1,
size_t i2,
const vector< I3, T >& data);
182 inline void set_row(
size_t i1,
size_t i3,
const vector< I2, T >& data);
183 inline void set_column(
size_t i2,
size_t i3,
const vector< I1, T >& data);
184 inline void set_tube(
size_t i1,
size_t i2,
const vector< I3, T >& data);
188 inline void get_horizontal_slice_fwd(
size_t i1,
horiz_slice_type& data)
const;
191 inline void get_lateral_slice_fwd(
size_t i2,
lat_slice_type& data)
const;
196 inline void set_horizontal_slice_fwd(
size_t i1,
const horiz_slice_type& data);
199 inline void set_lateral_slice_fwd(
size_t i2,
const lat_slice_type& data);
206 void operator=(T fill_value);
207 void fill(T fill_value);
213 void fill_random(
int seed = -1);
214 void fill_random_signed(
int seed = -1);
215 void fill_increasing_values();
216 void fill_rand_sym_slices(
int seed = -1);
217 void fill_rand_sym(
int seed = -1);
219 const tensor3& operator=(
const tensor3& source_);
222 typename enable_if< R == I1 && R == I2 && R == I3 >::type*
227 template<
size_t K1,
size_t K2,
size_t K3 >
233 template<
typename input_iterator_t >
234 void set(input_iterator_t begin_, input_iterator_t end_,
235 bool row_major_layout =
true);
240 T get_abs_min()
const;
241 T get_abs_max()
const;
245 size_t nnz(
const T& threshold_)
const;
246 void threshold(
const T& threshold_value_);
249 template<
typename TT >
251 template<
typename TT >
252 void quantize_to(
tensor3< I1, I2, I3, TT >& quantized_,
tensor3< I1, I2, I3, char >& signs_, T& min_value_, T& max_value_,
const TT& tt_range_)
const;
253 template<
typename TT >
255 template<
typename TT >
256 void quantize_log(
tensor3< I1, I2, I3, TT >& quantized_,
tensor3< I1, I2, I3, char >& signs_, T& min_value_, T& max_value_,
const TT& tt_range_)
const;
257 template<
typename TT >
259 template<
typename TT >
261 template<
typename TT >
264 bool operator==(
const tensor3& other)
const;
265 bool operator!=(
const tensor3& other)
const;
269 bool equals(
const tensor3& other, T tolerance)
const;
272 template<
typename compare_t >
273 bool equals(
const tensor3& other, compare_t& cmp)
const;
279 template<
typename float_t>
308 template<
size_t R,
typename TT >
309 double tensor_inner_product(
316 double frobenius_norm()
const;
318 double avg_frobenius_norm()
const;
322 void mean(T& mean_)
const;
324 double variance()
const;
325 double stdev()
const;
327 template<
typename TT >
330 template<
size_t J1,
size_t J2,
size_t J3,
typename TT >
334 template<
typename TT >
345 inline tensor3 operator+(T scalar)
const;
346 inline tensor3 operator-(T scalar)
const;
348 void operator+=(T scalar);
349 void operator-=(T scalar);
351 inline tensor3 operator+(
const tensor3& other)
const;
352 inline tensor3 operator-(
const tensor3& other)
const;
354 template<
size_t J1,
size_t J2,
size_t J3>
358 void operator+=(
const tensor3& other);
359 void operator-=(
const tensor3& other);
364 tensor3 operator*(T scalar);
365 void operator*=(T scalar);
367 tensor3 operator/(T scalar);
368 void operator/=(T scalar);
384 friend std::ostream& operator <<(std::ostream& os, const tensor3< I1, I2, I3, T >& t3) {
385 for (
size_t i = 0; i < I3; ++i) {
387 os << t3.get_frontal_slice_fwd(i) <<
" *** " << std::endl;
394 static void tensor3_allocate_data(T*& array_);
395 static void tensor3_deallocate_data(T*& array_);
400 const T* get_array_ptr()
const;
403 inline size_t compute_index(
size_t i1,
size_t i2,
size_t i3)
const;
413 #define VMML_TEMPLATE_STRING template< size_t I1, size_t I2, size_t I3, typename T >
414 #define VMML_TEMPLATE_CLASSNAME tensor3< I1, I2, I3, T >
420 VMML_TEMPLATE_CLASSNAME::tensor3(
void* memory)
421 : _array(reinterpret_cast<T*> (memory)) {
426 VMML_TEMPLATE_CLASSNAME::tensor3()
428 tensor3_allocate_data(_array);
432 VMML_TEMPLATE_CLASSNAME::tensor3(
const tensor3& source_)
434 tensor3_allocate_data(_array);
439 template<
typename U >
440 VMML_TEMPLATE_CLASSNAME::tensor3(
const tensor3< I1, I2, I3, U >& source_) {
441 const U* s_array = source_.get_array_ptr();
442 tensor3_allocate_data(_array);
443 for (
size_t index = 0; index < I1 * I2 * I3; ++index) {
444 _array[ index ] =
static_cast<T
> (s_array[ index ]);
449 template<
size_t J1,
size_t J2,
size_t J3 >
450 VMML_TEMPLATE_CLASSNAME::tensor3(
const tensor3< J1, J2, J3, T >& source_) {
451 const size_t minL = J1 < I1 ? J1 : I1;
452 const size_t minC = J2 < I2 ? J2 : I2;
453 const size_t minS = J3 < I3 ? J3 : I3;
457 for (
size_t i = 0; i < minL; i++) {
458 for (
size_t j = 0; j < minC; j++) {
459 for (
size_t k = 0; k < minS; k++) {
460 at(i, j, k) = source_(i, j, k);
467 VMML_TEMPLATE_CLASSNAME::~tensor3() {
468 tensor3_deallocate_data(_array);
473 VMML_TEMPLATE_CLASSNAME::at(
size_t i1,
size_t i2,
size_t i3) {
474 #ifdef VMMLIB_SAFE_ACCESSORS
475 if (i1 >= I1 || i2 >= I2 || i3 >= I3)
476 VMMLIB_ERROR(
"at( i1, i2, i3 ) - index out of bounds", VMMLIB_HERE);
479 return _array[ i3 * MATRIX_SIZE + i2 * ROWS + i1 ];
485 VMML_TEMPLATE_CLASSNAME::at(
size_t i1,
size_t i2,
size_t i3)
const {
486 #ifdef VMMLIB_SAFE_ACCESSORS
487 if (i1 >= I1 || i2 >= I2 || i3 >= I3)
488 VMMLIB_ERROR(
"at( i1, i2, i3 ) - i3 index out of bounds", VMMLIB_HERE);
490 return _array[ i3 * MATRIX_SIZE + i2 * ROWS + i1 ];
496 VMML_TEMPLATE_CLASSNAME::operator()(
size_t i1,
size_t i2,
size_t i3) {
497 return at(i1, i2, i3);
502 VMML_TEMPLATE_CLASSNAME::operator()(
size_t i1,
size_t i2,
size_t i3)
const {
503 return at(i1, i2, i3);
508 VMML_TEMPLATE_CLASSNAME::
509 get_I2_vector(
size_t i1,
size_t i3, vector< I2, T >& data)
const {
510 #ifdef VMMLIB_SAFE_ACCESSORS
513 VMMLIB_ERROR(
"get_I1_vector() - i3 index out of bounds.", VMMLIB_HERE);
516 _get_slice(i3).get_row(i1, data);
521 VMML_TEMPLATE_CLASSNAME::
522 get_I1_vector(
size_t i2,
size_t i3, vector< I1, T >& data)
const {
523 #ifdef VMMLIB_SAFE_ACCESSORS
526 VMMLIB_ERROR(
"get_I2_vector() - i3 index out of bounds.", VMMLIB_HERE);
530 _get_slice(i3).get_column(i2, data);
536 VMML_TEMPLATE_CLASSNAME::
537 get_I3_vector(
size_t i1,
size_t i2, vector< I3, T >& data)
const {
538 for (
size_t i3 = 0; i3 < I3; ++i3) {
539 data[ i3 ] = _get_slice(i3).at(i1, i2);
546 VMML_TEMPLATE_CLASSNAME::
547 get_row(
size_t i1,
size_t i3, vector< I2, T >& data)
const {
548 get_I2_vector(i1, i3, data);
553 VMML_TEMPLATE_CLASSNAME::
554 get_column(
size_t i2,
size_t i3, vector< I1, T >& data)
const {
555 get_I1_vector(i2, i3, data);
560 VMML_TEMPLATE_CLASSNAME::
561 get_tube(
size_t i1,
size_t i2, vector< I3, T >& data)
const {
562 get_I3_vector(i1, i2, data);
567 VMML_TEMPLATE_CLASSNAME::
568 set_I2_vector(
size_t i1,
size_t i3,
const vector< I2, T >& data) {
569 #ifdef VMMLIB_SAFE_ACCESSORS
572 VMMLIB_ERROR(
"set_I1_vector() - i3 index out of bounds.", VMMLIB_HERE);
576 _get_slice(i3).set_row(i1, data);
581 VMML_TEMPLATE_CLASSNAME::
582 set_I1_vector(
size_t i2,
size_t i3,
const vector< I1, T >& data) {
583 #ifdef VMMLIB_SAFE_ACCESSORS
586 VMMLIB_ERROR(
"set_I2_vector() - i3 index out of bounds.", VMMLIB_HERE);
590 _get_slice(i3).set_column(i2, data);
596 VMML_TEMPLATE_CLASSNAME::
597 set_I3_vector(
size_t i1,
size_t i2,
const vector< I3, T >& data) {
598 for (
size_t i3 = 0; i3 < I3; ++i3) {
599 _get_slice(i3).at(i1, i2) = data[ i3 ];
606 VMML_TEMPLATE_CLASSNAME::
607 set_row(
size_t i1,
size_t i3,
const vector< I2, T >& data) {
608 set_I2_vector(i1, i3, data);
613 VMML_TEMPLATE_CLASSNAME::
614 set_column(
size_t i2,
size_t i3,
const vector< I1, T >& data) {
615 set_I1_vector(i2, i3, data);
620 VMML_TEMPLATE_CLASSNAME::
621 set_tube(
size_t i1,
size_t i2,
const vector< I3, T >& data) {
622 set_I3_vector(i1, i2, data);
626 inline typename VMML_TEMPLATE_CLASSNAME::front_slice_type&
627 VMML_TEMPLATE_CLASSNAME::
628 get_frontal_slice_fwd(
size_t i3) {
629 #ifdef VMMLIB_SAFE_ACCESSORS
631 VMMLIB_ERROR(
"get_frontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
633 return _get_slice(i3);
637 inline const typename VMML_TEMPLATE_CLASSNAME::front_slice_type&
638 VMML_TEMPLATE_CLASSNAME::
639 get_frontal_slice_fwd(
size_t i3)
const {
640 #ifdef VMMLIB_SAFE_ACCESSORS
642 VMMLIB_ERROR(
"get_frontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
644 return _get_slice(i3);
649 VMML_TEMPLATE_CLASSNAME::
650 get_frontal_slice_fwd(
size_t i3, front_slice_type& data)
const {
651 #ifdef VMMLIB_SAFE_ACCESSORS
653 VMMLIB_ERROR(
"get_frontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
656 data = _get_slice(i3);
662 VMML_TEMPLATE_CLASSNAME::
663 get_lateral_slice_bwd(
size_t i2, bwd_lat_slice_type& data)
const {
664 #ifdef VMMLIB_SAFE_ACCESSORS
666 VMMLIB_ERROR(
"get_lateral_slice_bwd() - index out of bounds.", VMMLIB_HERE);
669 for (
size_t i3 = 0; i3 < I3; ++i3) {
670 data.set_column(i3, _get_slice(i3).get_column(i2));
676 VMML_TEMPLATE_CLASSNAME::
677 get_horizontal_slice_fwd(
size_t i1, horiz_slice_type& data)
const {
678 #ifdef VMMLIB_SAFE_ACCESSORS
680 VMMLIB_ERROR(
"get_horizontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
682 for (
size_t i3 = 0; i3 < I3; ++i3) {
683 data.set_column(i3, _get_slice(i3).get_row(i1));
689 VMML_TEMPLATE_CLASSNAME::
690 get_frontal_slice_bwd(
size_t i3, bwd_front_slice_type& data)
const {
691 #ifdef VMMLIB_SAFE_ACCESSORS
693 VMMLIB_ERROR(
"get_frontal_slice_bwd() - index out of bounds.", VMMLIB_HERE);
696 front_slice_type* data_t =
new front_slice_type();
697 *data_t = _get_slice(i3);
698 data_t->transpose_to(data);
704 VMML_TEMPLATE_CLASSNAME::
705 get_lateral_slice_fwd(
size_t i2, lat_slice_type& data)
const {
706 #ifdef VMMLIB_SAFE_ACCESSORS
708 VMMLIB_ERROR(
"get_lateral_slice_fwd() - index out of bounds.", VMMLIB_HERE);
710 bwd_lat_slice_type* data_t =
new bwd_lat_slice_type();
711 for (
size_t i3 = 0; i3 < I3; ++i3) {
712 data_t->set_column(i3, _get_slice(i3).get_column(i2));
714 data_t->transpose_to(data);
720 VMML_TEMPLATE_CLASSNAME::
721 get_horizontal_slice_bwd(
size_t i1, bwd_horiz_slice_type& data)
const {
722 #ifdef VMMLIB_SAFE_ACCESSORS
724 VMMLIB_ERROR(
"get_horizontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
726 horiz_slice_type* data_t =
new horiz_slice_type();
727 for (
size_t i3 = 0; i3 < I3; ++i3) {
728 data_t->set_column(i3, _get_slice(i3).get_row(i1));
730 data_t->transpose_to(data);
740 VMML_TEMPLATE_CLASSNAME::
741 set_frontal_slice_fwd(
size_t i3,
const front_slice_type& data) {
742 #ifdef VMMLIB_SAFE_ACCESSORS
744 VMMLIB_ERROR(
"set_frontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
747 _get_slice(i3) = data;
752 VMML_TEMPLATE_CLASSNAME::
753 set_lateral_slice_bwd(
size_t i2,
const bwd_lat_slice_type& data) {
754 #ifdef VMMLIB_SAFE_ACCESSORS
756 VMMLIB_ERROR(
"set_lateral_slice_bwd() - index out of bounds.", VMMLIB_HERE);
759 for (
size_t i3 = 0; i3 < I3; ++i3) {
760 _get_slice(i3).set_column(i2, data.get_column(i3));
766 VMML_TEMPLATE_CLASSNAME::
767 set_horizontal_slice_fwd(
size_t i1,
const horiz_slice_type& data) {
768 #ifdef VMMLIB_SAFE_ACCESSORS
770 VMMLIB_ERROR(
"set_horizontal_slice_fwd() - index out of bounds.", VMMLIB_HERE);
773 for (
size_t i3 = 0; i3 < I3; ++i3) {
774 _get_slice(i3).set_row(i1, data.get_column(i3));
781 VMML_TEMPLATE_CLASSNAME::
782 set_frontal_slice_bwd(
size_t i3,
const bwd_front_slice_type& data) {
783 #ifdef VMMLIB_SAFE_ACCESSORS
785 VMMLIB_ERROR(
"set_frontal_slice_bwd() - index out of bounds.", VMMLIB_HERE);
787 front_slice_type* data_t =
new front_slice_type();
788 data.transpose_to(*data_t);
789 _get_slice(i3) = *data_t;
795 VMML_TEMPLATE_CLASSNAME::
796 set_lateral_slice_fwd(
size_t i2,
const lat_slice_type& data) {
797 #ifdef VMMLIB_SAFE_ACCESSORS
799 VMMLIB_ERROR(
"set_lateral_slice_fwd() - index out of bounds.", VMMLIB_HERE);
801 bwd_lat_slice_type* data_t =
new bwd_lat_slice_type();
802 data.transpose_to(*data_t);
803 for (
size_t i3 = 0; i3 < I3; ++i3) {
804 _get_slice(i3).set_column(i2, data_t->get_column(i3));
812 VMML_TEMPLATE_CLASSNAME::
813 set_horizontal_slice_bwd(
size_t i1,
const bwd_horiz_slice_type& data) {
814 #ifdef VMMLIB_SAFE_ACCESSORS
816 VMMLIB_ERROR(
"set_horizontal_slice_bwd() - index out of bounds.", VMMLIB_HERE);
818 horiz_slice_type* data_t =
new horiz_slice_type();
819 data.transpose_to(*data_t);
821 for (
size_t i3 = 0; i3 < I3; ++i3) {
822 _get_slice(i3).set_row(i1, data_t->get_column(i3));
833 VMML_TEMPLATE_CLASSNAME::
835 for (
size_t i3 = 0; i3 < I3; ++i3) {
836 _get_slice(i3).fill(fillValue);
842 VMML_TEMPLATE_CLASSNAME::
843 fill_random(
int seed) {
847 double fillValue = 0.0f;
848 for (
size_t index = 0; index < I1 * I2 * I3; ++index) {
850 fillValue /= RAND_MAX;
851 fillValue *= std::numeric_limits< T >::max();
852 _array[ index ] =
static_cast<T
> (fillValue);
856 for (
size_t i3 = 0; i3 < I3; ++i3) {
857 for (
size_t i1 = 0; i1 < I1; ++i1) {
858 for (
size_t i2 = 0; i2 < I2; ++i2) {
860 fillValue /= RAND_MAX;
861 fillValue *= std::numeric_limits< T >::max();
862 at(i1, i2, i3) =
static_cast<T
> (fillValue);
871 VMML_TEMPLATE_CLASSNAME::
872 fill_random_signed(
int seed) {
876 double fillValue = 0.0f;
877 for (
size_t i3 = 0; i3 < I3; ++i3) {
878 for (
size_t i1 = 0; i1 < I1; ++i1) {
879 for (
size_t i2 = 0; i2 < I2; ++i2) {
881 fillValue /= RAND_MAX;
882 fillValue *= std::numeric_limits< T >::max();
883 T fillValue2 =
static_cast<T
> (fillValue) % std::numeric_limits< T >::max();
884 fillValue2 -= std::numeric_limits< T >::max() / 2;
885 at(i1, i2, i3) = fillValue2;
893 VMML_TEMPLATE_CLASSNAME::
894 fill_rand_sym(
int seed) {
900 double fillValue = 0.0f;
902 for (
size_t i3 = 0; i3 < I3; ++i3) {
903 for (
size_t i1 = i3; i1 < I1; ++i1) {
904 for (
size_t i2 = i1; i2 < I2; ++i2) {
906 fillValue /= RAND_MAX;
907 fillValue *= std::numeric_limits< T >::max();
908 t_fill_value =
static_cast<T
> (fillValue);
910 at(i1, i2, i3) = t_fill_value;
912 if (i1 != i2 || i1 != i3 || i2 != i3) {
914 at(i2, i1, i3) = t_fill_value;
916 at(i1, i3, i2) = t_fill_value;
918 at(i3, i2, i1) = t_fill_value;
920 if (i1 != i2 && i1 != i3 && i2 != i3) {
921 at(i2, i3, i1) = t_fill_value;
922 at(i3, i1, i2) = t_fill_value;
932 VMML_TEMPLATE_CLASSNAME::
933 fill_rand_sym_slices(
int seed) {
938 double fillValue = 0.0f;
939 for (
size_t i3 = 0; i3 < I3; ++i3) {
940 for (
size_t i1 = 0; i1 < I1; ++i1) {
941 for (
size_t i2 = i1; i2 < I2; ++i2) {
943 fillValue /= RAND_MAX;
944 fillValue *= std::numeric_limits< T >::max();
945 at(i1, i2, i3) =
static_cast<T
> (fillValue);
946 at(i2, i1, i3) =
static_cast<T
> (fillValue);
954 VMML_TEMPLATE_CLASSNAME::
955 fill_increasing_values() {
956 double fillValue = 0.0f;
957 for (
size_t i3 = 0; i3 < I3; ++i3) {
958 for (
size_t i1 = 0; i1 < I1; ++i1) {
959 for (
size_t i2 = 0; i2 < I2; ++i2) {
960 at(i1, i2, i3) =
static_cast<T
> (fillValue);
969 VMML_TEMPLATE_CLASSNAME::range_threshold(tensor3<I1, I2, I3, T>& other_,
const T& start_value,
const T& end_value)
const {
971 for (
size_t i3 = 0; i3 < I3; ++i3) {
972 for (
size_t i1 = 0; i1 < I1; ++i1) {
973 for (
size_t i2 = 0; i2 < I2; ++i2) {
974 T value = at(i1, i2, i3);
975 if (value >= start_value && value <= end_value)
976 other_.at(i1, i2, i3) =
static_cast<T
> (value);
984 typename enable_if< R == I1 && R == I2 && R == I3>::type*
985 VMML_TEMPLATE_CLASSNAME::diag(
const vector< R, T >& diag_values_) {
987 for (
size_t r = 0; r < R; ++r) {
988 at(r, r, r) =
static_cast<T
> (diag_values_.at(r));
996 VMML_TEMPLATE_CLASSNAME::zero() {
997 fill(static_cast<T> (0.0));
1000 VMML_TEMPLATE_STRING
1002 VMML_TEMPLATE_CLASSNAME::operator==(
const tensor3< I1, I2, I3, T >& other)
const {
1004 for (
size_t index = 0; index < I1 * I2 * I3; ++index) {
1005 if (_array[ index ] != other._array[ index ])
1011 for (
size_t i3 = 0; ok && i3 < I3; ++i3) {
1012 ok = array[ i3 ] == other.array[ i3 ];
1018 VMML_TEMPLATE_STRING
1020 VMML_TEMPLATE_CLASSNAME::operator!=(
const tensor3< I1, I2, I3, T >& other)
const {
1021 return !operator==(other);
1024 VMML_TEMPLATE_STRING
1025 bool equals(
const tensor3< I1, I2, I3, T >& t3_0,
const tensor3< I1, I2, I3, T >& t3_1, T tolerance) {
1026 return t3_0.equals(t3_1, tolerance);
1029 VMML_TEMPLATE_STRING
1031 VMML_TEMPLATE_CLASSNAME::equals(
const tensor3< I1, I2, I3, T >& other, T tolerance)
const {
1033 for (
size_t i3 = 0; is_ok && i3 < I3; ++i3) {
1034 is_ok = _get_slice(i3).equals(other.get_frontal_slice_fwd(i3), tolerance);
1039 VMML_TEMPLATE_STRING
1041 VMML_TEMPLATE_CLASSNAME::size()
const {
1042 return I1 * I2 * I3;
1045 VMML_TEMPLATE_STRING
1046 template<
size_t J1,
size_t J2,
size_t J3 >
1047 tensor3<J1, J2, J3, T>
1048 VMML_TEMPLATE_CLASSNAME::
1049 get_sub_tensor3(
size_t row_offset,
size_t col_offset,
size_t slice_offset,
1050 typename enable_if< J1 <= I1 && J2 <= I2 && J3 <= I3 >::type*)
const {
1051 tensor3< J1, J2, J3, T > result;
1052 get_sub_tensor3(result, row_offset, col_offset, slice_offset);
1056 VMML_TEMPLATE_STRING
1057 template<
size_t J1,
size_t J2,
size_t J3 >
1058 typename enable_if< J1 <= I1 && J2 <= I2 && J3 <= I3 >::type*
1059 VMML_TEMPLATE_CLASSNAME::
1060 get_sub_tensor3(tensor3<J1, J2, J3, T >& result,
1061 size_t row_offset,
size_t col_offset,
size_t slice_offset)
const {
1062 #ifdef VMMLIB_SAFE_ACCESSORS
1063 if (J1 + row_offset > I1 || J2 + col_offset > I2 || J3 + slice_offset > I3)
1064 VMMLIB_ERROR(
"index out of bounds.", VMMLIB_HERE);
1067 for (
size_t slice = 0; slice < J3; ++slice) {
1068 for (
size_t row = 0; row < J1; ++row) {
1069 for (
size_t col = 0; col < J2; ++col) {
1070 result.at(row, col, slice)
1071 = at(row_offset + row, col_offset + col, slice_offset + slice);
1078 VMML_TEMPLATE_STRING
1080 VMML_TEMPLATE_CLASSNAME::
1081 get_sub_tensor3(
char* data_,
1082 const size_t i1_start,
const size_t i1_end,
1083 const size_t i2_start,
const size_t i2_end,
1084 const size_t i3_start,
const size_t i3_end )
const
1087 T* t_ptr = (T*)&(data_[0]);
1088 for (
size_t slice = i3_start; slice <= i3_end; ++slice ) {
1089 for (
size_t col = i2_start; col <= i2_end; ++col ) {
1090 for (
size_t row = i1_start; row <= i1_end; ++row ) {
1092 *t_ptr = at( row, col, slice );
1099 VMML_TEMPLATE_STRING
1100 template<
size_t J1,
size_t J2,
size_t J3 >
1101 typename enable_if< J1 <= I1 && J2 <= I2 && J3 <= I3 >::type*
1102 VMML_TEMPLATE_CLASSNAME::
1103 set_sub_tensor3(
const tensor3<J1, J2, J3, T >& sub_data_,
1104 size_t row_offset,
size_t col_offset,
size_t slice_offset) {
1105 #ifdef VMMLIB_SAFE_ACCESSORS
1106 if (J1 + row_offset > I1 || J2 + col_offset > I2 || J3 + slice_offset > I3)
1107 VMMLIB_ERROR(
"index out of bounds.", VMMLIB_HERE);
1110 for (
size_t slice = 0; slice < J3; ++slice) {
1111 for (
size_t row = 0; row < J1; ++row) {
1112 for (
size_t col = 0; col < J2; ++col) {
1113 at(row_offset + row, col_offset + col, slice_offset + slice) = sub_data_.at(row, col, slice);
1120 VMML_TEMPLATE_STRING
1122 VMML_TEMPLATE_CLASSNAME::
1123 set_sub_tensor3(
const char* data_,
1124 const size_t i1_start,
const size_t i1_end,
1125 const size_t i2_start,
const size_t i2_end,
1126 const size_t i3_start,
const size_t i3_end )
1129 T* t_ptr = (T*)&(data_[0]);
1130 for (
size_t slice = i3_start; slice <= i3_end; ++slice ) {
1131 for (
size_t col = i2_start; col <= i2_end; ++col ) {
1132 for (
size_t row = i1_start; row <= i1_end; ++row ) {
1134 at( row, col, slice ) = *t_ptr;
1141 VMML_TEMPLATE_STRING
1142 typename VMML_TEMPLATE_CLASSNAME::iterator
1143 VMML_TEMPLATE_CLASSNAME::begin() {
1144 return iterator(*
this,
true);
1147 VMML_TEMPLATE_STRING
1148 typename VMML_TEMPLATE_CLASSNAME::iterator
1149 VMML_TEMPLATE_CLASSNAME::end() {
1150 return iterator(*
this,
false);
1153 VMML_TEMPLATE_STRING
1154 typename VMML_TEMPLATE_CLASSNAME::const_iterator
1155 VMML_TEMPLATE_CLASSNAME::begin()
const {
1156 return const_iterator(*
this,
true);
1159 VMML_TEMPLATE_STRING
1160 typename VMML_TEMPLATE_CLASSNAME::const_iterator
1161 VMML_TEMPLATE_CLASSNAME::end()
const {
1162 return const_iterator(*
this,
false);
1165 VMML_TEMPLATE_STRING
1166 template<
typename input_iterator_t >
1168 VMML_TEMPLATE_CLASSNAME::set(input_iterator_t begin_, input_iterator_t end_,
bool row_major_layout) {
1169 input_iterator_t it(begin_);
1170 if (row_major_layout) {
1171 for (
size_t i3 = 0; i3 < I3; ++i3) {
1172 for (
size_t i1 = 0; i1 < I1; ++i1) {
1173 for (
size_t i2 = 0; i2 < I2; ++i2, ++it) {
1176 at(i1, i2, i3) =
static_cast<T
> (*it);
1181 std::copy(it, it + (I1 * I2 * I3), begin());
1185 VMML_TEMPLATE_STRING
1186 inline VMML_TEMPLATE_CLASSNAME
1187 VMML_TEMPLATE_CLASSNAME::operator+(
const tensor3< I1, I2, I3, T >& other)
const {
1188 tensor3< I1, I2, I3, T > result(*
this);
1193 VMML_TEMPLATE_STRING
1194 template<
size_t J1,
size_t J2,
size_t J3>
1195 typename enable_if< J1 < I1 && J2 < I2 && J3 < I3 >::type*
1196 VMML_TEMPLATE_CLASSNAME::operator+=(
const tensor3< J1, J2, J3, T >& other) {
1197 for (
size_t i3 = 0; i3 < J3; ++i3) {
1198 for (
size_t i1 = 0; i1 < J1; ++i1) {
1199 for (
size_t i2 = 0; i2 < J2; ++i2) {
1200 at(i1, i2, i3) += other.at(i1, i2, i3);
1207 VMML_TEMPLATE_STRING
1209 VMML_TEMPLATE_CLASSNAME::operator+=(
const tensor3< I1, I2, I3, T >& other) {
1210 iterator it = begin(), it_end = end();
1211 const_iterator other_it = other.begin();
1212 for (; it != it_end; ++it, ++other_it) {
1217 VMML_TEMPLATE_STRING
1218 inline VMML_TEMPLATE_CLASSNAME
1219 VMML_TEMPLATE_CLASSNAME::operator-(
const tensor3< I1, I2, I3, T >& other)
const {
1220 tensor3< I1, I2, I3, T > result(*
this);
1225 VMML_TEMPLATE_STRING
1227 VMML_TEMPLATE_CLASSNAME::operator-=(
const tensor3< I1, I2, I3, T >& other) {
1228 iterator it = begin(), it_end = end();
1229 const_iterator other_it = other.begin();
1230 for (; it != it_end; ++it, ++other_it) {
1238 VMML_TEMPLATE_STRING
1239 inline VMML_TEMPLATE_CLASSNAME
1240 VMML_TEMPLATE_CLASSNAME::operator+(T scalar)
const {
1241 tensor3< I1, I2, I3, T > result(*
this);
1246 VMML_TEMPLATE_STRING
1248 VMML_TEMPLATE_CLASSNAME::operator+=(T scalar) {
1249 iterator it = begin(), it_end = end();
1250 for (; it != it_end; ++it) {
1255 VMML_TEMPLATE_STRING
1256 inline VMML_TEMPLATE_CLASSNAME
1257 VMML_TEMPLATE_CLASSNAME::operator-(T scalar)
const {
1258 tensor3< I1, I2, I3, T > result(*
this);
1263 VMML_TEMPLATE_STRING
1265 VMML_TEMPLATE_CLASSNAME::operator-=(T scalar) {
1266 iterator it = begin(), it_end = end();
1267 for (; it != it_end; ++it) {
1272 VMML_TEMPLATE_STRING
1274 VMML_TEMPLATE_CLASSNAME::horizontal_unfolding_bwd(bwd_horiz_unfolding_type& unfolding)
const {
1275 bwd_horiz_slice_type* horizontal_slice =
new bwd_horiz_slice_type();
1276 for (
size_t i = 0; i < I1; ++i) {
1277 get_horizontal_slice_bwd(i, *horizontal_slice);
1278 for (
size_t col = 0; col < I2; ++col) {
1279 unfolding.set_column(i * I2 + col, horizontal_slice->get_column(col));
1282 delete horizontal_slice;
1285 VMML_TEMPLATE_STRING
1287 VMML_TEMPLATE_CLASSNAME::horizontal_unfolding_fwd(fwd_horiz_unfolding_type& unfolding)
const {
1288 horiz_slice_type* horizontal_slice =
new horiz_slice_type();
1289 for (
size_t i = 0; i < I1; ++i) {
1290 get_horizontal_slice_fwd(i, *horizontal_slice);
1291 for (
size_t col = 0; col < I3; ++col) {
1292 unfolding.set_column(i * I3 + col, horizontal_slice->get_column(col));
1295 delete horizontal_slice;
1298 VMML_TEMPLATE_STRING
1300 VMML_TEMPLATE_CLASSNAME::lateral_unfolding_bwd(bwd_lat_unfolding_type& unfolding)
const {
1301 bwd_lat_slice_type* lateral_slice =
new bwd_lat_slice_type();
1302 for (
size_t i = 0; i < I2; ++i) {
1303 get_lateral_slice_bwd(i, *lateral_slice);
1304 for (
size_t col = 0; col < I3; ++col) {
1305 unfolding.set_column(i * I3 + col, lateral_slice->get_column(col));
1308 delete lateral_slice;
1311 VMML_TEMPLATE_STRING
1313 VMML_TEMPLATE_CLASSNAME::lateral_unfolding_fwd(fwd_lat_unfolding_type& unfolding)
const {
1314 lat_slice_type* lateral_slice =
new lat_slice_type();
1315 for (
size_t i = 0; i < I2; ++i) {
1316 get_lateral_slice_fwd(i, *lateral_slice);
1317 for (
size_t col = 0; col < I1; ++col) {
1318 unfolding.set_column(i * I1 + col, lateral_slice->get_column(col));
1321 delete lateral_slice;
1324 VMML_TEMPLATE_STRING
1326 VMML_TEMPLATE_CLASSNAME::frontal_unfolding_bwd(bwd_front_unfolding_type& unfolding)
const {
1327 bwd_front_slice_type* frontal_slice =
new bwd_front_slice_type();
1328 for (
size_t i = 0; i < I3; ++i) {
1329 get_frontal_slice_bwd(i, *frontal_slice);
1330 for (
size_t col = 0; col < I1; ++col) {
1331 unfolding.set_column(i * I1 + col, frontal_slice->get_column(col));
1334 delete frontal_slice;
1337 VMML_TEMPLATE_STRING
1339 VMML_TEMPLATE_CLASSNAME::frontal_unfolding_fwd(fwd_front_unfolding_type& unfolding)
const {
1340 front_slice_type* frontal_slice =
new front_slice_type();
1341 for (
size_t i = 0; i < I3; ++i) {
1342 get_frontal_slice_fwd(i, *frontal_slice);
1343 for (
size_t col = 0; col < I2; ++col) {
1344 unfolding.set_column(i * I2 + col, frontal_slice->get_column(col));
1347 delete frontal_slice;
1350 VMML_TEMPLATE_STRING
1352 VMML_TEMPLATE_CLASSNAME::horizontal_folding_bwd(
const bwd_horiz_unfolding_type& unfolding) {
1353 bwd_horiz_slice_type* horizontal_slice =
new bwd_horiz_slice_type;
1354 for (
size_t i = 0; i < I1; ++i) {
1355 for (
size_t col = 0; col < I2; ++col) {
1356 horizontal_slice->set_column(col, unfolding.get_column(i * I2 + col));
1358 set_horizontal_slice_bwd(i, *horizontal_slice);
1360 delete horizontal_slice;
1363 VMML_TEMPLATE_STRING
1365 VMML_TEMPLATE_CLASSNAME::frontal_folding_bwd(
const bwd_front_unfolding_type& unfolding) {
1366 bwd_front_slice_type* frontal_slice =
new bwd_front_slice_type();
1367 for (
size_t i = 0; i < I3; ++i) {
1368 for (
size_t col = 0; col < I1; ++col) {
1369 frontal_slice->set_column(col, unfolding.get_column(i * I1 + col));
1371 set_frontal_slice_bwd(i, *frontal_slice);
1373 delete frontal_slice;
1376 VMML_TEMPLATE_STRING
1378 VMML_TEMPLATE_CLASSNAME::lateral_folding_bwd(
const bwd_lat_unfolding_type& unfolding) {
1379 bwd_lat_slice_type* lateral_slice =
new bwd_lat_slice_type();
1380 for (
size_t i = 0; i < I2; ++i) {
1381 for (
size_t col = 0; col < I3; ++col) {
1382 lateral_slice->set_column(col, unfolding.get_column(i * I3 + col));
1384 set_lateral_slice_bwd(i, *lateral_slice);
1386 delete lateral_slice;
1389 VMML_TEMPLATE_STRING
1390 tensor3< I1, I2, I3, T >
1391 VMML_TEMPLATE_CLASSNAME::operator*(T scalar) {
1392 tensor3< I1, I2, I3, T > result;
1393 for (
size_t index = 0; index < I1 * I2 * I3; ++index) {
1394 result._array[ index ] = _array[ index ] * scalar;
1398 tensor3< I1, I2, I3, T >* result = (*this);
1400 for (
size_t i3 = 0; i3 < I3; ++i3) {
1401 result.array[ i3 ] = array[ i3 ] * scalar;
1408 VMML_TEMPLATE_STRING
1410 VMML_TEMPLATE_CLASSNAME::operator*=(T scalar) {
1411 for (
size_t index = 0; index < I1 * I2 * I3; ++index) {
1412 _array[ index ] *= scalar;
1416 for (
size_t i3 = 0; i3 < I3; ++i3) {
1417 array[ i3 ] *= scalar;
1422 VMML_TEMPLATE_STRING
1423 tensor3< I1, I2, I3, T >
1424 VMML_TEMPLATE_CLASSNAME::operator/(T scalar) {
1425 tensor3< I1, I2, I3, T > result;
1427 for (
size_t slice_idx = 0; slice_idx < I3; ++slice_idx) {
1428 for (
size_t row_index = 0; row_index < I1; ++row_index) {
1429 for (
size_t col_index = 0; col_index < I2; ++col_index) {
1430 result.at(row_index, col_index, slice_idx) = at(row_index, col_index, slice_idx) / scalar;
1437 VMML_TEMPLATE_STRING
1439 VMML_TEMPLATE_CLASSNAME::operator/=(T scalar) {
1440 for (
size_t slice_idx = 0; slice_idx < I3; ++slice_idx) {
1441 for (
size_t row_index = 0; row_index < I1; ++row_index) {
1442 for (
size_t col_index = 0; col_index < I2; ++col_index) {
1443 at(row_index, col_index, slice_idx) /= scalar;
1449 VMML_TEMPLATE_STRING
1450 inline tensor3< I1, I2, I3, T >
1451 VMML_TEMPLATE_CLASSNAME::operator-()
const {
1455 VMML_TEMPLATE_STRING
1456 tensor3< I1, I2, I3, T >
1457 VMML_TEMPLATE_CLASSNAME::negate()
const {
1458 tensor3< I1, I2, I3, T > result;
1463 VMML_TEMPLATE_STRING
1465 VMML_TEMPLATE_CLASSNAME::frobenius_norm(
const tensor3< I1, I2, I3, T>& other_)
const {
1466 double f_norm = 0.0;
1468 const_iterator it = begin(), it_end = end();
1469 const_iterator it_other = other_.begin();
1470 for (; it != it_end; ++it, ++it_other) {
1471 abs_diff = fabs(*it - *it_other);
1472 f_norm += abs_diff * abs_diff;
1475 return sqrt(f_norm);
1478 VMML_TEMPLATE_STRING
1480 VMML_TEMPLATE_CLASSNAME::frobenius_norm()
const {
1481 double f_norm = 0.0;
1483 const_iterator it = begin(), it_end = end();
1484 for (; it != it_end; ++it)
1485 f_norm += *it * *it;
1487 for (
long i3 = 0; i3 < long(I3); ++i3) {
1488 for (
long i1 = 0; i1 < long(I1); ++i1) {
1490 for (i2 = 0; i2 < long(I2); ++i2) {
1491 f_norm += at(i1, i2, i3) * at(i1, i2, i3);
1498 return sqrt(f_norm);
1501 VMML_TEMPLATE_STRING
1503 VMML_TEMPLATE_CLASSNAME::avg_frobenius_norm()
const {
1504 double af_norm = 0.0;
1505 const_iterator it = begin(), it_end = end();
1506 for (; it != it_end; ++it)
1507 af_norm += *it * *it;
1510 return sqrt(af_norm);
1513 VMML_TEMPLATE_STRING
1515 VMML_TEMPLATE_CLASSNAME::mse(
const tensor3< I1, I2, I3, T >& other)
const {
1516 double mse_val = 0.0;
1518 const_iterator it = begin(), it_end = end();
1519 const_iterator other_it = other.begin();
1520 for (; it != it_end; ++it, ++other_it) {
1521 diff = abs(*it) - abs(*other_it);
1522 mse_val += diff * diff;
1525 mse_val /= (double) size();
1530 VMML_TEMPLATE_STRING
1532 VMML_TEMPLATE_CLASSNAME::rmse(
const tensor3< I1, I2, I3, T >& other)
const {
1533 return sqrt(mse(other));
1536 VMML_TEMPLATE_STRING
1538 VMML_TEMPLATE_CLASSNAME::mean()
const {
1540 const_iterator it = begin(), it_end = end();
1541 for (; it != it_end; ++it) {
1542 val += double(abs(*it));
1545 return ( val / size());
1548 VMML_TEMPLATE_STRING
1550 VMML_TEMPLATE_CLASSNAME::mean(T& mean_)
const {
1551 mean_ =
static_cast<T
> (mean());
1554 VMML_TEMPLATE_STRING
1556 VMML_TEMPLATE_CLASSNAME::variance()
const {
1558 double sum_val = 0.0;
1559 double mean_val = mean();
1560 const_iterator it = begin(), it_end = end();
1561 for (; it != it_end; ++it) {
1562 val = double(*it) - mean_val;
1567 return double(sum_val / (size() - 1));
1570 VMML_TEMPLATE_STRING
1572 VMML_TEMPLATE_CLASSNAME::stdev()
const {
1573 return sqrt(variance());
1576 VMML_TEMPLATE_STRING
1578 VMML_TEMPLATE_CLASSNAME::compute_psnr(
const tensor3< I1, I2, I3, T >& other,
const T& max_value_)
const {
1579 double rmse_val = rmse(other);
1580 double psnr_val = log(max_value_ / rmse_val);
1583 return fabs(psnr_val);
1586 VMML_TEMPLATE_STRING
1587 template<
typename TT >
1589 VMML_TEMPLATE_CLASSNAME::cast_from(
const tensor3< I1, I2, I3, TT >& other) {
1591 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1592 typedef typename t3_tt_type::const_iterator tt_const_iterator;
1594 iterator it = begin(), it_end = end();
1595 tt_const_iterator other_it = other.begin();
1596 for (; it != it_end; ++it, ++other_it) {
1597 *it =
static_cast<T
> (*other_it);
1600 #pragma omp parallel for
1601 for (
long slice_idx = 0; slice_idx < (long) I3; ++slice_idx) {
1602 #pragma omp parallel for
1603 for (
long row_index = 0; row_index < (long) I1; ++row_index) {
1604 #pragma omp parallel for
1605 for (
long col_index = 0; col_index < (long) I2; ++col_index) {
1606 at(row_index, col_index, slice_idx) =
static_cast<T
> (other.at(row_index, col_index, slice_idx));
1614 VMML_TEMPLATE_STRING
1615 template<
size_t J1,
size_t J2,
size_t J3,
typename TT >
1617 VMML_TEMPLATE_CLASSNAME::cast_from(
const tensor3< J1, J2, J3, TT >& other,
const long& slice_idx_start_) {
1618 #pragma omp parallel for
1619 for (
long slice_idx = slice_idx_start_; slice_idx < (long) J3; ++slice_idx) {
1620 #pragma omp parallel for
1621 for (
long row_index = 0; row_index < (long) J1; ++row_index) {
1622 #pragma omp parallel for
1623 for (
long col_index = 0; col_index < (long) J2; ++col_index) {
1624 at(row_index, col_index, slice_idx) =
static_cast<T
> (other.at(row_index, col_index, slice_idx));
1630 VMML_TEMPLATE_STRING
1631 template<
typename TT >
1633 VMML_TEMPLATE_CLASSNAME::float_t_to_uint_t(
const tensor3< I1, I2, I3, TT >& other) {
1634 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1635 typedef typename t3_tt_type::const_iterator tt_const_iterator;
1637 if (
sizeof (T) == 1 ||
sizeof (T) == 2) {
1638 iterator it = begin(), it_end = end();
1639 tt_const_iterator other_it = other.begin();
1640 for (; it != it_end; ++it, ++other_it) {
1641 *it = T(std::min(std::max(
int(0),
int( *other_it + 0.5)),
int(std::numeric_limits< T >::max())));
1645 this->cast_from(other);
1650 VMML_TEMPLATE_STRING
1652 VMML_TEMPLATE_CLASSNAME::get_min()
const {
1653 T tensor3_min =
static_cast<T
> (std::numeric_limits<T>::max());
1655 const_iterator it = begin(),
1657 for (; it != it_end; ++it) {
1658 if (*it < tensor3_min) {
1665 VMML_TEMPLATE_STRING
1667 VMML_TEMPLATE_CLASSNAME::get_max()
const {
1668 T tensor3_max =
static_cast<T
> (0);
1670 const_iterator it = begin(),
1672 for (; it != it_end; ++it) {
1673 if (*it > tensor3_max) {
1680 VMML_TEMPLATE_STRING
1682 VMML_TEMPLATE_CLASSNAME::get_abs_min()
const {
1683 T tensor3_min =
static_cast<T
> (std::numeric_limits<T>::max());
1685 const_iterator it = begin(),
1687 for (; it != it_end; ++it) {
1688 if (fabs(*it) < fabs(tensor3_min)) {
1689 tensor3_min = fabs(*it);
1695 VMML_TEMPLATE_STRING
1697 VMML_TEMPLATE_CLASSNAME::get_abs_max()
const {
1698 T tensor3_max =
static_cast<T
> (0);
1700 const_iterator it = begin(),
1702 for (; it != it_end; ++it) {
1703 if (fabs(*it) > fabs(tensor3_max)) {
1704 tensor3_max = fabs(*it);
1710 VMML_TEMPLATE_STRING
1712 VMML_TEMPLATE_CLASSNAME::nnz()
const {
1715 const_iterator it = begin(),
1717 for (; it != it_end; ++it) {
1726 VMML_TEMPLATE_STRING
1728 VMML_TEMPLATE_CLASSNAME::nnz(
const T& threshold_)
const {
1731 const_iterator it = begin(),
1733 for (; it != it_end; ++it) {
1734 if (fabs(*it) > threshold_) {
1742 VMML_TEMPLATE_STRING
1744 VMML_TEMPLATE_CLASSNAME::threshold(
const T& threshold_value_) {
1745 iterator it = begin(),
1747 for (; it != it_end; ++it) {
1748 if (fabs(*it) <= threshold_value_) {
1749 *it =
static_cast<T
> (0);
1754 VMML_TEMPLATE_STRING
1755 template<
typename TT >
1757 VMML_TEMPLATE_CLASSNAME::quantize_to(tensor3< I1, I2, I3, TT >& quantized_,
1758 const T& min_value_,
const T& max_value_)
const {
1759 double max_tt_range = double(std::numeric_limits< TT >::max());
1760 double min_tt_range = double(std::numeric_limits< TT >::min());
1761 double tt_range = max_tt_range - min_tt_range;
1762 double t_range = max_value_ - min_value_;
1767 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1768 typedef typename t3_tt_type::iterator tt_iterator;
1769 tt_iterator it_quant = quantized_.begin();
1770 const_iterator it = begin(), it_end = end();
1772 for (; it != it_end; ++it, ++it_quant) {
1773 if (std::numeric_limits<TT>::is_signed) {
1774 *it_quant = TT(std::min(std::max(min_tt_range,
double((*it * tt_range / t_range) + 0.5)), max_tt_range));
1776 *it_quant = TT(std::min(std::max(min_tt_range,
double(((*it - min_value_) * tt_range / t_range) + 0.5)), max_tt_range));
1782 VMML_TEMPLATE_STRING
1783 template<
typename TT >
1785 VMML_TEMPLATE_CLASSNAME::quantize(tensor3< I1, I2, I3, TT >& quantized_, T& min_value_, T& max_value_)
const {
1786 min_value_ = get_min();
1787 max_value_ = get_max();
1789 quantize_to(quantized_, min_value_, max_value_);
1792 VMML_TEMPLATE_STRING
1793 template<
typename TT >
1795 VMML_TEMPLATE_CLASSNAME::quantize_log(tensor3< I1, I2, I3, TT >& quantized_, tensor3< I1, I2, I3, char >& signs_, T& min_value_, T& max_value_,
const TT& tt_range_)
const {
1796 double max_tt_range = double(tt_range_);
1797 double min_tt_range = 0;
1800 max_value_ = get_abs_max();
1801 double t_range = max_value_ - min_value_;
1803 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1804 typedef typename t3_tt_type::iterator tt_iterator;
1805 tt_iterator it_quant = quantized_.begin();
1806 const_iterator it = begin(), it_end = end();
1808 typedef tensor3< I1, I2, I3, char > t3_sign_type;
1809 typedef typename t3_sign_type::iterator sign_iterator;
1810 sign_iterator it_sign = signs_.begin();
1812 for (; it != it_end; ++it, ++it_quant, ++it_sign) {
1813 T value = fabs(*it);
1814 *it_sign = ((*it) < 0.f) ? 0 : 1;
1816 if (std::numeric_limits<TT>::is_signed) {
1817 quant_value = log2(1 + value) / log2(1 + t_range) * tt_range_;
1818 *it_quant = TT(std::min(std::max(min_tt_range,
double(quant_value + 0.5)), max_tt_range));
1820 quant_value = log2(1 + (value - min_value_)) / log2(1 + t_range) * tt_range_;
1821 *it_quant = TT(std::min(std::max(min_tt_range,
double(quant_value + 0.5)), max_tt_range));
1826 VMML_TEMPLATE_STRING
1827 template<
typename TT >
1829 VMML_TEMPLATE_CLASSNAME::quantize_to(tensor3< I1, I2, I3, TT >& quantized_,
1830 tensor3< I1, I2, I3, char >& signs_,
1831 T& min_value_, T& max_value_,
1832 const TT& tt_range_)
const {
1833 double max_tt_range = double(tt_range_);
1834 double min_tt_range = 0;
1836 min_value_ = get_abs_min();
1837 max_value_ = get_abs_max();
1838 double t_range = max_value_ - min_value_;
1840 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1841 typedef typename t3_tt_type::iterator tt_iterator;
1842 tt_iterator it_quant = quantized_.begin();
1843 const_iterator it = begin(), it_end = end();
1845 typedef tensor3< I1, I2, I3, char > t3_sign_type;
1846 typedef typename t3_sign_type::iterator sign_iterator;
1847 sign_iterator it_sign = signs_.begin();
1849 for (; it != it_end; ++it, ++it_quant, ++it_sign) {
1850 T value = fabs(*it);
1851 *it_sign = ((*it) < 0.f) ? 0 : 1;
1852 if (std::numeric_limits<TT>::is_signed) {
1853 *it_quant = TT(std::min(std::max(min_tt_range,
double((value * tt_range_ / t_range) + 0.5)), max_tt_range));
1855 *it_quant = TT(std::min(std::max(min_tt_range,
double(((value - min_value_) * tt_range_ / t_range) + 0.5)), max_tt_range));
1860 VMML_TEMPLATE_STRING
1861 template<
typename TT >
1863 VMML_TEMPLATE_CLASSNAME::dequantize(tensor3< I1, I2, I3, TT >& dequantized_,
1864 const tensor3< I1, I2, I3, char >& signs_,
1865 const TT& min_value_,
const TT& max_value_)
const {
1866 T max_t_range = get_max();
1867 T min_t_range = get_min();
1868 long t_range = long(max_t_range) - long(min_t_range);
1870 TT tt_range = max_value_ - min_value_;
1872 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1873 typedef typename t3_tt_type::iterator tt_iterator;
1874 tt_iterator it_dequant = dequantized_.begin();
1875 const_iterator it = begin(), it_end = end();
1877 typedef tensor3< I1, I2, I3, char > t3_sign_type;
1878 typedef typename t3_sign_type::const_iterator sign_iterator;
1879 sign_iterator it_sign = signs_.begin();
1882 for (; it != it_end; ++it, ++it_dequant, ++it_sign) {
1883 sign = ((*it_sign) == 0) ? -1 : 1;
1884 if (std::numeric_limits<T>::is_signed) {
1885 *it_dequant = sign * std::min(std::max(min_value_, TT((TT(*it) / t_range) * tt_range)), max_value_);
1887 *it_dequant = sign * std::min(std::max(min_value_, TT((((TT(*it) / t_range)) * tt_range) + min_value_)), max_value_);
1892 VMML_TEMPLATE_STRING
1893 template<
typename TT >
1895 VMML_TEMPLATE_CLASSNAME::dequantize_log(tensor3< I1, I2, I3, TT >& dequantized_,
1896 const tensor3< I1, I2, I3, char >& signs_,
1897 const TT& min_value_,
const TT& max_value_)
const {
1898 T max_t_range = get_max();
1899 T min_t_range = get_min();
1900 long t_range = long(max_t_range) - long(min_t_range);
1902 TT tt_range = max_value_ - min_value_;
1904 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1905 typedef typename t3_tt_type::iterator tt_iterator;
1906 tt_iterator it_dequant = dequantized_.begin();
1907 const_iterator it = begin(), it_end = end();
1909 typedef tensor3< I1, I2, I3, char > t3_sign_type;
1910 typedef typename t3_sign_type::const_iterator sign_iterator;
1911 sign_iterator it_sign = signs_.begin();
1914 for (; it != it_end; ++it, ++it_dequant, ++it_sign) {
1916 TT dequant_value = 0;
1917 sign = ((*it_sign) == 0) ? -1 : 1;
1918 if (std::numeric_limits<T>::is_signed) {
1919 dequant_value = exp2((value / t_range) * log2(1 + tt_range)) - 1;
1920 *it_dequant = sign * (std::min(std::max(min_value_, dequant_value), max_value_));
1922 dequant_value = exp2((value / t_range) * log2(1 + tt_range)) - 1;
1923 *it_dequant = sign * (std::min(std::max(min_value_, dequant_value + min_value_), max_value_));
1928 VMML_TEMPLATE_STRING
1929 template<
typename TT >
1931 VMML_TEMPLATE_CLASSNAME::dequantize(tensor3< I1, I2, I3, TT >& dequantized_,
const TT& min_value_,
const TT& max_value_)
const {
1932 T max_t_range = get_max();
1933 T min_t_range = get_min();
1934 long t_range = long(max_t_range) - long(min_t_range);
1936 TT tt_range = max_value_ - min_value_;
1938 typedef tensor3< I1, I2, I3, TT > t3_tt_type;
1939 typedef typename t3_tt_type::iterator tt_iterator;
1940 tt_iterator it_dequant = dequantized_.begin();
1941 const_iterator it = begin(), it_end = end();
1942 for (; it != it_end; ++it, ++it_dequant) {
1943 if (std::numeric_limits<T>::is_signed) {
1944 *it_dequant = std::min(std::max(min_value_, TT((TT(*it) / t_range) * tt_range)), max_value_);
1946 *it_dequant = std::min(std::max(min_value_, TT((((TT(*it) / t_range)) * tt_range) + min_value_)), max_value_);
1951 VMML_TEMPLATE_STRING
1952 const VMML_TEMPLATE_CLASSNAME&
1953 VMML_TEMPLATE_CLASSNAME::operator=(
const VMML_TEMPLATE_CLASSNAME& source_) {
1954 memcpy(_array, source_._array, I1 * I2 * I3 * sizeof ( T));
1963 std::string format_path(
const std::string& dir_,
const std::string& filename_,
const std::string& format_) {
1964 std::string path = dir_;
1965 int dir_length = dir_.size() - 1;
1966 int last_separator = dir_.find_last_of(
"/");
1967 std::string path = dir_;
1968 if (last_separator < dir_length) {
1971 path.append(filename_);
1973 if (filename_.find(format_, filename_.size() - 3) == (-1)) {
1975 path.append(format_);
1982 VMML_TEMPLATE_STRING
1984 VMML_TEMPLATE_CLASSNAME::
1985 _get_slice(
size_t index_) {
1986 typedef matrix< I1, I2, T > matrix_type;
1987 return *
reinterpret_cast<matrix_type*
> (_array + I1 * I2 * index_);
1990 VMML_TEMPLATE_STRING
1992 VMML_TEMPLATE_CLASSNAME::
1993 _get_slice(
size_t index_)
const {
1994 typedef matrix< I1, I2, T > matrix_type;
1995 return *
reinterpret_cast<const matrix_type*
> (_array + I1 * I2 * index_);
1998 VMML_TEMPLATE_STRING
2000 VMML_TEMPLATE_CLASSNAME::
2001 tensor3_allocate_data(T*& array_) {
2002 array_ =
new T[ I1 * I2 * I3];
2005 VMML_TEMPLATE_STRING
2007 VMML_TEMPLATE_CLASSNAME::
2008 tensor3_deallocate_data(T*& array_) {
2014 VMML_TEMPLATE_STRING
2016 VMML_TEMPLATE_CLASSNAME::get_array_ptr() {
2020 VMML_TEMPLATE_STRING
2022 VMML_TEMPLATE_CLASSNAME::get_array_ptr()
const {
2026 VMML_TEMPLATE_STRING
2027 template<
size_t R >
2029 VMML_TEMPLATE_CLASSNAME::
2037 for (
size_t j = 0; j < I2; j++) {
2038 for (
size_t k = 0; k < I3; k++) {
2039 for (
size_t r = 0; r < R; r++) {
2040 temp(r, j + k * I2) = V(r, j) * W(r, k);
2045 for (
size_t i = 0; i < I1; i++) {
2046 for (
size_t r = 0; r < R; r++) {
2047 U(r, i) = lambda[r] * U(r, i);
2052 vector< R, T > tmpi;
2053 blas_dot< R, T > bdot;
2054 for (
size_t k = 0; k < I3; k++) {
2055 for (
size_t j = 0; j < I2; j++) {
2056 for (
size_t i = 0; i < I1; i++) {
2057 T& value = at(i, j, k);
2058 value =
static_cast<T
> (0.0);
2061 ui = U.get_column(i);
2062 tmpi = temp.get_column(j + k * I2);
2063 bdot.compute(ui, tmpi, value);
2066 for (
size_t r = 0; r < R; ++r)
2067 value += U(r, i) * temp(r, j + k * I2);
2075 VMML_TEMPLATE_STRING
2076 template<
typename float_t>
2078 VMML_TEMPLATE_CLASSNAME::
2079 apply_spherical_weights(tensor3< I1, I2, I3, float_t >& other) {
2081 for (
size_t i3 = 0; i3 < I3; ++i3) {
2082 size_t k3 = i3 - I3 / 2;
2083 for (
size_t i1 = 0; i1 < I1; ++i1) {
2084 size_t k1 = i1 - I1 / 2;
2085 for (
size_t i2 = 0; i2 < I2; ++i2) {
2086 size_t k2 = i2 - I2 / 2;
2087 float_t weight = (sqrtf(k1 * k1 + k2 * k2 + k3 * k3) + 0.0000001);
2088 weight = exp(-weight);
2089 float_t value =
static_cast<float_t
> (at(i1, i2, i3));
2091 other.at(i1, i2, i3) =
static_cast<float_t
> (weight * value);
2097 VMML_TEMPLATE_STRING
2099 VMML_TEMPLATE_CLASSNAME::
2101 for (
size_t i3 = 0; i3 < I3; ++i3) {
2102 size_t k3 = i3 - I3 / 2;
2103 for (
size_t i1 = 0; i1 < I1; ++i1) {
2104 size_t k1 = i1 - I1 / 2;
2105 for (
size_t i2 = 0; i2 < I2; ++i2) {
2106 size_t k2 = i2 - I2 / 2;
2107 float_t radius = sqrtf(k1 * k1 + k2 * k2 + k3 * k3);
2109 if (radius >= (I1 / 2))
2116 VMML_TEMPLATE_STRING
2117 template<
size_t R,
typename TT >
2119 VMML_TEMPLATE_CLASSNAME::tensor_inner_product(
2125 for (
size_t r = 0; r < R; ++r) {
2126 for (
size_t k = 0; k < I3; ++k) {
2127 for (
size_t j = 0; j < I2; ++j) {
2128 for (
size_t i = 0; i < I1; ++i) {
2129 inner_prod += at(i, j, k) * U(i, r) * V(j, r) * W(k, r) * lambda.at(r);
2137 VMML_TEMPLATE_STRING
2138 template<
size_t K1,
size_t K2,
size_t K3 >
2140 VMML_TEMPLATE_CLASSNAME::average_8to1(tensor3< K1, K2, K3, T >& other)
const {
2141 assert(I1 / 2 >= K1);
2142 assert(I2 / 2 >= K2);
2143 assert(I3 / 2 >= K3);
2145 typedef matrix< K1, K2, T > other_slice_type;
2146 typedef matrix< K1, K2, float > other_slice_float_type;
2147 typedef matrix< K1, I2, T> sub_row_slice_type;
2149 front_slice_type* slice0 =
new front_slice_type;
2150 front_slice_type* slice1 =
new front_slice_type;
2151 sub_row_slice_type* sub_row_slice =
new sub_row_slice_type;
2152 other_slice_type* slice_other =
new other_slice_type;
2153 other_slice_float_type* slice_float_other =
new other_slice_float_type;
2157 for (
size_t i3 = 0, k3 = 0; i3 < I3; ++i3, ++k3) {
2158 get_frontal_slice_fwd(i3++, *slice0);
2160 get_frontal_slice_fwd(i3, *slice1);
2163 slice0->sum_rows(*sub_row_slice);
2164 sub_row_slice->sum_columns(*slice_other);
2166 *slice_float_other = *slice_other;
2167 *slice_float_other /= 8.0;
2168 *slice_float_other += 0.5;
2170 slice_other->cast_from(*slice_float_other);
2172 other.set_frontal_slice_fwd(k3, *slice_other);
2179 delete sub_row_slice;
2182 VMML_TEMPLATE_STRING
2184 VMML_TEMPLATE_CLASSNAME::get_array_size_in_bytes() {
2185 return (
sizeof (T) * SIZE);
2193 VMML_TEMPLATE_STRING
2195 VMML_TEMPLATE_CLASSNAME::clear_array_pointer() {
2201 #undef VMML_TEMPLATE_STRING
2202 #undef VMML_TEMPLATE_CLASSNAME