55 #ifndef __VMML__CP3_TENSOR__HPP__
56 #define __VMML__CP3_TENSOR__HPP__
58 #include <vmmlib/matrix_pseudoinverse.hpp>
59 #include <vmmlib/t3_hopm.hpp>
60 #include <vmmlib/t3_ihopm.hpp>
61 #include <vmmlib/tensor3_iterator.hpp>
66 template<
size_t R,
size_t I1,
size_t I2,
size_t I3,
67 typename T_value = double,
typename T_coeff =
float >
71 typedef float T_internal;
84 typedef typename u1_type::iterator u1_iterator;
85 typedef typename u1_type::const_iterator u1_const_iterator;
88 typedef typename u2_type::iterator u2_iterator;
89 typedef typename u2_type::const_iterator u2_const_iterator;
92 typedef typename u3_type::iterator u3_iterator;
93 typedef typename u3_type::const_iterator u3_const_iterator;
110 void get_u1(
u1_type& U1)
const {
114 void get_u2(
u2_type& U2)
const {
118 void get_u3(
u3_type& U3)
const {
124 _lambdas_comp->cast_from(lambdas);
129 _u1_comp->cast_from(U1);
134 _u1_comp->cast_from(U2);
139 _u1_comp->cast_from(U3);
143 *_lambdas_comp = lambdas;
144 _lambdas->cast_from(lambdas);
163 data_ = _lambdas_comp;
178 void export_to(std::vector< T_coeff >& data_)
const;
179 void import_from(std::vector< T_coeff >& data_);
180 void reconstruct(
t3_type& data_)
const;
181 double error(
t3_type& data_)
const;
184 template<
typename T_init >
185 tensor_stats decompose(
const t3_type& data_, T_init init,
const size_t max_iterations_ = 50,
const float tolerance = 1e-04);
187 template<
typename T_init >
188 tensor_stats cp_als(
const t3_type& data_, T_init init,
const size_t max_iterations_ = 50,
const float tolerance = 1e-04);
190 template<
size_t NBLOCKS,
typename T_init >
191 tensor_stats i_cp_als(
const t3_type& data_, T_init init,
const size_t max_iterations_ = 50,
const float tolerance = 1e-04);
201 cp3_tensor< R, I1, I1, I1, T_value, T_coeff > operator=(
const cp3_tensor< R, I1, I1, I1, T_value, T_coeff >& ) {
206 friend std::ostream& operator <<(std::ostream& os,
const cp3_type& dec_ ) {
208 dec_.get_lambdas(lambdas);
216 os <<
"U1: " << std::endl << *u1 << std::endl
217 <<
"U2: " << std::endl << *u2 << std::endl
218 <<
"U3: " << std::endl << *u3 << std::endl
219 <<
"lambdas: " << std::endl << lambdas << std::endl;
228 void cast_comp_members();
245 #define VMML_TEMPLATE_STRING template< size_t R, size_t I1, size_t I2, size_t I3, typename T_value, typename T_coeff >
246 #define VMML_TEMPLATE_CLASSNAME cp3_tensor< R, I1, I2, I3, T_value, T_coeff >
249 VMML_TEMPLATE_CLASSNAME::cp3_tensor(u1_type& U1, u2_type& U2, u3_type& U3, lambda_type& lambdas_) {
250 set_lambdas(lambdas_);
257 VMML_TEMPLATE_CLASSNAME::cp3_tensor() {
258 _lambdas =
new vector< R, T_coeff > ();
266 _lambdas_comp =
new vector< R, T_internal>;
267 _lambdas_comp->set(0);
268 _u1_comp =
new u1_comp_type;
270 _u2_comp =
new u2_comp_type;
272 _u3_comp =
new u3_comp_type;
277 VMML_TEMPLATE_CLASSNAME::~cp3_tensor() {
285 delete _lambdas_comp;
290 VMML_TEMPLATE_CLASSNAME::cast_members() {
291 _u1->cast_from(*_u1_comp);
292 _u2->cast_from(*_u2_comp);
293 _u3->cast_from(*_u3_comp);
294 _lambdas->cast_from(*_lambdas_comp);
299 VMML_TEMPLATE_CLASSNAME::cast_comp_members() {
300 _u1_comp->cast_from(*_u1);
301 _u2_comp->cast_from(*_u2);
302 _u3_comp->cast_from(*_u3);
303 _lambdas_comp->cast_from(_lambdas);
308 VMML_TEMPLATE_CLASSNAME::reconstruct(t3_type& data_)
const {
312 data.cast_from(data_);
314 typedef t3_hopm< R, I1, I2, I3, T_internal > hopm_type;
315 hopm_type::reconstruct(data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp);
318 if ((
sizeof (T_value) == 1) || (
sizeof (T_value) == 2)) {
319 data_.float_t_to_uint_t(data);
321 data_.cast_from(data);
328 VMML_TEMPLATE_CLASSNAME::error(t3_type& original)
const {
329 typedef t3_hopm< R, I1, I2, I3, T_internal > hopm_type;
331 hopm_type::reconstruct(data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp);
332 double err = data.frobenius_norm(original) / original.frobenius_norm() * 100;
337 template<
typename T_init >
339 VMML_TEMPLATE_CLASSNAME::decompose(
const t3_type& data_, T_init init,
const size_t max_iterations_,
const float tolerance) {
340 return cp_als(data_, init, max_iterations_, tolerance );
344 template<
typename T_init >
346 VMML_TEMPLATE_CLASSNAME::cp_als(
const t3_type& data_, T_init init,
const size_t max_iterations_,
const float tolerance) {
350 data.cast_from(data_);
352 typedef t3_hopm< R, I1, I2, I3, T_internal > hopm_type;
353 result += hopm_type::als(data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp, init, max_iterations_, tolerance);
360 template<
size_t NBLOCKS,
typename T_init >
362 VMML_TEMPLATE_CLASSNAME::i_cp_als(
const t3_type& data_, T_init init,
const size_t max_iterations_,
const float tolerance) {
366 data.cast_from(data_);
368 typedef t3_ihopm< R, NBLOCKS, I1, I2, I3, T_internal > ihopm_type;
369 result += ihopm_type::incremental_als(data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp, init, max_iterations_, tolerance);
380 VMML_TEMPLATE_CLASSNAME::reduce_ranks(
const cp3_tensor< K, I1, I2, I3, T_value, T_coeff >& other)
386 matrix< I1, K, T_coeff >* u1 =
new matrix< I1, K, T_coeff > ();
388 matrix< I2, K, T_coeff >* u2 =
new matrix< I2, K, T_coeff > ();
390 matrix< I3, K, T_coeff >* u3 =
new matrix< I3, K, T_coeff > ();
392 for (
size_t r = 0; r < R; ++r) {
393 _u1->set_column(r, u1->get_column(r));
394 _u2->set_column(r, u2->get_column(r));
395 _u3->set_column(r, u3->get_column(r));
398 vector< K, T_coeff >* lambdas;
399 other.get_lambdas(lambdas);
400 _lambdas_comp->set(lambdas);
411 VMML_TEMPLATE_CLASSNAME::export_to(std::vector< T_coeff >& data_)
const {
412 u1_const_iterator it = _u1->begin(),
414 for (; it != it_end; ++it) {
415 data_.push_back(*it);
418 u2_const_iterator u2_it = _u2->begin(),
419 u2_it_end = _u2->end();
420 for (; u2_it != u2_it_end; ++u2_it) {
421 data_.push_back(*u2_it);
424 u3_const_iterator u3_it = _u3->begin(),
425 u3_it_end = _u3->end();
426 for (; u3_it != u3_it_end; ++u3_it) {
427 data_.push_back(*u3_it);
435 VMML_TEMPLATE_CLASSNAME::import_from(std::vector< T_coeff >& data_) {
438 u1_iterator it = _u1->begin(),
440 for (; it != it_end; ++it, ++i) {
444 u2_iterator u2_it = _u2->begin(),
445 u2_it_end = _u2->end();
446 for (; u2_it != u2_it_end; ++u2_it, ++i) {
447 *u2_it = data_.at(i);
450 u3_iterator u3_it = _u3->begin(),
451 u3_it_end = _u3->end();
452 for (; u3_it != u3_it_end; ++u3_it, ++i) {
453 *u3_it = data_.at(i);
462 VMML_TEMPLATE_CLASSNAME::nnz()
const {
465 counter += _u1_comp->nnz();
466 counter += _u2_comp->nnz();
467 counter += _u3_comp->nnz();
468 counter += _lambdas_comp->nnz();
473 #undef VMML_TEMPLATE_STRING
474 #undef VMML_TEMPLATE_CLASSNAME