00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef TDSPMATRIX_H
00019 #define TDSPMATRIX_H
00020
00021 #include <TH2.h>
00022 #include <TArrayI.h>
00023 #include <TDSPVector.h>
00024
00029
00030
00031 #define LINALG_INDEX_OPT 1
00032 #define LINALG_MAT_ROWWISE 1
00033
00034
00036
00037 enum eMatrixApplyMode {
00038 kMatrixApplyReal,
00039 kMatrixApplyConjA,
00040 kMatrixApplyConjB,
00041 kMatrixApplyConjAB
00042 };
00043
00044 class TDSPMatrix : public TDSPVector {
00045
00046 static TH2 *fHistogram2;
00047 char* fZTitle;
00048 protected:
00049
00050 UInt_t fRows;
00051 UInt_t fCols;
00052
00053 public:
00054
00055 friend istream &operator>>(istream&,TDSPMatrix&);
00056 friend ostream &operator<<(ostream&,TDSPMatrix&);
00057 friend istream &operator>>(istream&,TDSPMatrix*);
00058 friend ostream &operator<<(ostream&,TDSPMatrix*);
00059
00060 TDSPMatrix();
00061 TDSPMatrix(Int_t rows, Int_t cols);
00062
00063 ~TDSPMatrix();
00064
00065 TComplex& Swap(Int_t, Int_t, Int_t, Int_t);
00066 void SetSize(Int_t rows, Int_t cols);
00067 UInt_t GetRows() const { return fRows; };
00068 UInt_t GetCols() const { return fCols; };
00069 void SetRows(UInt_t, Bool_t savedata=kFALSE);
00070 void SetCols(UInt_t, Bool_t savedata=kFALSE);
00071 virtual void SetLen(Int_t num, Bool_t savedata=kFALSE);
00072
00073
00074 Int_t Clo() const { return 0;};
00075 Int_t Chi() const { return fCols-1;};
00076
00077 Int_t Rlo() const { return 0;};
00078 Int_t Rhi() const { return fRows-1;};
00079
00080 TDSPMatrix* Dup() { return Copy(NULL);};
00081 TDSPMatrix* Copy(TDSPMatrix* n);
00082 TDSPVector* Apply(TDSPVector*, TDSPVector *out=NULL, eMatrixApplyMode m=kMatrixApplyReal);
00083 TDSPVector* RightApply(TDSPVector*, TDSPVector* out =NULL);
00084 TDSPMatrix* RightApply(TDSPMatrix*, TDSPMatrix* out =NULL);
00085 TDSPVector* LeftApply( TDSPVector*, TDSPVector* out =NULL);
00086 TDSPMatrix* LeftApply( TDSPMatrix*, TDSPMatrix* out =NULL);
00087
00088 TDSPVector* AdjointRightApply(TDSPVector*, TDSPVector* out =NULL);
00089 TDSPMatrix* AdjointRightApply(TDSPMatrix*, TDSPMatrix* out =NULL);
00090 TDSPVector* AdjointLeftApply( TDSPVector*, TDSPVector* out =NULL);
00091 TDSPMatrix* AdjointLeftApply( TDSPMatrix*, TDSPMatrix* out =NULL);
00092 TDSPVector* TransposedRightApply(TDSPVector*, TDSPVector* out =NULL);
00093 TDSPVector* TransposedLeftApply( TDSPVector*, TDSPVector* out =NULL);
00094
00095 TDSPMatrix* Transform(TDSPMatrix* H,TDSPMatrix* result=NULL);
00096 TDSPMatrix* AdjointTransform(TDSPMatrix* H,TDSPMatrix* result=NULL);
00097
00098 TDSPMatrix* Transposed(TDSPMatrix *r=NULL);
00099 void TransposeMe();
00100 TDSPMatrix* Adjoint(TDSPMatrix *r=NULL);
00101 TComplex Trace();
00102 Double_t Trace2();
00103
00104 Bool_t DiagZero();
00105 Bool_t DiagZeros();
00106 Bool_t IsDiag();
00107 Bool_t IsSquare() const { return fRows==fCols;};
00108 Bool_t IsHermitian();
00109
00110 TDSPMatrix* ReversedColumns(TDSPMatrix *r=NULL);
00111 TDSPMatrix* ReversedRows(TDSPMatrix *r=NULL);
00112 void ReverseColumns();
00113 void ReverseRows();
00114
00115 TDSPVector* GetDiag(TDSPVector *a=NULL);
00116 void SetDiag(TDSPVector *a);
00117 void SetDiag(TComplex a);
00118 void SetNonDiag(TComplex a);
00119 void AddDiag(TComplex a);
00120 void AddDiag(TDSPVector* a);
00121 void MultDiag(TComplex a);
00122 void MultDiag(TDSPVector* a);
00123
00124 Double_t Redundancy() const { return ((Double_t)fRows)/((Double_t)fCols); };
00125
00126 TDSPMatrix *SubMatrix(Int_t atRow, Int_t atCol,
00127 Int_t m, Int_t n, TDSPMatrix*out=NULL);
00128 TDSPMatrix *TransposedSubMatrix(Int_t atRow, Int_t atCol,
00129 Int_t m, Int_t n, TDSPMatrix*out=NULL);
00130 TComplex *MoveVec(Int_t m, Int_t n);
00131 TDSPVector* GetColumn(Int_t c=0, TDSPVector *out=NULL);
00132 TDSPVector* GetRow(Int_t r=0, TDSPVector *out=NULL);
00133 void SetColumn(UInt_t c, TDSPVector *in, UInt_t ifrom=0, UInt_t ito=0);
00134 void SetRow(UInt_t r, TDSPVector *in, UInt_t ifrom=0, UInt_t ito=0);
00135 void RowConvolute(TComplex* inp, TComplex *out,
00136 Int_t N=0,
00137 Bool_t cyclic=kTRUE );
00138
00139 TDSPVector* RowConvolute(TDSPVector*inp, TDSPVector*out=NULL,
00140 Bool_t cyclic=kTRUE,
00141 Bool_t zerosbefore=kTRUE);
00142
00143 TH2* Draw(Option_t *option = "hist surf4",
00144 Double_t dx=1, Double_t xoff=0,
00145 Double_t dy=1, Double_t yoff=0,
00146 TH2 *h = NULL);
00147 void SetZTitle(char *name);
00148 void FFTShiftMe(Int_t dim);
00149
00151
00153
00154
00155
00156 #ifdef HAVE_MATLAB
00157 TDSPMatrix &operator=(TmxArray &m);
00158 #endif
00159
00160
00161 TDSPMatrix &operator=(TDSPMatrix& x) { x.Copy(this);return *this;};
00162 void Print();
00163 void Input();
00164 void Unit(TComplex diag=1.0) { Delta(diag);};
00165 void Delta(TComplex diag=1.0);
00166 void Fourier();
00167 void Hilbert();
00168
00169 TComplex& Element(Int_t i, Int_t j) { return fVec[i*fCols+j];};
00170 TComplex& operator()(UInt_t row, UInt_t col);
00171
00172
00173
00174
00175
00176 void LUDecompose(TArrayI& Index, Int_t &d);
00177 void LUBacksubst(TArrayI& Index, TDSPVector& B);
00178 void LUBacksubst(TArrayI& Index, TDSPMatrix& B);
00179 void LUSolveLinear(TDSPVector& B);
00180 void LUSolveLinear(TDSPMatrix& B);
00181
00182 TDSPMatrix* Inverse(TDSPMatrix *result=NULL);
00183 TComplex Det();
00184
00185
00186
00187
00188 TDSPMatrix* PseudoInverse(TDSPMatrix *result=NULL);
00189 TDSPVector* SVD(TDSPVector *S=NULL,
00190 TDSPMatrix *U=NULL,
00191 TDSPMatrix *VStar=NULL);
00192 ClassDef(TDSPMatrix,1)
00193
00194 };
00195
00196 #include <MatrixRoutines.h>
00197
00198
00199
00200 inline TDSPVector* TDSPMatrix::Apply(TDSPVector *inp, TDSPVector *out, eMatrixApplyMode m) {
00201 switch(m) {
00202 case kMatrixApplyReal :
00203 return RightApply(inp,out);
00204 case kMatrixApplyConjA :
00205 return AdjointRightApply(inp,out);
00206 case kMatrixApplyConjB :
00207 Error("Apply","error");
00208 return NULL;
00209 case kMatrixApplyConjAB :
00210 Error("Apply","error");
00211 return NULL;
00212 }
00213 return NULL;
00214 }
00215
00217
00218 inline TDSPMatrix* TDSPMatrix::Transform(TDSPMatrix* H, TDSPMatrix *result) {
00220
00221 TDSPMatrix* b = LeftApply(H);
00222 result=H->AdjointLeftApply(b,result);
00223 delete b;
00224
00225 return result;
00226
00227 }
00228
00230
00231 inline TDSPMatrix* TDSPMatrix::AdjointTransform(TDSPMatrix* H, TDSPMatrix *result) {
00233
00234 TDSPMatrix* b = H->AdjointRightApply(this);
00235 result = H->LeftApply(b,result);
00236 delete b;
00237 return result;
00238
00239 }
00240
00241 inline TDSPMatrix* TDSPMatrix::LeftApply( TDSPMatrix *inp, TDSPMatrix *out) {
00242 return inp->RightApply(this,out);
00243 }
00244
00245
00246
00248
00249
00250 inline TComplex& TDSPMatrix::operator()(UInt_t row, UInt_t col) {
00251 if (fVec) {
00252 if ((row<fRows)&&(row>=0)&&(col<fCols)&&(col>=0))
00253 return Element(row,col);
00254 else
00255 Error("operator()","index (%d,%d) out of bounds (%d..%d,%d..%d)",row,col,0,fRows-1,0,fCols-1);
00256 } else
00257 Error("operator()","matrix not allocated (this->fVec=0x0)!");
00258 return ComplexZero;
00259 }
00260
00261 inline Bool_t TDSPMatrix::DiagZero() {
00262 if (!IsSquare()) return kTRUE;
00263 for(register UInt_t i=0;i<fRows; ++i)
00264 if (Element(i,i)==0.0) return kTRUE;
00265 return kFALSE;
00266 }
00267
00268 inline Bool_t TDSPMatrix::DiagZeros() {
00269 Int_t min=TMath::Min(fRows,fCols);
00270 for(register Int_t i=0;i<min; ++i)
00271 if (Element(i,i)!=0.0) return kFALSE;
00272 return kTRUE;
00273 }
00274
00275 inline Bool_t TDSPMatrix::IsDiag() {
00276 for(register UInt_t i=0;i<fRows;++i)
00277 for(register UInt_t j=0;j<fCols;++j)
00278 if ((i!=j)&&(Element(i,j)!=0.0)) return kFALSE;
00279 return kTRUE;
00280 }
00281
00282 inline TDSPVector* TDSPMatrix::GetDiag(TDSPVector *a) {
00283 Int_t m=TMath::Min(fRows,fCols);
00284 if (!a) a=new TDSPVector();
00285 a->SetLen(m);
00286 for(register Int_t i=0;i<m;++i)
00287 a->Element(i)=Element(i,i);
00288 return a;
00289 }
00290
00291
00292 inline TDSPMatrix* TDSPMatrix::Transposed(TDSPMatrix *r) {
00293
00294 if (r==this) {
00295 Error("Transposed","Can not be the same matrix - use TDSPMatrix::TransposeMe() !");
00296 return NULL;
00297 }
00298
00299 if (!r) r=new TDSPMatrix();
00300 r->SetSize(fCols,fRows);
00301 for(register UInt_t i=0;i<fRows;++i)
00302 for(register UInt_t j=0;j<fCols;++j)
00303 r->Element(j,i)=Element(i,j);
00304 return r;
00305
00306 }
00307
00308 inline void TDSPMatrix::TransposeMe() {
00309 if (fCols!=fRows)
00310 Error("TransposeMe","non square matrix - use TDSPMatrix::Transposed()!");
00311 else
00312 for(register UInt_t i=0; i<fRows;++i)
00313 for(register UInt_t j=i+1;j<fCols;++j)
00314 Swap(j,i,i,j);
00315 }
00316
00317 inline TDSPMatrix* TDSPMatrix::Adjoint(TDSPMatrix *r) {
00318
00319 if (!r) r=new TDSPMatrix(fCols,fRows);
00320
00321 for(register UInt_t i=0;i<fRows;++i)
00322 for(register UInt_t j=0;j<fCols;++j) {
00323 r->Element(j,i).fRe = Element(i,j).fRe;
00324 r->Element(j,i).fIm = -Element(i,j).fIm;
00325 }
00326
00327 return r;
00328
00329 }
00330 inline Double_t Dist(TDSPMatrix *s1, TDSPMatrix *s2) {
00331 return s1->Dist(s2);
00332 }
00333 inline Double_t Dist2(TDSPMatrix *s1, TDSPMatrix *s2) {
00334 return s1->Dist2(s2);
00335 }
00336 inline Double_t Dot(TDSPMatrix *s1, TDSPMatrix *s2) {
00337 return s1->Dot(s2);
00338 }
00339 inline Double_t Dot2(TDSPMatrix *s1, TDSPMatrix *s2) {
00340 return s1->Dot2(s2);
00341 }
00342 inline Double_t Dist(TDSPMatrix& s1, TDSPMatrix& s2) {
00343 return s1.Dist(s2);
00344 }
00345 inline Double_t Dist2(TDSPMatrix& s1, TDSPMatrix& s2) {
00346 return s1.Dist2(s2);
00347 }
00348 inline Double_t Dot(TDSPMatrix& s1, TDSPMatrix& s2) {
00349 return s1.Dot(s2);
00350 }
00351 inline Double_t Dot2(TDSPMatrix& s1, TDSPMatrix& s2) {
00352 return s1.Dot2(s2);
00353 }
00354 inline Bool_t IsDiag(TDSPMatrix*s) { return s->IsDiag();};
00355 inline Bool_t IsDiag(TDSPMatrix&s) { return s.IsDiag();};
00356
00357
00358 inline TDSPMatrix* TDSPMatrix::Copy(TDSPMatrix *output){
00359
00360 if (!output) output = new TDSPMatrix();
00361 output->SetSize(fRows,fCols);
00362
00363 TComplex *ovec = output->GetVec();
00364
00365 for(register Int_t i=0;i<Num;++i)
00366 ovec[i] = fVec[i];
00367
00368 return output;
00369 }
00370
00371
00372
00373 inline TComplex& TDSPMatrix::Swap(Int_t i, Int_t j, Int_t m, Int_t n) {
00374 #ifdef LINALG_MAT_ROWWISE
00375 UInt_t l1=i*fCols+j;
00376 UInt_t l2=m*fCols+n;
00377 #else
00378 UInt_t l1=j*fRows+i;
00379 UInt_t l2=n*fRows+m;
00380 #endif
00381 TComplex tmp=fVec[l1];
00382 fVec[l1] = fVec[l2];
00383 fVec[l2] = tmp;
00384 return fVec[l2];
00385 }
00386
00387 #endif