00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
#ifndef TENSOR_INC
00035
#define TENSOR_INC
00036
00037
#include <iostream.h>
00038
#include <plearn/base/Storage.h>
00039
#include <plearn/base/TinyVector.h>
00040
#include <vector>
00041
00042
using namespace std;
00043
00044
namespace PLearn {
00045
00046
template <
class T>
00047
class TTensor;
00048
00049 typedef TinyVector<int, 7> IVec;
00050
00051
00052
00053
00054
00055
00056
template<
class T>
00057 class TTensorElementIterator
00058 {
00059
private:
00060
00061 TTensor<T>*
tensor;
00062 IVec position_;
00063
00064
00065 IVec stride_minus_width;
00066 T*
ptr;
00067
00068 bool end_met;
00069
00070
public:
00071
00072 inline TTensorElementIterator()
00073 :
tensor(NULL),
ptr(NULL),
end_met(false)
00074 {
00075 }
00076
00077 inline TTensorElementIterator(
TTensor<T>* tensor_,
const IVec& pos)
00078 :
tensor(tensor_),
position_(pos),
end_met(false)
00079 {
00080
ptr =
tensor->data()+
tensor->linearIndex(pos);
00081
stride_minus_width.
resize(
tensor->ndims());
00082
for(
int i=0;i<(
signed)
tensor->ndims()-1;i++)
00083
stride_minus_width[i] =
tensor->stride_[i+1] -
tensor->stride_[i] *
tensor->width_[i];
00084 }
00085
00086
inline TTensorElementIterator<T>&
operator++();
00087
00088 inline T*
operator->()
const
00089
{
return ptr; }
00090
00091 inline T&
operator*()
const
00092
{
return *
ptr; }
00093
00094 inline bool operator==(
const TTensorElementIterator& other)
00095 {
return ptr==other.
ptr; }
00096
00097 inline bool operator!=(
const TTensorElementIterator& other)
00098 {
return ptr!=other.
ptr; }
00099
00100 inline IVec position()
const {
return position_;}
00101
00102 inline bool end()
const {
return end_met;}
00103 };
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
template<
class T>
00114 class TTensorSubTensorIterator
00115 {
00116
private:
00117
00118 TTensor<T>*
tensor;
00119 IVec position_;
00120 IVec dimensions_;
00121
00122 bool end_met;
00123
00124
public:
00125
00126 inline TTensorSubTensorIterator(
TTensor<T>* tensor_,
const IVec& dim)
00127 :
tensor(tensor_),
dimensions_(dim),
end_met(false)
00128 {
00129
position_=
IVec((
unsigned)
tensor->ndims(),0);
00130
for(
int i=0;i<
tensor->ndims();i++)
00131
if(
dimensions_[i]!=0)
00132
position_[i]=-1;
00133 }
00134
00135
inline TTensorSubTensorIterator<T>()
00136 :tensor(NULL),end_met(
false){}
00137
00138 inline IVec position()
const {
return position_;}
00139
00140
inline TTensorSubTensorIterator<T>&
operator++();
00141
00142 inline TTensor<T> operator*()
const
00143
{
00144
IVec from(
tensor->ndims()),length(
tensor->ndims());
00145
for(
int i=0;i<
tensor->ndims();i++)
00146 {
00147
if(
position_[i]==-1)
00148 {
00149 from[i]=0;
00150 length[i]=
tensor->width_[i];
00151 }
00152
else
00153 {
00154 from[i]=
position_[i];
00155 length[i]=1;
00156 }
00157 }
00158
return tensor->subTensor(from,length);
00159 }
00160
00161 inline bool end()
const {
return end_met;}
00162 };
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
template <
class T>
00178 class TTensor
00179 {
00180 friend class TTensorElementIterator<T>;
00181 friend class TTensorSubTensorIterator<T>;
00182
protected:
00183 int offset_;
00184 IVec stride_;
00185 IVec width_;
00186 PP< Storage<T> >
storage;
00188
public:
00189 typedef TTensorElementIterator<T> iterator;
00190 typedef TTensorSubTensorIterator<T> subTensorIterator;
00191
00192
TTensor<T>()
00193 :
offset_(0),
stride_(0),
width_(0)
00194 {}
00195
00196
TTensor<T>(
IVec len)
00197 :offset_(0), stride_(0), width_(len)
00198 {
00199 stride_.
resize(len.size());
00200
for(
int i=0;i<
ndims();i++)
00201 {
00202 stride_[i]=1;
00203
for(
int j=i-1;j>=0;j--)
00204 stride_[i]*=len[j];
00205 }
00206 storage =
new Storage<T>(
totalElements());
00207 }
00208
00209 TTensor<T>(
const IVec& len,
const T& init_value)
00210 :
offset_(0),
stride_(0),
width_(len)
00211 {
00212
stride_.resize(len.size());
00213
for(
int i=0;i<
ndims();i++)
00214 {
00215
stride_[i]=1;
00216
for(
int j=i-1;j>=0;j--)
00217
stride_[i]*=len[j];
00218 }
00219
storage =
new Storage<T>(
totalElements());
00220
fill(init_value);
00221 }
00222
00224 int resize(
const IVec& len)
00225 {
00226
width_=len;
00227
stride_.
resize(len.size());
00228
for(
int i=0;i<
ndims();i++)
00229 {
00230
stride_[i]=1;
00231
for(
int j=i-1;j>=0;j--)
00232
stride_[i]*=len[j];
00233 }
00234
storage =
new Storage<T>(
totalElements());
00235
offset_=0;
00236 }
00237
00238 int ndims()
const {
return width_.
size();}
00239
00240 IVec width()
const {
return width_;}
00241 IVec sizes()
const {
return width_;}
00242 int size(
int k)
const {
return width_[
k]; }
00243
00244 int totalElements()
const
00245
{
00246
if(
ndims()==0)
00247
return 0;
00248
int te=1;
00249
for(
int i=0;i<
ndims();i++)
00250 te*=
width_[i];
00251
return te;
00252 }
00253
00254 int linearIndex(
const IVec& pos)
const
00255
{
00256
int idx=0;
00257
for(
int i=0;i<
ndims();i++)
00258 idx+=pos[i]*
stride_[i];
00259
return idx;
00260 }
00261
00262 int linearIndex(
const vector<int>& pos)
const
00263
{
00264
int idx=0;
00265
for(
int i=0;i<
ndims();i++)
00266 idx+=pos[i]*
stride_[i];
00267
return idx;
00268 }
00269
00270
00271
00272
00273
00274 TTensor<T> subTensor(
const IVec& from,
const IVec& len)
00275 {
00276
TTensor<T> subt = *
this;
00277 subt.
width_ = len;
00278 subt.
offset_ = linearIndex(from);
00279
00280
IVec idx;
00281
for(
int i=0;i<
ndims();i++)
00282 {
00283
if(from[i]<0 || from[i]+len[i]>
width_[i] || len[i]<0)
00284
PLERROR(
"TTensor::subTensor : at index %i : from, len, width = %i %i %i",i,from[i],len[i],width_[i]);
00285
if(len[i]>0)
00286 idx.
push_back(i);
00287 }
00288
00289
if(idx.
empty())
00290 idx.
push_back(0);
00291 subt.
selectDimensions(idx);
00292
return subt;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 TTensor<T> DEPRECATEDsubTensor(
const IVec& from,
const IVec& len,
bool throw_useless_dimensions=
true)
00306 {
00307
TTensor<T> subt = *
this;
00308 subt.
width_ = len;
00309 subt.
offset_ = linearIndex(from);
00310
00311
IVec idx;
00312
for(
int i=0;i<
ndims();i++)
00313 {
00314
if(from[i]<0 || from[i]+len[i]>
width_[i] || len[i]<0)
00315
PLERROR(
"TTensor::subTensor : at index %i : from, len, width = %i %i %i",i,from[i],len[i],width_[i]);
00316
if(len[i]>1 || !throw_useless_dimensions)
00317 idx.
push_back(i);
00318 }
00319
00320
00321
if(idx.
empty())
00322 idx.
push_back(0);
00323 subt.
selectDimensions(idx);
00324
return subt;
00325 }
00326
00327 TTensor<T> operator[](
int i)
00328 {
00329
IVec from;
00330
IVec len;
00331 from.
push_back(i);
00332 len.
push_back(0);
00333
for(
int k=1;
k<
ndims();
k++)
00334 {
00335 from.
push_back(0);
00336 len.
push_back(size(
k));
00337 }
00338
return subTensor(from,len);
00339 }
00340
00341 void selectDimensions(
const IVec& dim)
00342 {
00343
IVec newwidth,newstride;
00344
for(
int i=0;i<(
signed)dim.
size();i++)
00345 {
00346 newwidth.
push_back(
width_[dim[i]]);
00347 newstride.
push_back(
stride_[dim[i]]);
00348 }
00349
stride_=newstride;
00350
width_=newwidth;
00351 }
00352
00353 T&
operator()(
const IVec& pos)
const {
return (*storage)[linearIndex(pos)];}
00354 T&
operator()(
const vector<int>& pos)
const {
return (*storage)[linearIndex(pos)];}
00355
00356 void fill(
const T& val)
00357 {
00358
int te=
totalElements();
00359
for(
int i=0;i<te;i++)
00360 (*storage)[i]=
val;
00361 }
00362
00363 inline T*
data()
const
00364
{
00365
#ifdef BOUNDCHECK
00366
if(!
storage)
00367
PLERROR(
"IN TTensor::data()\nAttempted to get a pointer to the data of an empty matrix");
00368
#endif
00369
return storage->data+
offset_;
00370 }
00371
00372 IVec lastElementPos()
const
00373
{
00374
IVec v;
00375 v.
resize(
ndims());
00376
for(
int i=0;i<
ndims();i++)
00377 v[i]=(
width_[i]-1);
00378
return v;
00379 }
00380
00382 inline iterator begin()
00383 {
00384
return iterator(
this,
IVec((
unsigned)
ndims(),0));
00385 }
00386
00387
00388
00389 inline iterator end()
00390 {
00391
return iterator(
this,
lastElementPos());
00392 }
00393
00395 inline subTensorIterator getSubTensorIterator(
const IVec& v)
00396 {
00397
return subTensorIterator(
this, v);
00398 }
00399
00400 };
00401
00402 typedef TTensor<real> Tensor;
00403
00404
template<
class T>
00405 inline TTensorElementIterator<T>&
TTensorElementIterator<T>::operator++()
00406 {
00407
ptr+=
tensor->stride_[0];
00408
position_[0]++;
00409
00410
00411
if(
position_[0]==
tensor->width_[0])
00412 {
00413
bool found=
false;
00414
int idx=0;
00415
00416
00417
while(!found && idx<(
signed int)(
tensor->ndims()-1))
00418 {
00419 idx++;
00420 found =
position_[idx]<
tensor->width_[idx]-1;
00421 }
00422
if(found)
00423 {
00424
position_[idx]++;
00425
for(
int i=0;i<idx;i++)
00426 {
00427
ptr+=
stride_minus_width[i];
00428
position_[i]=0;
00429 }
00430 }
00431
else
00432
00433
end_met=
true;
00434 }
00435
return *
this;
00436 }
00437
00438
00439
template<
class T>
00440 inline TTensorSubTensorIterator<T>&
TTensorSubTensorIterator<T>::operator++()
00441 {
00442
bool found=
false;
00443
int idx=-1;
00444
00445
while(!found && idx<(
signed int)(
tensor->ndims()-1))
00446 {
00447 idx++;
00448 found =
position_[idx]!=-1 && position_[idx]<
tensor->width_[idx]-1;
00449 }
00450
if(found)
00451 {
00452
position_[idx]++;
00453
for(
int i=0;i<idx;i++)
00454
if(
position_[i]!=-1)
00455
position_[i]=0;
00456 }
00457
else
00458
00459
end_met=
true;
00460
00461
return *
this;
00462 }
00463
00464
00465 };
00466
00467
#endif