46 #ifndef __VMML__QTUCKER3_TENSOR__HPP__
47 #define __VMML__QTUCKER3_TENSOR__HPP__
49 #define CORE_RANGE 127
52 #include <vmmlib/tucker3_tensor.hpp>
58 template<
size_t R1,
size_t R2,
size_t R3,
size_t I1,
size_t I2,
size_t I3,
typename T_value =
float,
typename T_coeff =
double >
62 typedef float T_internal;
82 static const size_t SIZE = R1*R2*R3 + I1*R1 + I2*R2 + I3*R3;
91 void enable_quantify_hot() { _is_quantify_hot =
true; _is_quantify_log =
false; _is_quantify_linear =
false;};
92 void disable_quantify_hot() { _is_quantify_hot =
false; } ;
93 void enable_quantify_linear() { _is_quantify_linear =
true; _is_quantify_hot =
false;};
94 void disable_quantify_linear() { _is_quantify_linear =
false; } ;
95 void enable_quantify_log() { _is_quantify_log =
true; _is_quantify_hot =
false;};
96 void disable_quantify_log() { _is_quantify_log =
false; } ;
101 T_internal get_hottest_value() {
return _hottest_core_value; };
102 void set_hottest_value(
const T_internal value_ ) { _hottest_core_value = value_; } ;
105 void set_u1(
u1_type& U1 ) { *_u1 = U1; _u1_comp->cast_from( U1 ); } ;
106 void set_u2(
u2_type& U2 ) { *_u2 = U2; _u2_comp->cast_from( U2 ); } ;
107 void set_u3(
u3_type& U3 ) { *_u3 = U3; _u3_comp->cast_from( U3 ); } ;
109 void get_core(
t3_core_type& data_ )
const { data_ = _core; } ;
110 void get_u1(
u1_type& U1 )
const { U1 = *_u1; } ;
111 void get_u2(
u2_type& U2 )
const { U2 = *_u2; } ;
112 void get_u3(
u3_type& U3 )
const { U3 = *_u3; } ;
115 void set_u1_comp(
u1_comp_type& U1 ) { *_u1_comp = U1; _u1->cast_from( U1 ); } ;
116 void set_u2_comp(
u2_comp_type& U2 ) { *_u2_comp = U2; _u2->cast_from( U2 ); } ;
117 void set_u3_comp(
u3_comp_type& U3 ) { *_u3_comp = U3; _u3->cast_from( U3 ); } ;
120 void get_u1_comp(
u1_comp_type& U1 )
const { U1 = *_u1_comp; } ;
121 void get_u2_comp(
u2_comp_type& U2 )
const { U2 = *_u2_comp; } ;
122 void get_u3_comp(
u3_comp_type& U3 )
const { U3 = *_u3_comp; } ;
126 size_t nnz(
const T_value& threshold )
const;
127 size_t nnz_core()
const;
128 size_t size_core()
const;
129 size_t size()
const {
return SIZE; } ;
131 void threshold_core(
const size_t& nnz_core_,
size_t& nnz_core_is_ );
132 void threshold_core(
const T_coeff& threshold_value_,
size_t& nnz_core_ );
133 void reconstruct(
t3_type& data_,
134 const T_internal& u_min_,
const T_internal& u_max_,
135 const T_internal& core_min_,
const T_internal& core_max_ );
136 void reconstruct(
t3_type& data_,
137 const T_internal& u1_min_,
const T_internal& u1_max_,
138 const T_internal& u2_min_,
const T_internal& u2_max_,
139 const T_internal& u3_min_,
const T_internal& u3_max_,
140 const T_internal& core_min_,
const T_internal& core_max_ );
142 template<
typename T_init>
143 void decompose(
const t3_type& data_,
144 T_internal& u1_min_, T_internal& u1_max_,
145 T_internal& u2_min_, T_internal& u2_max_,
146 T_internal& u3_min_, T_internal& u3_max_,
147 T_internal& core_min_, T_internal& core_max_,
149 template<
typename T_init>
150 void decompose(
const t3_type& data_,
151 T_internal& u_min_, T_internal& u_max_,
152 T_internal& core_min_, T_internal& core_max_,
155 template<
typename T_init>
156 void tucker_als(
const t3_type& data_, T_init init );
158 friend std::ostream& operator << ( std::ostream& os,
const tucker3_type& t3 )
165 os <<
"U1: " << std::endl << *u1 << std::endl
166 <<
"U2: " << std::endl << *u2 << std::endl
167 <<
"U3: " << std::endl << *u3 << std::endl
168 <<
"core: " << std::endl << core << std::endl;
177 void cast_comp_members();
178 void quantize_basis_matrices( T_internal& u_min_, T_internal& u_max_ );
179 void quantize_basis_matrices( T_internal& u1_min_, T_internal& u1_max_, T_internal& u2_min_, T_internal& u2_max_, T_internal& u3_min_, T_internal& u3_max_ );
180 void quantize_core( T_internal& core_min_, T_internal& core_max_ );
181 void dequantize_basis_matrices(
const T_internal& u1_min_,
const T_internal& u1_max_,
const T_internal& u2_min_,
const T_internal& u2_max_,
const T_internal& u3_min_,
const T_internal& u3_max_ );
182 void dequantize_core(
const T_internal& core_min_,
const T_internal& core_max_ );
187 template<
typename T_init>
188 void decompose(
const t3_type& data_, T_init init );
189 void reconstruct(
t3_type& data_ );
204 T_internal _hottest_core_value;
207 bool _is_quantify_hot;
208 bool _is_quantify_log;
209 bool _is_quantify_linear;
214 #define VMML_TEMPLATE_STRING template< size_t R1, size_t R2, size_t R3, size_t I1, size_t I2, size_t I3, typename T_value, typename T_coeff >
215 #define VMML_TEMPLATE_CLASSNAME qtucker3_tensor< R1, R2, R3, I1, I2, I3, T_value, T_coeff >
219 VMML_TEMPLATE_CLASSNAME::qtucker3_tensor( )
220 : _hottest_core_value( 0 )
221 , _is_quantify_hot( false )
222 , _is_quantify_log( false )
223 , _is_quantify_linear( false )
226 _u1 =
new u1_type(); _u1->zero();
227 _u2 =
new u2_type(); _u2->zero();
228 _u3 =
new u3_type(); _u3->zero();
230 _u1_comp =
new u1_comp_type(); _u1_comp->zero();
231 _u2_comp =
new u2_comp_type(); _u2_comp->zero();
232 _u3_comp =
new u3_comp_type(); _u3_comp->zero();
238 VMML_TEMPLATE_CLASSNAME::qtucker3_tensor( t3_core_type& core )
239 : _hottest_core_value( 0 )
240 , _is_quantify_hot( false )
241 , _is_quantify_log( false )
242 , _is_quantify_linear( false )
245 _u1 =
new u1_type(); _u1->zero();
246 _u2 =
new u2_type(); _u2->zero();
247 _u3 =
new u3_type(); _u3->zero();
248 _u1_comp =
new u1_comp_type(); _u1_comp->zero();
249 _u2_comp =
new u2_comp_type(); _u2_comp->zero();
250 _u3_comp =
new u3_comp_type(); _u3_comp->zero();
251 _core_comp.cast_from( core );
257 VMML_TEMPLATE_CLASSNAME::qtucker3_tensor( t3_core_type& core, u1_type& U1, u2_type& U2, u3_type& U3 )
258 : _hottest_core_value( 0 )
259 , _is_quantify_hot( false )
260 , _is_quantify_log( false )
261 , _is_quantify_linear( false )
264 _u1 =
new u1_type( U1 );
265 _u2 =
new u2_type( U2 );
266 _u3 =
new u3_type( U3 );
267 _u1_comp =
new u1_comp_type();
268 _u2_comp =
new u2_comp_type();
269 _u3_comp =
new u3_comp_type();
276 VMML_TEMPLATE_CLASSNAME::qtucker3_tensor(
const t3_type& data_, u1_type& U1, u2_type& U2, u3_type& U3 )
277 : _hottest_core_value( 0 )
278 , _is_quantify_hot( false )
279 , _is_quantify_log( false )
280 , _is_quantify_linear( false )
282 _u1 =
new u1_type( U1 );
283 _u2 =
new u2_type( U2 );
284 _u3 =
new u3_type( U3 );
285 _u1_comp =
new u1_comp_type();
286 _u2_comp =
new u2_comp_type();
287 _u3_comp =
new u3_comp_type();
289 t3_hooi< R1, R2, R3, I1, I2, I3, T_coeff >::derive_core( data_, *_u1, *_u2, *_u3, _core );
297 VMML_TEMPLATE_CLASSNAME::qtucker3_tensor(
const tucker3_type& other )
298 : _hottest_core_value( 0 )
299 , _is_quantify_hot( false )
300 , _is_quantify_log( false )
301 , _is_quantify_linear( false )
306 _u1_comp =
new u1_comp_type();
307 _u2_comp =
new u2_comp_type();
308 _u3_comp =
new u3_comp_type();
310 other.get_core( _core );
311 other.get_u1( *_u1 );
312 other.get_u2( *_u2 );
313 other.get_u3( *_u3 );
324 VMML_TEMPLATE_CLASSNAME::cast_members()
326 _u1->cast_from( *_u1_comp );
327 _u2->cast_from( *_u2_comp );
328 _u3->cast_from( *_u3_comp );
329 _core.cast_from( _core_comp);
334 VMML_TEMPLATE_CLASSNAME::cast_comp_members()
336 _u1_comp->cast_from( *_u1 );
337 _u2_comp->cast_from( *_u2 );
338 _u3_comp->cast_from( *_u3 );
339 _core_comp.cast_from( _core);
345 VMML_TEMPLATE_CLASSNAME::nnz_core()
const
347 return _core_comp.nnz();
352 VMML_TEMPLATE_CLASSNAME::size_core()
const
354 return _core_comp.size();
361 VMML_TEMPLATE_CLASSNAME::quantize_basis_matrices(T_internal& u1_min_, T_internal& u1_max_,
362 T_internal& u2_min_, T_internal& u2_max_,
363 T_internal& u3_min_, T_internal& u3_max_ )
365 _u1_comp->quantize( *_u1, u1_min_, u1_max_ );
366 _u2_comp->quantize( *_u2, u2_min_, u2_max_ );
367 _u3_comp->quantize( *_u3, u3_min_, u3_max_ );
373 VMML_TEMPLATE_CLASSNAME::quantize_basis_matrices(T_internal& u_min_, T_internal& u_max_)
375 u_min_ = _u1_comp->get_min();
376 T_internal u2_min = _u2_comp->get_min();
377 T_internal u3_min = _u3_comp->get_min();
379 if ( u2_min < u_min_) {
382 if ( u3_min < u_min_) {
386 u_max_ = _u1_comp->get_max();
387 T_internal u2_max = _u2_comp->get_max();
388 T_internal u3_max = _u3_comp->get_max();
390 if ( u2_max > u_max_ ) {
393 if ( u3_max > u_max_ ) {
397 _u1_comp->quantize_to( *_u1, u_min_, u_max_ );
398 _u2_comp->quantize_to( *_u2, u_min_, u_max_ );
399 _u3_comp->quantize_to( *_u3, u_min_, u_max_ );
402 std::cout <<
"quantized (1u): " << std::endl <<
"u1-u3: " << std::endl
403 << *_u1 << std::endl << *_u1_comp << std::endl
404 << *_u2 << std::endl << *_u2_comp << std::endl
405 << *_u3 << std::endl << *_u3_comp << std::endl
406 <<
" core " << std::endl
407 << _core << std::endl
408 <<
" core_comp " << std::endl
409 << _core_comp << std::endl;
416 VMML_TEMPLATE_CLASSNAME::quantize_core( T_internal& core_min_, T_internal& core_max_ )
418 if ( _is_quantify_hot ) {
419 _hottest_core_value = _core_comp.at(0,0,0);
420 _core_comp.at( 0, 0, 0 ) = 0;
421 _core_comp.quantize_log( _core, _signs, core_min_, core_max_, T_coeff(CORE_RANGE) );
422 }
else if ( _is_quantify_linear ) {
423 _core_comp.quantize( _core, core_min_, core_max_ );
424 }
else if ( _is_quantify_log ) {
425 _core_comp.quantize_log( _core, _signs, core_min_, core_max_, T_coeff(CORE_RANGE) );
427 _core_comp.quantize( _core, core_min_, core_max_ );
428 std::cout <<
"quant.method not specified" << std::endl;
435 VMML_TEMPLATE_CLASSNAME::dequantize_basis_matrices(
const T_internal& u1_min_,
const T_internal& u1_max_,
436 const T_internal& u2_min_,
const T_internal& u2_max_,
437 const T_internal& u3_min_,
const T_internal& u3_max_ )
439 _u1->dequantize( *_u1_comp, u1_min_, u1_max_ );
440 _u2->dequantize( *_u2_comp, u2_min_, u2_max_ );
441 _u3->dequantize( *_u3_comp, u3_min_, u3_max_ );
446 VMML_TEMPLATE_CLASSNAME::dequantize_core(
const T_internal& core_min_,
const T_internal& core_max_ )
448 if ( _is_quantify_hot ) {
449 _core.dequantize_log( _core_comp, _signs, core_min_, core_max_ );
450 _core.at(0,0,0) = _hottest_core_value;
451 _core_comp.at(0,0,0) = _hottest_core_value;
452 }
else if ( _is_quantify_linear ) {
453 _core.dequantize( _core_comp, core_min_, core_max_ );
454 }
else if ( _is_quantify_log ) {
455 _core.dequantize_log( _core_comp, _signs, core_min_, core_max_ );
457 _core.dequantize( _core_comp, core_min_, core_max_ );
462 VMML_TEMPLATE_CLASSNAME::~qtucker3_tensor( )
474 VMML_TEMPLATE_CLASSNAME::reconstruct( t3_type& data_,
475 const T_internal& u_min_,
const T_internal& u_max_,
476 const T_internal& core_min_,
const T_internal& core_max_ )
478 dequantize_basis_matrices( u_min_, u_max_, u_min_, u_max_, u_min_, u_max_ );
479 dequantize_core( core_min_, core_max_ );
482 std::cout <<
"dequantized (1u): " << std::endl <<
"u1-u3: " << std::endl
483 << *_u1 << std::endl << *_u1_comp << std::endl
484 << *_u2 << std::endl << *_u2_comp << std::endl
485 << *_u3 << std::endl << *_u3_comp << std::endl
486 <<
" core " << std::endl
487 << _core << std::endl
488 <<
" core_comp " << std::endl
489 << _core_comp << std::endl;
492 reconstruct( data_ );
497 VMML_TEMPLATE_CLASSNAME::reconstruct( t3_type& data_,
498 const T_internal& u1_min_,
const T_internal& u1_max_,
499 const T_internal& u2_min_,
const T_internal& u2_max_,
500 const T_internal& u3_min_,
const T_internal& u3_max_,
501 const T_internal& core_min_,
const T_internal& core_max_ )
503 dequantize_basis_matrices( u1_min_, u1_max_, u2_min_, u2_max_, u3_min_, u3_max_ );
504 dequantize_core( core_min_, core_max_ );
506 reconstruct( data_ );
511 VMML_TEMPLATE_CLASSNAME::reconstruct( t3_type& data_ )
514 data.cast_from( data_ );
515 t3_ttm::full_tensor3_matrix_multiplication( _core_comp, *_u1_comp, *_u2_comp, *_u3_comp, data );
518 if( (
sizeof(T_value) == 1) || (
sizeof(T_value) == 2) ){
519 data_.float_t_to_uint_t( data );
521 data_.cast_from( data );
527 template<
typename T_init>
529 VMML_TEMPLATE_CLASSNAME::decompose(
const t3_type& data_, T_init init )
532 tucker_als( data_, init );
536 template<
typename T_init>
538 VMML_TEMPLATE_CLASSNAME::decompose(
const t3_type& data_,
539 T_internal& u1_min_, T_internal& u1_max_,
540 T_internal& u2_min_, T_internal& u2_max_,
541 T_internal& u3_min_, T_internal& u3_max_,
542 T_internal& core_min_, T_internal& core_max_,
546 decompose( data_, init );
548 quantize_basis_matrices( u1_min_, u1_max_, u2_min_, u2_max_, u3_min_, u3_max_ );
549 quantize_core(core_min_, core_max_ );
553 template<
typename T_init>
555 VMML_TEMPLATE_CLASSNAME::decompose(
const t3_type& data_,
556 T_internal& u_min_, T_internal& u_max_,
557 T_internal& core_min_, T_internal& core_max_,
561 decompose( data_, init );
563 quantize_basis_matrices( u_min_, u_max_ );
564 quantize_core(core_min_, core_max_ );
569 template<
typename T_init >
571 VMML_TEMPLATE_CLASSNAME::tucker_als(
const t3_type& data_, T_init init )
574 data.cast_from( data_ );
576 typedef t3_hooi< R1, R2, R3, I1, I2, I3, T_internal > hooi_type;
577 hooi_type::als( data, *_u1_comp, *_u2_comp, *_u3_comp, _core_comp, init );
586 VMML_TEMPLATE_CLASSNAME::nnz()
const
590 counter += _u1_comp->nnz();
591 counter += _u2_comp->nnz();
592 counter += _u3_comp->nnz();
593 counter += _core_comp.nnz();
600 VMML_TEMPLATE_CLASSNAME::nnz(
const T_value& threshold )
const
604 counter += _u1_comp->nnz( threshold );
605 counter += _u2_comp->nnz( threshold );
606 counter += _u3_comp->nnz( threshold );
607 counter += _core_comp.nnz( threshold );
613 #undef VMML_TEMPLATE_STRING
614 #undef VMML_TEMPLATE_CLASSNAME