33 #ifndef __VMML__T4_HOSVD__HPP__
34 #define __VMML__T4_HOSVD__HPP__
36 #include <vmmlib/tensor4.hpp>
37 #include <vmmlib/lapack_svd.hpp>
38 #include <vmmlib/lapack_sym_eigs.hpp>
39 #include <vmmlib/blas_dgemm.hpp>
40 #include <vmmlib/blas_daxpy.hpp>
45 template<
size_t R1,
size_t R2,
size_t R3,
size_t R4,
size_t I1,
size_t I2,
size_t I3,
size_t I4,
typename T =
float >
75 template<
size_t N,
size_t R >
85 #define VMML_TEMPLATE_STRING template< size_t R1, size_t R2, size_t R3, size_t R4, size_t I1, size_t I2, size_t I3, size_t I4, typename T >
86 #define VMML_TEMPLATE_CLASSNAME t4_hosvd< R1, R2, R3, R4, I1, I2, I3, I4, T >
90 VMML_TEMPLATE_CLASSNAME::apply_mode1(
const t4_type& data_, u1_type& u1_)
92 eigs_mode1( data_, u1_ );
97 VMML_TEMPLATE_CLASSNAME::apply_mode2(
const t4_type& data_, u2_type& u2_)
99 eigs_mode2( data_, u2_ );
104 VMML_TEMPLATE_CLASSNAME::apply_mode3(
const t4_type& data_, u3_type& u3_)
106 eigs_mode3( data_, u3_ );
111 VMML_TEMPLATE_CLASSNAME::apply_mode4(
const t4_type& data_, u4_type& u4_)
113 eigs_mode4( data_, u4_ );
120 VMML_TEMPLATE_CLASSNAME::eigs_mode1(
const t4_type& data_, u1_type& u1_ )
123 u1_unfolded_type* unfolding =
new u1_unfolded_type;
124 data_.mode1_unfolding_fwd( *unfolding );
127 u1_cov_type* cov =
new u1_cov_type;
128 blas_dgemm< I1, I2*I3*I4, I1, T>* blas_cov =
new blas_dgemm< I1, I2*I3*I4, I1, T>;
129 blas_cov->compute( *unfolding, *cov );
134 get_eigs_u_red( *cov, u1_ );
141 VMML_TEMPLATE_CLASSNAME::eigs_mode2(
const t4_type& data_, u2_type& u2_ )
144 u2_unfolded_type* unfolding =
new u2_unfolded_type;
145 data_.mode2_unfolding_fwd( *unfolding );
148 u2_cov_type* cov =
new u2_cov_type;
149 blas_dgemm< I2, I1*I3*I4, I2, T>* blas_cov =
new blas_dgemm< I2, I1*I3*I4, I2, T>;
150 blas_cov->compute( *unfolding, *cov );
155 get_eigs_u_red( *cov, u2_ );
162 VMML_TEMPLATE_CLASSNAME::eigs_mode3(
const t4_type& data_, u3_type& u3_)
165 u3_unfolded_type* unfolding =
new u3_unfolded_type;
166 data_.mode3_unfolding_fwd( *unfolding );
169 u3_cov_type* cov =
new u3_cov_type;
170 blas_dgemm< I3, I1*I2*I4, I3, T>* blas_cov =
new blas_dgemm< I3, I1*I2*I4, I3, T>;
171 blas_cov->compute( *unfolding, *cov );
176 get_eigs_u_red( *cov, u3_ );
183 VMML_TEMPLATE_CLASSNAME::eigs_mode4(
const t4_type& data_, u4_type& u4_)
186 u4_unfolded_type* unfolding =
new u4_unfolded_type;
187 data_.mode4_unfolding_fwd( *unfolding );
190 u4_cov_type* cov =
new u4_cov_type;
191 blas_dgemm< I4, I1*I2*I3, I4, T>* blas_cov =
new blas_dgemm< I4, I1*I2*I3, I4, T>;
192 blas_cov->compute( *unfolding, *cov );
197 get_eigs_u_red( *cov, u4_ );
205 template<
size_t N,
size_t R >
207 VMML_TEMPLATE_CLASSNAME::get_eigs_u_red(
const matrix< N, N, T >& data_, matrix< N, R, T >& u_ )
209 typedef matrix< N, N, T > cov_matrix_type;
210 typedef vector< R, T > eigval_type;
211 typedef matrix< N, R, T > eigvec_type;
215 eigval_type* eigxvalues =
new eigval_type;
216 eigvec_type* eigxvectors =
new eigvec_type;
218 lapack_sym_eigs< N, T > eigs;
219 cov_matrix_type* data =
new cov_matrix_type;
220 data->cast_from( data_ );
221 if( !eigs.compute_x( *data, *eigxvectors, *eigxvalues) ) {
231 std::cerr <<
"Warning: lapack eigenvector computation returned error code" << std::endl;
240 #undef VMML_TEMPLATE_STRING
241 #undef VMML_TEMPLATE_CLASSNAME