~ubuntu-branches/ubuntu/trusty/repsnapper/trusty

« back to all changes in this revision

Viewing changes to libraries/vmmlib/include/vmmlib/cp3_tensor.hpp

  • Committer: Package Import Robot
  • Author(s): Ying-Chun Liu (PaulLiu)
  • Date: 2012-09-08 21:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20120908212826-x5opjslz0fna5jq3
Tags: upstream-0+git20120902.349ce298
ImportĀ upstreamĀ versionĀ 0+git20120902.349ce298

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * VMMLib - Tensor Classes
 
3
 *  
 
4
 * @author Susanne Suter
 
5
 * @author Jonas Boesch
 
6
 *
 
7
 * The cp3 tensor class is consists of three basis matrices u1-u3 and R lambda values for a given rank-R approximation
 
8
 * CP stands for Candecomp/Parafac (1970)
 
9
 * - Carroll & Chang, 1970: Analysis of Individual Differences in Multidimensional Scaling via an N-way generalization of ``Eckart--Young'' decompositions, Psychometrika.
 
10
 * - Harshman, 1970: Foundations of the PARAFAC procedure: Models and conditions for an 'explanatory' multi-modal factor analysis,UCLA Working Papers in Phonetics.
 
11
 * - De Lathauwer, De Moor, Vandewalle, 2000: A multilinear singular value decomposition, SIAM J. Matrix Anal. Appl.
 
12
 * - Kolda & Bader, 2009: Tensor Decompositions and Applications, SIAM Review.
 
13
 * 
 
14
 */
 
15
 
 
16
#ifndef __VMML__CP3_TENSOR__HPP__
 
17
#define __VMML__CP3_TENSOR__HPP__
 
18
 
 
19
#include <vmmlib/t3_hopm.hpp>
 
20
#include <vmmlib/tensor3_iterator.hpp>
 
21
#include <vmmlib/matrix_pseudoinverse.hpp>
 
22
 
 
23
namespace vmml
 
24
{
 
25
        
 
26
        template< size_t R, size_t I1, size_t I2, size_t I3, typename T_value = float, typename T_coeff = float >
 
27
        class cp3_tensor
 
28
        {
 
29
        public:                 
 
30
                typedef float T_internal;       
 
31
 
 
32
                typedef tensor3< I1, I2, I3, T_value > t3_type;
 
33
                typedef typename t3_type::iterator t3_iterator;
 
34
                typedef typename t3_type::const_iterator t3_const_iterator;
 
35
                
 
36
                typedef tensor3< I1, I2, I3, T_internal > t3_comp_type;
 
37
                
 
38
                typedef tensor3< I1, I2, I3, T_coeff > t3_coeff_type;
 
39
                typedef typename t3_coeff_type::iterator t3_coeff_iterator;
 
40
                typedef typename t3_coeff_type::const_iterator t3_coeff_const_iterator;
 
41
                
 
42
                typedef matrix< I1, R, T_coeff > u1_type;
 
43
                typedef typename u1_type::iterator u1_iterator;
 
44
                typedef typename u1_type::const_iterator u1_const_iterator;
 
45
                
 
46
                typedef matrix< I2, R, T_coeff > u2_type;
 
47
                typedef typename u2_type::iterator u2_iterator;
 
48
                typedef typename u2_type::const_iterator u2_const_iterator;
 
49
                
 
50
                typedef matrix< I3, R, T_coeff > u3_type;
 
51
                typedef typename u3_type::iterator u3_iterator;
 
52
                typedef typename u3_type::const_iterator u3_const_iterator;
 
53
                
 
54
                typedef matrix< I1, R, T_internal > u1_comp_type;
 
55
                typedef matrix< I2, R, T_internal > u2_comp_type;
 
56
                typedef matrix< I3, R, T_internal > u3_comp_type;
 
57
                
 
58
                typedef vector< R, T_internal > lambda_comp_type;
 
59
                typedef vector< R, T_coeff > lambda_type;
 
60
 
 
61
                cp3_tensor(  u1_type& U1, u2_type& U2, u3_type& U3, lambda_type& lambdas_ );
 
62
                cp3_tensor();
 
63
                ~cp3_tensor();
 
64
                
 
65
                void get_lambdas( lambda_type& data_ ) const { data_  = *_lambdas; } ;
 
66
                void get_u1( u1_type& U1 ) const { U1 = *_u1; } ;
 
67
                void get_u2( u2_type& U2 ) const { U2 = *_u2; } ;
 
68
                void get_u3( u3_type& U3 ) const { U3 = *_u3; } ;
 
69
                
 
70
                void set_core( const lambda_type& lambdas_ )  { _lambdas = lambda_type( lambdas_ ); _lambdas_comp.cast_from( _lambdas ); } ;
 
71
                void set_u1( u1_type& U1 ) { *_u1 = U1; _u1_comp->cast_from( U1 ); } ;
 
72
                void set_u2( u2_type& U2 ) { *_u2 = U2; _u1_comp->cast_from( U2 ); } ;
 
73
                void set_u3( u3_type& U3 ) { *_u3 = U3; _u1_comp->cast_from( U3 ); } ;
 
74
                
 
75
                void set_lambda_comp( lambda_comp_type& lambdas_ )  { _lambdas_comp = lambda_comp_type( lambdas_ ); _lambdas.cast_from( _lambdas_comp ); } ;
 
76
                void set_u1_comp( u1_comp_type& U1 ) { *_u1_comp = U1; _u1->cast_from( U1 ); } ;
 
77
                void set_u2_comp( u2_comp_type& U2 ) { *_u2_comp = U2; _u1->cast_from( U2 ); } ;
 
78
                void set_u3_comp( u3_comp_type& U3 ) { *_u3_comp = U3; _u1->cast_from( U3 ); } ;
 
79
                
 
80
                void get_lambda_comp( lambda_comp_type& data_ ) const { data_ = _lambdas_comp; } ;
 
81
                void get_u1_comp( u1_comp_type& U1 ) const { U1 = *_u1_comp; } ;
 
82
                void get_u2_comp( u2_comp_type& U2 ) const { U2 = *_u2_comp; } ;
 
83
                void get_u3_comp( u3_comp_type& U3 ) const { U3 = *_u3_comp; } ;
 
84
                
 
85
                void export_to( std::vector< T_coeff >& data_ ) const;
 
86
                void import_from( std::vector< T_coeff >& data_ );      
 
87
                
 
88
                void reconstruct( t3_type& data_ ) const;
 
89
                template< typename T_init >
 
90
                void decompose( const t3_type& data_, T_init init, const size_t max_iterations_ = 100 ); 
 
91
                template< typename T_init >
 
92
                void cp_als( const t3_type& data_, T_init init, const size_t max_iterations_ = 100 );
 
93
                
 
94
                size_t nnz() const;
 
95
                
 
96
        protected:
 
97
                cp3_tensor( const cp3_tensor< R, I1, I1, I1, T_value, T_coeff >& other ) {};
 
98
                cp3_tensor< R, I1, I1, I1, T_value, T_coeff > operator=( const cp3_tensor< R, I1, I1, I1, T_value, T_coeff >& other ) { return *this; };
 
99
 
 
100
        void cast_members();
 
101
        void cast_comp_members();
 
102
                
 
103
        private:
 
104
                lambda_type* _lambdas ;
 
105
                u1_type* _u1 ;
 
106
                u2_type* _u2 ;
 
107
                u3_type* _u3 ;
 
108
                
 
109
        lambda_comp_type* _lambdas_comp ;
 
110
        u1_comp_type* _u1_comp ;
 
111
        u2_comp_type* _u2_comp ;
 
112
        u3_comp_type* _u3_comp ;
 
113
                
 
114
        }; // class cp3_tensor
 
115
        
 
116
        
 
117
#define VMML_TEMPLATE_STRING                    template< size_t R, size_t I1, size_t I2, size_t I3, typename T_value, typename T_coeff >
 
118
#define VMML_TEMPLATE_CLASSNAME                 cp3_tensor< R, I1, I2, I3, T_value, T_coeff >
 
119
        
 
120
        
 
121
VMML_TEMPLATE_STRING
 
122
VMML_TEMPLATE_CLASSNAME::cp3_tensor( u1_type& U1, u2_type& U2, u3_type& U3, lambda_type& lambdas_ )
 
123
{
 
124
        set_lambdas(lambdas_);
 
125
        set_u1( U1);
 
126
        set_u2( U2);
 
127
        set_u3( U3);
 
128
}
 
129
 
 
130
VMML_TEMPLATE_STRING
 
131
VMML_TEMPLATE_CLASSNAME::cp3_tensor()
 
132
{
 
133
        _lambdas = new vector< R, T_coeff>(); 
 
134
        _lambdas->set( 0 );
 
135
        _u1 = new u1_type(); _u1->zero();
 
136
        _u2 = new u2_type(); _u2->zero();
 
137
        _u3 = new u3_type(); _u3->zero();
 
138
        _lambdas_comp = new vector< R, T_internal>; 
 
139
        _lambdas_comp->set( 0 );
 
140
        _u1_comp = new u1_comp_type; _u1_comp->zero();
 
141
        _u2_comp = new u2_comp_type; _u2_comp->zero();
 
142
        _u3_comp = new u3_comp_type; _u3_comp->zero();
 
143
}
 
144
        
 
145
VMML_TEMPLATE_STRING
 
146
VMML_TEMPLATE_CLASSNAME::~cp3_tensor()
 
147
{
 
148
        delete _u1;
 
149
        delete _u2;
 
150
        delete _u3;
 
151
        delete _lambdas;
 
152
        delete _u1_comp;
 
153
        delete _u2_comp;
 
154
        delete _u3_comp;
 
155
        delete _lambdas_comp;
 
156
}
 
157
        
 
158
        
 
159
VMML_TEMPLATE_STRING
 
160
void
 
161
VMML_TEMPLATE_CLASSNAME::cast_members()
 
162
{
 
163
        _u1->cast_from( *_u1_comp );
 
164
        _u2->cast_from( *_u2_comp );
 
165
        _u3->cast_from( *_u3_comp );    
 
166
        _lambdas->cast_from( *_lambdas_comp );
 
167
}
 
168
 
 
169
VMML_TEMPLATE_STRING
 
170
void
 
171
VMML_TEMPLATE_CLASSNAME::cast_comp_members()
 
172
{
 
173
        _u1_comp->cast_from( *_u1 );
 
174
        _u2_comp->cast_from( *_u2 );
 
175
        _u3_comp->cast_from( *_u3 );    
 
176
        _lambdas_comp->cast_from( _lambdas );
 
177
}
 
178
        
 
179
        
 
180
VMML_TEMPLATE_STRING
 
181
void 
 
182
VMML_TEMPLATE_CLASSNAME::reconstruct( t3_type& data_ ) const
 
183
{
 
184
        //FIXME: check data types
 
185
    t3_comp_type data;
 
186
    data.cast_from( data_ );
 
187
        
 
188
        typedef t3_hopm< R, I1, I2, I3, T_internal > hopm_type;
 
189
        hopm_type::reconstruct( data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp );
 
190
         
 
191
     //convert reconstructed data, which is in type T_internal (double, float) to T_value (uint8 or uint16)
 
192
    if( (sizeof(T_value) == 1) || (sizeof(T_value) == 2) ){
 
193
        data_.float_t_to_uint_t( data );
 
194
    } else {
 
195
           data_.cast_from( data );
 
196
    }
 
197
}
 
198
 
 
199
 
 
200
VMML_TEMPLATE_STRING
 
201
template< typename T_init >
 
202
void 
 
203
VMML_TEMPLATE_CLASSNAME::decompose( const t3_type& data_, T_init init, const size_t max_iterations_  )
 
204
{
 
205
        cp_als( data_, init, max_iterations_ );
 
206
}
 
207
 
 
208
VMML_TEMPLATE_STRING
 
209
template< typename T_init >
 
210
void 
 
211
VMML_TEMPLATE_CLASSNAME::cp_als( const t3_type& data_, T_init init, const size_t max_iterations_  )
 
212
{
 
213
        t3_comp_type data;
 
214
        data.cast_from( data_ );
 
215
        
 
216
        typedef t3_hopm< R, I1, I2, I3, T_internal > hopm_type;
 
217
        hopm_type::als( data, *_u1_comp, *_u2_comp, *_u3_comp, *_lambdas_comp, init, max_iterations_ );
 
218
 
 
219
        cast_members();
 
220
}
 
221
 
 
222
        
 
223
VMML_TEMPLATE_STRING
 
224
void
 
225
VMML_TEMPLATE_CLASSNAME::export_to( std::vector< T_coeff >& data_ ) const
 
226
{
 
227
        u1_const_iterator  it = _u1.begin(),
 
228
        it_end = _u1.end();
 
229
        for( ; it != it_end; ++it )
 
230
        {
 
231
                data_.push_back( *it );
 
232
        }
 
233
        
 
234
        u2_const_iterator  u2_it = _u2.begin(),
 
235
        u2_it_end = _u2.end();
 
236
        for( ; u2_it != u2_it_end; ++u2_it )
 
237
        {
 
238
                data_.push_back( *u2_it );
 
239
        }
 
240
        
 
241
        u3_const_iterator  u3_it = _u3.begin(),
 
242
        u3_it_end = _u3.end();
 
243
        for( ; u3_it != u3_it_end; ++u3_it )
 
244
        {
 
245
                data_.push_back( *u3_it );
 
246
        }
 
247
        
 
248
        //TODO: iterate over lambdas
 
249
}
 
250
 
 
251
 
 
252
VMML_TEMPLATE_STRING
 
253
void
 
254
VMML_TEMPLATE_CLASSNAME::import_from( std::vector< T_coeff >& data_ )
 
255
{
 
256
        size_t i = 0; //iterator over data_
 
257
        
 
258
        u1_iterator  it = _u1.begin(),
 
259
        it_end = _u1.end();
 
260
        for( ; it != it_end; ++it, ++i )
 
261
        {
 
262
                *it = data_.at(i);
 
263
        }
 
264
        
 
265
        u2_iterator  u2_it = _u2.begin(),
 
266
        u2_it_end = _u2.end();
 
267
        for( ; u2_it != u2_it_end; ++u2_it, ++i )
 
268
        {
 
269
                *u2_it = data_.at(i);
 
270
        }
 
271
        
 
272
        u3_iterator  u3_it = _u3.begin(),
 
273
        u3_it_end = _u3.end();
 
274
        for( ; u3_it != u3_it_end; ++u3_it, ++i )
 
275
        {
 
276
                *u3_it = data_.at(i);
 
277
        }
 
278
        
 
279
        //TODO: import lambdas
 
280
        
 
281
}       
 
282
 
 
283
VMML_TEMPLATE_STRING
 
284
size_t
 
285
VMML_TEMPLATE_CLASSNAME::nnz() const
 
286
{
 
287
        size_t counter = 0;
 
288
        
 
289
        counter += _u1_comp->nnz();
 
290
        counter += _u2_comp->nnz();
 
291
        counter += _u3_comp->nnz();
 
292
        counter += _lambdas_comp->nnz();
 
293
        
 
294
        return counter;
 
295
}
 
296
        
 
297
 
 
298
                
 
299
#undef VMML_TEMPLATE_STRING
 
300
#undef VMML_TEMPLATE_CLASSNAME
 
301
                
 
302
        } // namespace vmml
 
303
        
 
304
#endif
 
305