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 #ifndef LTI_SINGULAR_VALUE_DECOMPOSITION
00034 #define LTI_SINGULAR_VALUE_DECOMPOSITION
00035
00036 #include "ltiMath.h"
00037 #include "ltiMatrix.h"
00038 #include "ltiLinearAlgebraFunctor.h"
00039
00040 namespace lti {
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 template<class T>
00064 class singularValueDecomp: public linearAlgebraFunctor {
00065 public:
00066
00067
00068
00069
00070 class parameters : public linearAlgebraFunctor::parameters {
00071 public:
00072
00073
00074
00075 parameters() : linearAlgebraFunctor::parameters() {
00076 sort = false;
00077 transposeU = false;
00078 transposeV = false;
00079 };
00080
00081
00082
00083
00084
00085 parameters(const parameters& other)
00086 : linearAlgebraFunctor::parameters() {
00087 copy(other);
00088 };
00089
00090
00091
00092
00093 ~parameters() {
00094 };
00095
00096
00097
00098
00099 const char* getTypeName() const {
00100 return "singularValueDecomp::parameters";
00101 };
00102
00103
00104
00105
00106
00107
00108 parameters& copy(const parameters& other) {
00109 # ifndef _LTI_MSC_6
00110
00111 linearAlgebraFunctor::parameters::copy(other);
00112 # else
00113
00114
00115 functor::parameters&
00116 (functor::parameters::* p_copy)
00117 (const functor::parameters&) =
00118 functor::parameters::copy;
00119 (this->*p_copy)(other);
00120 # endif
00121
00122 sort=other.sort;
00123 transposeU = other.transposeU;
00124 transposeV = other.transposeV;
00125
00126 return *this;
00127 };
00128
00129
00130
00131
00132 inline parameters& operator=(const parameters& other) {
00133 copy(other);
00134 return *this;
00135 }
00136
00137
00138
00139
00140 virtual functor::parameters* clone() const {
00141 return new parameters(*this);
00142 };
00143
00144
00145 # ifndef _LTI_MSC_6
00146
00147
00148
00149
00150
00151
00152
00153 virtual bool read(ioHandler &handler, const bool complete=true)
00154 # else
00155 bool readMS(ioHandler& handler,const bool complete=true)
00156 # endif
00157 {
00158 bool b=true;
00159
00160 if (complete) {
00161 b=handler.readBegin();
00162 }
00163
00164 if (b) {
00165 lti::read(handler,"sort",this->sort);
00166 lti::read(handler,"transposeU",transposeU);
00167 lti::read(handler,"transposeV",transposeV);
00168 }
00169
00170 # ifndef _LTI_MSC_6
00171
00172
00173 b = b && linearAlgebraFunctor::parameters::read(handler,false);
00174 # else
00175 bool (functor::parameters::* p_readMS)(ioHandler&,const bool) =
00176 functor::parameters::readMS;
00177 b = b && (this->*p_readMS)(handler,false);
00178 # endif
00179
00180 if (complete) {
00181 b=b && handler.readEnd();
00182 }
00183
00184 return b;
00185 }
00186
00187 # ifdef _LTI_MSC_6
00188
00189
00190
00191
00192
00193
00194
00195 virtual bool read(ioHandler& handler,const bool complete=true) {
00196
00197
00198 return readMS(handler,complete);
00199 }
00200 # endif
00201
00202 # ifndef _LTI_MSC_6
00203
00204
00205
00206
00207
00208
00209
00210
00211 virtual bool write(ioHandler& handler,const bool complete=true) const
00212 # else
00213 bool writeMS(ioHandler& handler,const bool complete=true) const
00214 # endif
00215 {
00216 bool b=true;
00217
00218 if (complete) {
00219 b=handler.writeBegin();
00220 }
00221
00222 if (b) {
00223 lti::write(handler,"sort",this->sort);
00224 lti::write(handler,"transposeU",transposeU);
00225 lti::write(handler,"transposeV",transposeV);
00226 }
00227
00228 # ifndef _LTI_MSC_6
00229
00230
00231 b = b && linearAlgebraFunctor::parameters::write(handler,false);
00232 # else
00233 bool
00234 (functor::parameters::* p_writeMS)(ioHandler&,const bool) const =
00235 functor::parameters::writeMS;
00236 b = b && (this->*p_writeMS)(handler,false);
00237 # endif
00238
00239 if (complete) {
00240 b=b && handler.writeEnd();
00241 }
00242
00243 return b;
00244 }
00245
00246 # ifdef _LTI_MSC_6
00247
00248
00249
00250
00251
00252
00253
00254 virtual bool write(ioHandler& handler,const bool complete=true) {
00255
00256
00257 return writeMS(handler,complete);
00258 }
00259 # endif
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 bool sort;
00272
00273
00274
00275
00276
00277 bool transposeU;
00278
00279
00280
00281
00282
00283 bool transposeV;
00284 };
00285
00286
00287
00288
00289 singularValueDecomp();
00290
00291
00292
00293
00294 singularValueDecomp(const parameters& params);
00295
00296
00297
00298
00299 singularValueDecomp(bool sort);
00300
00301
00302
00303
00304 singularValueDecomp(const singularValueDecomp<T>& other);
00305
00306
00307
00308
00309 virtual ~singularValueDecomp();
00310
00311
00312
00313
00314 virtual const char* getTypeName() const;
00315
00316
00317
00318
00319
00320
00321 singularValueDecomp& copy(const singularValueDecomp& other);
00322
00323
00324
00325
00326 virtual functor* clone() const;
00327
00328
00329
00330
00331 const parameters& getParameters() const;
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 bool decomposition(matrix<T>& src, vector<T>& w, matrix<T>& v) const;
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 virtual bool apply(matrix<T>& src, vector<T>& w, matrix<T>& v) const;
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 virtual bool apply(const matrix<T>& src, matrix<T>& u,
00378 vector<T>& w, matrix<T>& v) const;
00379
00380 private:
00381
00382
00383
00384 T pythag(const T a,const T b) const;
00385
00386
00387
00388
00389 inline T sign(const T a,const T b) const {
00390 return (b >= T(0)) ? abs(a) : -abs(a);
00391 }
00392
00393
00394
00395
00396 inline bool isZero(const T x) const;
00397
00398
00399
00400
00401 inline bool notZero(const T x) const;
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 inline T dotOfRows(const matrix<T>& data,
00418 const int row1, const int row2,
00419 int lowCol=0, const int highCol=MaxInt32) const {
00420
00421
00422 T sum=T(0);
00423 const vector<T>& rtmp1=data.getRow(row1);
00424 const vector<T>& rtmp2=data.getRow(row2);
00425 const typename vector<T>::const_iterator ie1=rtmp1.end();
00426 const typename vector<T>::const_iterator ie2=rtmp2.end();
00427
00428 typename vector<T>::const_iterator i1=rtmp1.begin();
00429 typename vector<T>::const_iterator i2=rtmp2.begin();
00430
00431 i1+=lowCol;
00432 i2+=lowCol;
00433
00434 while (lowCol++ <= highCol && i1 != ie1 && i2 != ie2) {
00435 sum+=*i1++**i2++;
00436 }
00437 return sum;
00438 }
00439
00440
00441
00442
00443 inline T dotOfColumns(const matrix<T>& data,
00444 const int col1, const int col2,
00445 int lowRow=0, int highRow=MaxInt32) const {
00446 T sum=T(0);
00447 highRow=min(highRow,data.rows()-1);
00448 while (lowRow <= highRow) {
00449 sum+=data.at(lowRow,col1)*data.at(lowRow,col2);
00450 lowRow++;
00451 }
00452 return sum;
00453 }
00454
00455
00456
00457
00458
00459 inline T sumOfRowPart(const matrix<T>& data,
00460 const int row,
00461 int lowCol=0, const int highCol=MaxInt32) const {
00462 T sum=T(0);
00463 const vector<T>& rtmp=data.getRow(row);
00464 const typename vector<T>::const_iterator ie=rtmp.end();
00465
00466 typename vector<T>::const_iterator i=rtmp.begin();
00467 i+=lowCol;
00468 while (lowCol++ <= highCol && i != ie) {
00469 sum+=*i++;
00470 }
00471 return sum;
00472 }
00473
00474
00475
00476
00477 inline T sumOfColumnPart(const matrix<T>& data,
00478 const int col,
00479 int lowRow=0, int highRow=MaxInt32) const {
00480 T sum=T(0);
00481 highRow=min(highRow,data.rows()-1);
00482 while (lowRow <= highRow) {
00483 sum+=data.at(lowRow,col);
00484 lowRow++;
00485 }
00486 return sum;
00487 }
00488
00489
00490
00491
00492
00493 inline T sumOfAbsRowPart(const matrix<T>& data,
00494 const int row,
00495 int lowCol=0, const int highCol=MaxInt32) const {
00496 T sum=T(0);
00497 const vector<T>& rtmp=data.getRow(row);
00498 const typename vector<T>::const_iterator ie=rtmp.end();
00499
00500 typename vector<T>::const_iterator i=rtmp.begin();
00501 i+=lowCol;
00502 while (lowCol <= highCol && i != ie) {
00503 sum+=abs(*i++);
00504 lowCol++;
00505 }
00506 return sum;
00507 }
00508
00509
00510
00511
00512 inline T sumOfAbsColumnPart(const matrix<T>& data,
00513 const int col,
00514 int lowRow=0, int highRow=MaxInt32) const {
00515 T sum=T(0);
00516 highRow=min(highRow,data.rows()-1);
00517 while (lowRow <= highRow) {
00518 sum+=abs(data.at(lowRow,col));
00519 lowRow++;
00520 }
00521 return sum;
00522 }
00523
00524 inline void multiplyColumn(matrix<T>& data, const int col, const T factor,
00525 int lowRow=0, int highRow=MaxInt32) const {
00526 highRow=min(highRow,data.rows()-1);
00527 for (int i=lowRow; i<=highRow; i++) {
00528 data.at(lowRow++,col)*=factor;
00529 }
00530 }
00531
00532 inline void multiplyRow(matrix<T>& data, const int row, const T factor,
00533 int lowCol=0, const int highCol=MaxInt32) const {
00534 vector<T>& rtmp=data.getRow(row);
00535 typename vector<T>::iterator i=rtmp.begin();
00536 const typename vector<T>::iterator ie=rtmp.end();
00537 i+=lowCol;
00538 while (lowCol++ <= highCol && i != ie) {
00539 *i++*=factor;
00540 }
00541 }
00542
00543 inline void fillColumn(matrix<T>& data, const int col, const T value,
00544 int lowRow=0, int highRow=MaxInt32) const {
00545 highRow=min(highRow,data.rows()-1);
00546 for (int i=lowRow; i<=highRow; i++) {
00547 data.at(lowRow++,col)=value;
00548 }
00549 }
00550
00551 inline void fillRow(matrix<T>& data, const int row, const T value,
00552 int lowCol=0, const int highCol=MaxInt32) const {
00553 vector<T>& rtmp=data.getRow(row);
00554 typename vector<T>::iterator i=rtmp.begin();
00555 const typename vector<T>::iterator ie=rtmp.end();
00556 i+=lowCol;
00557 while (lowCol++ <= highCol && i != ie) {
00558 *i++=value;
00559 }
00560 }
00561
00562 };
00563 }
00564
00565 #endif