37 #ifndef __INCLUDE_MIST_TENSOR__
38 #define __INCLUDE_MIST_TENSOR__
40 #ifndef __INCLUDE_MIST_H__
44 #ifndef __INCLUDE_MIST_MATRIX__
48 #ifndef __INCLUDE_NUMERIC__
60 template<
int M,
typename V,
typename A >
65 template<
int M,
typename V,
typename A >
72 typedef matrix< V, A > matrix_type;
75 array< size_type > _ranks;
76 array< value_type, allocator > _data;
78 template<
typename MV,
typename MA >
79 void _fold(
const size_type &m,
const matrix< MV, MA > &mat )
81 array< size_type > i( _mode ), d( _mode );
82 for( size_type ii = 0 ; ii < _mode ; d[ ii ] = _diff( ii ), ii ++ );
83 for(
typename matrix_type::size_type c = 0 ; c < mat.cols( ) ; c ++ )
85 for(
typename matrix_type::size_type r = i[ m - 1 ] = 0 ; r < mat.rows( ) ; r ++, i[ m - 1 ] ++ )
87 operator [ ]( ::std::inner_product( &i[ 0 ], &i[ 0 ] + i.size( ), &d[ 0 ], 0 ) ) = mat( r, c );
89 _inc( m % _mode, m - 1, i );
94 size_type _diff(
const size_type &i )
const
96 return i == 0 ? 1 : _ranks[ i - 1 ] * _diff( i - 1 );
98 void _inc(
const size_type &m,
const size_type &em, array< size_type > &i )
const
100 if( m != em && ++ i[ m ] == _ranks[ m ] )
103 _inc( ( m + 1 ) % _mode, em, i );
106 void _out( ::std::ostream &o,
const array< size_type > &d, array< size_type > &i,
const size_type &m )
const
108 for( i[ m ] = 0 ; i[ m ] < _ranks[ m ] ; i[ m ] ++ )
112 i[ m ] != 0 ? o << std::endl : o;
113 for( size_type ii = 0 ; ii < _mode - m - 1 ; o <<
" ", ii ++ );
114 m > 1 ? o << i[ m ] + 1 <<
" ----------" << ::std::endl : o;
115 _out( o, d, i, m - 1 );
119 o << operator [ ]( ::std::inner_product( &i[ 0 ], &i[ 0 ] + _mode, &d[ 0 ], 0 ) );
120 i[ m ] != _ranks[ m ] - 1 ? o <<
", " : o;
126 const size_type mode( )
const
130 const size_type rank(
const size_type &m )
const
132 return _ranks[ m - 1 ];
134 const size_type size( )
const
136 return _data.size( );
138 value_type &operator [ ](
const size_type &i )
142 const value_type &operator [ ](
const size_type &i )
const
146 matrix_type unfold(
const size_type &m )
const
148 array< size_type > i( _mode ), d( _mode );
149 for( size_type ii = 0 ; ii < _mode ; d[ ii ] = _diff( ii ), ii ++ );
150 matrix_type mat( _ranks[ m - 1 ], _data.size( ) / _ranks[ m - 1 ] );
151 for(
typename matrix_type::size_type c = 0 ; c < mat.cols( ) ; c ++ )
153 for(
typename matrix_type::size_type r = i[ m - 1 ] = 0 ; r < mat.rows( ) ; r ++, i[ m - 1 ] ++ )
155 mat( r, c ) = operator [ ]( ::std::inner_product( &i[ 0 ], &i[ 0 ] + i.size( ), &d[ 0 ], 0 ) );
157 _inc( m % _mode, m - 1, i );
161 void out( ::std::ostream &o )
const
163 array< size_type > i( _mode ), d( _mode );
164 for( size_type ii = 0 ; ii < _mode ; d[ ii ] = _diff( ii ), ii ++ );
165 _out( o, d, i, _mode - 1 );
168 _base_( ) : _mode( M ), _ranks( array< size_type >( M ) )
173 template<
int M,
typename V,
typename A >
174 class _data_ :
public _base_< M, V, A >
186 template<
typename V,
typename A >
187 class _data_< 2, V, A >
189 template<
int FM,
typename FV,
typename FA >
192 typedef V value_type;
194 typedef matrix< V, A > matrix_type;
195 typedef typename matrix_type::size_type size_type;
199 const size_type mode( )
const
203 const size_type rank(
const size_type &m )
const
205 return m == 1 ? _mat.rows( ) : _mat.cols( );
207 const size_type size( )
const
211 void _resize(
const size_type &r1,
const size_type &r2 )
213 _mat.resize( r1, r2 );
215 void resize(
const size_type &r1,
const size_type &r2 )
220 value_type &operator [ ](
const size_type &i )
224 const value_type &operator [ ](
const size_type &i )
const
228 value_type &operator ( )(
const size_type &i1,
const size_type &i2 )
230 return _mat( i1, i2 );
232 const value_type &operator ( )(
const size_type &i1,
const size_type &i2 )
const
234 return _mat( i1, i2 );
236 template<
typename MV,
typename MA >
237 _data_< 2, V, A > fold(
const size_type &m,
const matrix< MV, MA > &mat )
const
239 return _data_< 2, V, A >( m == 1 ? mat : mat.t( ) );
241 matrix_type unfold(
const size_type &m )
const
243 return m == 1 ? _mat : _mat.t( );
245 void out( ::std::ostream &o )
const
249 template<
typename AV,
typename AA >
250 _data_< 2, V, A >(
const size_t &r1,
const size_t &r2,
const array< AV, AA > &data ) : _mat( matrix_type( r1, r2 ) )
252 ::std::copy( &data[ 0 ], &data[ 0 ] + data.size( ), &_mat[ 0 ] );
254 template<
typename AV,
typename AA >
255 _data_< 2, V, A >(
const array2< AV, AA > &img ) : _mat( matrix_type( img.width( ), img.height( ) ) )
257 ::std::copy( &img[ 0 ], &img[ 0 ] + img.size( ), &_mat[ 0 ] );
259 template<
typename MV,
typename MA >
260 _data_< 2, V, A >(
const matrix< MV, MA > &mat ) : _mat( mat )
263 _data_< 2, V, A >(
const size_type &r1,
const size_type &r2 ) : _mat( matrix_type( r1, r2 ) )
266 _data_< 2, V, A >( ) : _mat( matrix_type( ) )
276 template<
typename V,
typename A >
277 class _data_< 3, V, A > :
public _base_< 3, V, A >
279 template<
int FM,
typename FV,
typename FA >
282 typedef _base_< 3, V, A > base;
283 typedef typename base::value_type value_type;
284 typedef typename base::size_type size_type;
286 void _resize(
const size_type &r1,
const size_type &r2,
const size_type &r3 )
288 if( base::_ranks[ 0 ] != r1 || base::_ranks[ 1 ] != r2 || base::_ranks[ 2 ] != r3 )
290 base::_ranks[ 0 ] = r1;
291 base::_ranks[ 1 ] = r2;
292 base::_ranks[ 2 ] = r3;
293 base::_data.resize( r1 * r2 * r3 );
296 void resize(
const size_type &r1,
const size_type &r2,
const size_type &r3 )
298 _resize( r1, r2, r3 );
301 value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3 )
303 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] ];
305 const value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3 )
const
307 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] ];
309 template<
typename MV,
typename MA >
310 _data_< 3, V, A > fold(
const size_type &m,
const matrix< MV, MA > &mat )
const
312 _data_< 3, V, A > ret( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ] );
313 ret._ranks[ m - 1 ] = mat.rows( );
314 ret._resize( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ] );
318 template<
typename AV,
typename AA >
319 _data_< 3, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const array< AV, AA > &data )
321 _resize( r1, r2, r3 );
322 ::std::copy( &data[ 0 ], &data[ 0 ] + data.size( ), &base::_data[ 0 ] );
324 _data_< 3, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3 )
326 _resize( r1, r2, r3 );
328 template<
typename TV,
typename TA,
typename AA >
329 _data_< 3, V, A >(
const array< tensor< 2, TV, TA >, AA > &ts )
331 _resize( ts[ 0 ].rank( 1 ), ts[ 0 ].rank( 2 ), ts.size( ) );
332 for( size_type i = 0 ; i < ts.size( ) ; i ++ )
334 ::std::copy( &ts[ i ][ 0 ], &ts[ i ][ 0 ] + ts[ 0 ].size( ), &base::_data[ i * ts[ 0 ].size( ) ] );
347 template<
typename V,
typename A >
348 class _data_< 4, V, A > :
public _base_< 4, V, A >
350 template<
int FM,
typename FV,
typename FA >
353 typedef _base_< 4, V, A > base;
354 typedef typename base::value_type value_type;
355 typedef typename base::size_type size_type;
357 void _resize(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4 )
359 if( base::_ranks[ 0 ] != r1 || base::_ranks[ 1 ] != r2 || base::_ranks[ 2 ] != r3 || base::_ranks[ 3 ] != r4 )
361 base::_ranks[ 0 ] = r1;
362 base::_ranks[ 1 ] = r2;
363 base::_ranks[ 2 ] = r3;
364 base::_ranks[ 3 ] = r4;
365 base::_data.resize( r1 * r2 * r3 * r4 );
368 void resize(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4 )
370 _resize( r1, r2, r3, r4 );
373 value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3,
const size_type &i4 )
375 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] + i4 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] ];
377 const value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3,
const size_type &i4 )
const
379 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] + i4 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] ];
381 template<
typename MV,
typename MA >
382 _data_< 4, V, A > fold(
const size_type &m,
const matrix< MV, MA > &mat )
const
384 _data_< 4, V, A > ret( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ], base::_ranks[ 3 ] );
385 ret.base::_ranks[ m - 1 ] = mat.rows( );
386 ret._resize( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ], base::_ranks[ 3 ] );
390 template<
typename AV,
typename AA >
391 _data_< 4, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4,
const array< AV, AA > &data )
393 _resize( r1, r2, r3, r4 );
394 ::std::copy( &data[ 0 ], &data[ 0 ] + data.size( ), &base::_data[ 0 ] );
396 _data_< 4, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4 )
398 _resize( r1, r2, r3, r4 );
400 template<
typename TV,
typename TA,
typename AA >
401 _data_< 4, V, A >(
const array< tensor< 3, TV, TA >, AA > &ts )
403 _resize( ts[ 0 ].rank( 1 ), ts[ 0 ].rank( 2 ), ts[ 0 ].rank( 3 ), ts.size( ) );
404 for( size_type i = 0 ; i < ts.size( ) ; i ++ )
406 ::std::copy( &ts[ i ][ 0 ], &ts[ i ][ 0 ] + ts[ 0 ].size( ), &base::_data[ i * ts[ 0 ].size( ) ] );
419 template<
typename V,
typename A >
420 class _data_< 5, V, A > :
public _base_< 5, V, A >
422 template<
int FM,
typename FV,
typename FA >
425 typedef _base_< 5, V, A > base;
426 typedef typename base::value_type value_type;
427 typedef typename base::size_type size_type;
429 void _resize(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4,
const size_type &r5 )
431 if( base::_ranks[ 0 ] != r1 || base::_ranks[ 1 ] != r2 || base::_ranks[ 2 ] != r3 || base::_ranks[ 3 ] != r4 || base::_ranks[ 4 ] != r5 )
433 base::_ranks[ 0 ] = r1;
434 base::_ranks[ 1 ] = r2;
435 base::_ranks[ 2 ] = r3;
436 base::_ranks[ 3 ] = r4;
437 base::_ranks[ 4 ] = r5;
438 base::_data.resize( r1 * r2 * r3 * r4 * r5 );
441 void resize(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4,
const size_type &r5 )
443 _resize( r1, r2, r3, r4, r5 );
446 value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3,
const size_type &i4,
const size_type &i5 )
448 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] + i4 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] + i5 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] * base::_ranks[ 3 ] ];
450 const value_type &operator ( )(
const size_type &i1,
const size_type &i2,
const size_type &i3,
const size_type &i4,
const size_type &i5 )
const
452 return base::_data[ i1 + i2 * base::_ranks[ 0 ] + i3 * base::_ranks[ 0 ] * base::_ranks[ 1 ] + i4 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] + i5 * base::_ranks[ 0 ] * base::_ranks[ 1 ] * base::_ranks[ 2 ] * base::_ranks[ 3 ] ];
454 template<
typename MV,
typename MA >
455 _data_< 5, V, A > fold(
const size_type &m,
const matrix< MV, MA > &mat )
const
457 _data_< 5, V, A > ret( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ], base::_ranks[ 3 ], base::_ranks[ 4 ] );
458 ret.base::_ranks[ m - 1 ] = mat.rows( );
459 ret._resize( base::_ranks[ 0 ], base::_ranks[ 1 ], base::_ranks[ 2 ], base::_ranks[ 3 ], base::_ranks[ 4 ] );
463 template<
typename AV,
typename AA >
464 _data_< 5, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4,
const size_type &r5,
const array< AV, AA > &data )
466 _resize( r1, r2, r3, r4, r5 );
467 ::std::copy( &data[ 0 ], &data[ 0 ] + data.size( ), &base::_data[ 0 ] );
469 _data_< 5, V, A >(
const size_type &r1,
const size_type &r2,
const size_type &r3,
const size_type &r4,
const size_type &r5 )
471 _resize( r1, r2, r3, r4, r5 );
473 template<
typename TV,
typename TA,
typename AA >
474 _data_< 5, V, A >(
const array< tensor< 4, TV, TA >, AA > &ts )
476 _resize( ts[ 0 ].rank( 1 ), ts[ 0 ].rank( 2 ), ts[ 0 ].rank( 3 ), ts[ 0 ].rank( 4 ), ts.size( ) );
477 for( size_type i = 0 ; i < ts.size( ) ; i ++ )
479 ::std::copy( &ts[ i ][ 0 ], &ts[ i ][ 0 ] + ts[ 0 ].size( ), &base::_data[ i * ts[ 0 ].size( ) ] );
497 template<
int M,
typename V,
typename A = ::std::allocator< V > >
501 typedef typename __tensor__::_data_< M, V, A > data_type;
511 bool _is_valid(
const size_type &m )
const
513 return 0 < m && m <= mode( );
515 template<
typename TV,
typename TA >
518 for( size_type i = 1 ; i <= mode( ) ; i ++ )
520 if( rank( i ) != t.
rank( i ) )
527 template<
typename MV,
typename MA >
528 tensor< M, V, A > _fold(
const size_type &m,
const matrix< MV, MA > &mat )
const
530 tensor< M, V, A > ret;
531 ret._d = _d.fold( m, mat );
534 matrix_type _unfold(
const size_type &m )
const
536 return _d.unfold( m );
538 template<
typename MV,
typename MA >
539 tensor< M, V, A > _x(
const size_type &m,
const matrix< MV, MA > &mat )
const
541 return _fold( m, mat * _unfold( m ) );
557 if( _is_valid( mode ) )
559 return _d.rank( mode );
563 ::std::cerr <<
"can't obtain rank" << ::std::endl;
602 if( _is_valid( mode ) )
604 return _unfold( mode );
608 ::std::cerr <<
"can't unfold tensor" << ::std::endl;
620 template<
typename MV,
typename MA >
623 if( _is_valid( mode ) )
625 return _x( mode, mat );
629 ::std::cerr <<
"can't obtain n-mode product" << ::std::endl;
633 void out( ::std::ostream &o )
const
638 template<
typename TV,
typename TA >
641 if( !_is_same_size( t ) )
647 for(
size_type i = 0 ; i < size( ) ; i ++ )
649 if(
operator [ ]( i ) != t[ i ] )
658 template<
typename TV,
typename TA >
661 return !operator ==( t );
664 template<
typename TV,
typename TA >
667 if( _is_same_size( t ) )
669 ::std::transform( &
operator [ ]( 0 ), &
operator [ ]( 0 ) + size( ), &t[ 0 ], &
operator [ ]( 0 ), ::std::plus< value_type >( ) );
673 ::std::cerr <<
"can't add tensors" << ::std::endl;
678 template<
typename TV,
typename TA >
681 if( _is_same_size( t ) )
683 ::std::transform( &
operator [ ]( 0 ), &
operator [ ]( 0 ) + size( ), &t[ 0 ], &
operator [ ]( 0 ), ::std::minus< value_type >( ) );
687 ::std::cerr <<
"can't subtract tensors" << ::std::endl;
692 template<
typename VV >
695 ::std::transform( &
operator [ ]( 0 ), &
operator [ ]( 0 ) + size( ), &
operator [ ]( 0 ), ::std::bind2nd( ::std::multiplies< value_type >( ), v ) );
699 template<
typename VV >
702 ::std::transform( &
operator [ ]( 0 ), &
operator [ ]( 0 ) + size( ), &
operator [ ]( 0 ), ::std::bind2nd( ::std::divides< value_type >( ), v ) );
724 _d.resize( rank1, rank2 );
757 template<
typename MV,
typename MA >
761 svd( _unfold( 1 ), u1, s, u2 );
762 z = _x( 1, u1.
dagger( ) )._x( 2, u2 );
771 template<
typename AV,
typename AA >
781 template<
typename AV,
typename AA >
791 template<
typename MV,
typename MA >
819 _d.resize( rank1, rank2, rank3 );
830 return _d( i1, i2, i3 );
841 return _d( i1, i2, i3 );
853 template<
typename MV,
typename MA >
857 svd( _unfold( 1 ), u1, s, tmp );
858 svd( _unfold( 2 ), u2, s, tmp );
859 svd( _unfold( 3 ), u3, s, tmp );
869 template<
typename AV,
typename AA >
886 template<
typename TV,
typename TA,
typename AA >
907 _d.resize( rank1, rank2, rank3, rank4 );
919 return _d( i1, i2, i3, i4 );
931 return _d( i1, i2, i3, i4 );
944 template<
typename MV,
typename MA >
945 void hosvd(
tensor< M, V, A > &z,
matrix< MV, MA > &u1,
matrix< MV, MA > &u2,
matrix< MV, MA > &u3,
matrix< MV, MA > &u4 )
const
948 svd( _unfold( 1 ), u1, s, tmp );
949 svd( _unfold( 2 ), u2, s, tmp );
950 svd( _unfold( 3 ), u3, s, tmp );
951 svd( _unfold( 4 ), u4, s, tmp );
962 template<
typename AV,
typename AA >
963 tensor< M, V, A >(
const size_type &rank1,
const size_type &rank2,
const size_type &rank3,
const size_type &rank4,
const array< AV, AA > &data ) : _d( rank1, rank2, rank3, rank4, data )
980 template<
typename TV,
typename TA,
typename AA >
1002 _d.resize( rank1, rank2, rank3, rank4, rank5 );
1015 return _d( i1, i2, i3, i4, i5 );
1028 return _d( i1, i2, i3, i4, i5 );
1042 template<
typename MV,
typename MA >
1043 void hosvd(
tensor< M, V, A > &z,
matrix< MV, MA > &u1,
matrix< MV, MA > &u2,
matrix< MV, MA > &u3,
matrix< MV, MA > &u4,
matrix< MV, MA > &u5 )
const
1046 svd( _unfold( 1 ), u1, s, tmp );
1047 svd( _unfold( 2 ), u2, s, tmp );
1048 svd( _unfold( 3 ), u3, s, tmp );
1049 svd( _unfold( 4 ), u4, s, tmp );
1050 svd( _unfold( 5 ), u5, s, tmp );
1062 template<
typename AV,
typename AA >
1063 tensor< M, V, A >(
const size_type &rank1,
const size_type &rank2,
const size_type &rank3,
const size_type &rank4,
const size_type &rank5,
const array< AV, AA > &data ) : _d( rank1, rank2, rank3, rank4, rank5, data )
1074 tensor< M, V, A >(
const size_type &rank1,
const size_type &rank2,
const size_type &rank3,
const size_type &rank4,
const size_type &rank5 ) : _d( rank1, rank2, rank3, rank4, rank5 )
1081 template<
typename TV,
typename TA,
typename AA >
1094 template<
int M,
typename V,
typename A >
1106 template<
int M,
typename V,
typename A >
1118 template<
int M,
typename V,
typename A >
1130 template<
int M,
typename V,
typename A >
1142 template<
int M,
typename V,
typename A >
1154 template <
int M,
typename V,
typename A >
1155 inline ::std::ostream &operator <<( ::std::ostream &o, const tensor< M, V, A > &t )
1180 template<
typename TV,
typename TA,
typename MV,
typename MA >
1183 t.
hosvd( z, u1, u2 );
1204 template<
typename TV,
typename TA,
typename MV,
typename MA >
1205 inline void hosvd(
const tensor< 3, TV, TA > &t,
tensor< 3, TV, TA > &z,
matrix< MV, MA > &u1,
matrix< MV, MA > &u2,
matrix< MV, MA > &u3 )
1207 t.
hosvd( z, u1, u2, u3 );
1229 template<
typename TV,
typename TA,
typename MV,
typename MA >
1230 inline void hosvd(
const tensor< 4, TV, TA > &t,
tensor< 4, TV, TA > &z,
matrix< MV, MA > &u1,
matrix< MV, MA > &u2,
matrix< MV, MA > &u3,
matrix< MV, MA > &u4 )
1232 t.
hosvd( z, u1, u2, u3, u4 );
1255 template<
typename TV,
typename TA,
typename MV,
typename MA >
1256 inline void hosvd(
const tensor< 5, TV, TA > &t,
tensor< 5, TV, TA > &z,
matrix< MV, MA > &u1,
matrix< MV, MA > &u2,
matrix< MV, MA > &u3,
matrix< MV, MA > &u4,
matrix< MV, MA > &u5 )
1258 t.
hosvd( z, u1, u2, u3, u4, u5 );
1265 #endif // __INCLUDE_MIST_TENSOR__