| [658] | 1 | // $Id: tmatrix.cc,v 1.1.1.1 1999-11-26 16:37:12 ansari Exp $ | 
|---|
|  | 2 | //                         C.Magneville          04/99 | 
|---|
|  | 3 | #include "machdefs.h" | 
|---|
|  | 4 | #include <stdio.h> | 
|---|
|  | 5 | #include <stdlib.h> | 
|---|
|  | 6 | #include <iostream.h> | 
|---|
|  | 7 | #include <values.h> | 
|---|
|  | 8 | #include <complex> | 
|---|
|  | 9 | #include "pexceptions.h" | 
|---|
|  | 10 | #include "tmatrix.h" | 
|---|
|  | 11 | #include "objfio.h" | 
|---|
|  | 12 |  | 
|---|
|  | 13 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 14 | //**** Createur, Destructeur | 
|---|
|  | 15 |  | 
|---|
|  | 16 | template <class T> | 
|---|
|  | 17 | TMatrix<T>::TMatrix() | 
|---|
|  | 18 | // Constructeur par defaut. | 
|---|
|  | 19 | : mNr(0), mNc(0), mNDBlock() | 
|---|
|  | 20 | { | 
|---|
|  | 21 | } | 
|---|
|  | 22 |  | 
|---|
|  | 23 | template <class T> | 
|---|
|  | 24 | TMatrix<T>::TMatrix(uint_4 r,uint_4 c) | 
|---|
|  | 25 | // Construit une matrice de r lignes et c colonnes. | 
|---|
|  | 26 | : mNr(r), mNc(c), mNDBlock(r*c) | 
|---|
|  | 27 | { | 
|---|
|  | 28 | } | 
|---|
|  | 29 |  | 
|---|
|  | 30 | template <class T> | 
|---|
|  | 31 | TMatrix<T>::TMatrix(uint_4 r,uint_4 c,T* values,Bridge* br) | 
|---|
|  | 32 | // Construit une matrice de r lignes et c colonnes. On fournit | 
|---|
|  | 33 | // le tableau des valeurs et eventuellement un Bridge. | 
|---|
|  | 34 | : mNr(r), mNc(c), mNDBlock(r*c,values,br) | 
|---|
|  | 35 | { | 
|---|
|  | 36 | } | 
|---|
|  | 37 |  | 
|---|
|  | 38 | template <class T> | 
|---|
|  | 39 | TMatrix<T>::TMatrix(const TMatrix<T>& a) | 
|---|
|  | 40 | // Constructeur par copie (partage si "a" temporaire). | 
|---|
|  | 41 | : mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock) | 
|---|
|  | 42 | { | 
|---|
|  | 43 | } | 
|---|
|  | 44 |  | 
|---|
|  | 45 | template <class T> | 
|---|
|  | 46 | TMatrix<T>::TMatrix(const TMatrix<T>& a,bool share) | 
|---|
|  | 47 | // Constructeur par copie avec possibilite de forcer le partage ou non. | 
|---|
|  | 48 | : mNr(a.mNr), mNc(a.mNc), mNDBlock(a.mNDBlock,share) | 
|---|
|  | 49 | { | 
|---|
|  | 50 | } | 
|---|
|  | 51 |  | 
|---|
|  | 52 | template <class T> | 
|---|
|  | 53 | TMatrix<T>::~TMatrix() | 
|---|
|  | 54 | // Destructeur | 
|---|
|  | 55 | { | 
|---|
|  | 56 | } | 
|---|
|  | 57 |  | 
|---|
|  | 58 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 59 | // Operations matricielles | 
|---|
|  | 60 | template <class T> | 
|---|
|  | 61 | TMatrix<T> TMatrix<T>::Transpose(void) const | 
|---|
|  | 62 | // Transposition | 
|---|
|  | 63 | { | 
|---|
|  | 64 | TMatrix<T> a; a.Clone(*this); a.SetTemp(true); | 
|---|
|  | 65 | a.mNr = mNc; a.mNc = mNr; | 
|---|
|  | 66 | {for(uint_4 i=0; i<mNr; i++) | 
|---|
|  | 67 | for(uint_4 j=0; j<mNc; j++) { | 
|---|
|  | 68 | a(j,i) = (*this)(i,j); | 
|---|
|  | 69 | }} | 
|---|
|  | 70 | return a; | 
|---|
|  | 71 | } | 
|---|
|  | 72 |  | 
|---|
|  | 73 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 74 | //**** Impression | 
|---|
|  | 75 |  | 
|---|
|  | 76 | template <class T> | 
|---|
|  | 77 | void TMatrix<T>::Print(ostream& os,int lp | 
|---|
|  | 78 | ,uint_4 i0,uint_4 ni,uint_4 j0,uint_4 nj) const | 
|---|
|  | 79 | // Impression de la sous-matrice (i:i+ni-1,i:j+nj-1) | 
|---|
|  | 80 | { | 
|---|
|  | 81 | os<<"TMatrix::Print("<<mNr<<","<<mNc<<")"<<endl; | 
|---|
|  | 82 | if(lp>0) | 
|---|
|  | 83 | {os<<"       this="<<this<<endl; mNDBlock.Print(0,0);} | 
|---|
|  | 84 | if(mNr==0 || mNc==0) return; | 
|---|
|  | 85 | if(i0>=mNr || j0>=mNc || ni==0 || nj==0) return; | 
|---|
|  | 86 | uint_4 i1 = i0+ni; if(i1>mNr) i1 = mNr; | 
|---|
|  | 87 | uint_4 j1 = j0+nj; if(j1>mNc) j1 = mNc; | 
|---|
|  | 88 | for(uint_4 i=i0;i<i1;i++) { | 
|---|
|  | 89 | for(uint_4 j=j0;j<j1;j++) cout<<" "<<(*this)(i,j); | 
|---|
|  | 90 | cout<<endl; | 
|---|
|  | 91 | } | 
|---|
|  | 92 | } | 
|---|
|  | 93 |  | 
|---|
|  | 94 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 95 | //**** Surcharge de *= (INPLACE): TMatrix *= TMatrix; | 
|---|
|  | 96 |  | 
|---|
|  | 97 | template <class T> | 
|---|
|  | 98 | TMatrix<T>& TMatrix<T>::operator *= (const TMatrix<T>& a) | 
|---|
|  | 99 | // A = A*B  -> A(n,m) = A(n,m)*B(m,m) | 
|---|
|  | 100 | { | 
|---|
|  | 101 | uint_4 ndata = mNr*mNc; | 
|---|
|  | 102 | if(ndata==0 || mNc!=a.mNr || a.mNr!=a.mNc) | 
|---|
|  | 103 | throw(SzMismatchError("TMatrix::operator*=A size mismatch")); | 
|---|
|  | 104 | // A(i,j) = Sum(k) A(i,k)*B(k,j) ... il faut sauver la ligne "i" de A | 
|---|
|  | 105 | // Vecteur oi   : vecteur ou est sauve la ligne i de la matrice *this | 
|---|
|  | 106 | //                oi,oe = pointeur de debut et de fin du vecteur temporaire | 
|---|
|  | 107 | //                oij   = pointeur parcourant le vecteur oi | 
|---|
|  | 108 | // Matrice *this: i     = pointeur du debut de la ligne i | 
|---|
|  | 109 | //                ij    = pointeur parcourant la ligne i | 
|---|
|  | 110 | // Matrice a    : aj    = pointeur de debut de la colonne j | 
|---|
|  | 111 | //                aji   = pointeur parcourant la colonne j | 
|---|
|  | 112 | T* oi = new T[mNc]; T* oe = oi+mNc; | 
|---|
|  | 113 | for(T *i=Data(); i<Data()+ndata; i+=mNc) { | 
|---|
|  | 114 | {for(T *oij=oi,*ij=i; oij<oe;) *oij++ = *ij++;} | 
|---|
|  | 115 | {for(T *ij=i,*aj=const_cast<T *>(a.Data()); aj<a.Data()+a.mNc; ij++,aj++) { | 
|---|
|  | 116 | T sum = 0; | 
|---|
|  | 117 | for(T *oij=oi,*aji=aj; oij<oe; oij++,aji+=a.mNc) sum += *oij * *aji; | 
|---|
|  | 118 | *ij = sum; | 
|---|
|  | 119 | }} | 
|---|
|  | 120 | } | 
|---|
|  | 121 | delete [] oi; | 
|---|
|  | 122 | return *this; | 
|---|
|  | 123 | } | 
|---|
|  | 124 |  | 
|---|
|  | 125 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 126 | //**** Pour surcharge d'operateurs C = A (+,-,*,/) B | 
|---|
|  | 127 |  | 
|---|
|  | 128 | template <class T> TMatrix<T> TMatrix<T>::Add(const TMatrix<T>& b) const | 
|---|
|  | 129 | { | 
|---|
|  | 130 | if(mNr!=b.mNr || mNc!=b.mNc) | 
|---|
|  | 131 | throw(SzMismatchError("TMatrix operator C=A+B size mismatch\n")); | 
|---|
|  | 132 | TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc; | 
|---|
|  | 133 | result.mNDBlock = mNDBlock+b.mNDBlock; | 
|---|
|  | 134 | return result; | 
|---|
|  | 135 | } | 
|---|
|  | 136 |  | 
|---|
|  | 137 | template <class T> TMatrix<T> TMatrix<T>::Sub(const TMatrix<T>& b) const | 
|---|
|  | 138 | { | 
|---|
|  | 139 | if(mNr!=b.mNr || mNc!=b.mNc) | 
|---|
|  | 140 | throw(SzMismatchError("TMatrix operator C=A-B size mismatch\n")); | 
|---|
|  | 141 | TMatrix<T> result; result.SetTemp(true); result.mNr=mNr; result.mNc=mNc; | 
|---|
|  | 142 | result.mNDBlock = mNDBlock-b.mNDBlock; | 
|---|
|  | 143 | return result; | 
|---|
|  | 144 | } | 
|---|
|  | 145 |  | 
|---|
|  | 146 | template <class T> TMatrix<T> TMatrix<T>::Mul(const TMatrix<T>& b) const | 
|---|
|  | 147 | // C = A(this)*B : Cij = Aik Bkj (allocation forcee dans tous les cas) | 
|---|
|  | 148 | { | 
|---|
|  | 149 | if(mNr==0 || mNc==0 || b.mNc==0 || mNc!=b.mNr) | 
|---|
|  | 150 | throw(SzMismatchError("TMatrix operator C=A*B size mismatch\n")); | 
|---|
|  | 151 | TMatrix<T> r; r.SetTemp(true); r.ReSize(mNr,b.mNc); | 
|---|
|  | 152 | T *ai,*aik,*bj,*bkj,*ri,*rij; | 
|---|
|  | 153 | for(ri=const_cast<T *>(r.Data()),ai=const_cast<T *>(Data()); | 
|---|
|  | 154 | ri<r.Data()+r.mNr*r.mNc;ri+=r.mNc,ai+=mNc) { | 
|---|
|  | 155 | for(rij=ri,bj=const_cast<T *>(b.Data());rij<ri+r.mNc;rij++,bj++) { | 
|---|
|  | 156 | *rij = 0; | 
|---|
|  | 157 | for(aik=ai,bkj=bj;aik<ai+mNc;aik++,bkj+=b.mNc) *rij += *aik * *bkj; | 
|---|
|  | 158 | } | 
|---|
|  | 159 | } | 
|---|
|  | 160 | return r; | 
|---|
|  | 161 | } | 
|---|
|  | 162 |  | 
|---|
|  | 163 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 164 | //**** Pour gestion des lignes et des colonnes | 
|---|
|  | 165 |  | 
|---|
|  | 166 | template <class T> TMatrixRC<T> TMatrix<T>::Row(uint_4 r) const | 
|---|
|  | 167 | { | 
|---|
|  | 168 | TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixRow, r); | 
|---|
|  | 169 | return rc; | 
|---|
|  | 170 | } | 
|---|
|  | 171 |  | 
|---|
|  | 172 | template <class T> TMatrixRC<T> TMatrix<T>::Col(uint_4 c) const | 
|---|
|  | 173 | { | 
|---|
|  | 174 | TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixCol, c); | 
|---|
|  | 175 | return rc; | 
|---|
|  | 176 | } | 
|---|
|  | 177 |  | 
|---|
|  | 178 | template <class T> TMatrixRC<T> TMatrix<T>::Diag() const | 
|---|
|  | 179 | { | 
|---|
|  | 180 | TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixDiag); | 
|---|
|  | 181 | return rc; | 
|---|
|  | 182 | } | 
|---|
|  | 183 |  | 
|---|
|  | 184 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 185 | //**** Pour inversion | 
|---|
|  | 186 | #ifndef M_LN2 | 
|---|
|  | 187 | #define M_LN2 0.69314718055994530942 | 
|---|
|  | 188 | #endif | 
|---|
|  | 189 | #ifndef LN_MINDOUBLE | 
|---|
|  | 190 | #define LN_MINDOUBLE  (M_LN2 * (DMINEXP - 1)) | 
|---|
|  | 191 | #endif | 
|---|
|  | 192 | #ifndef LN_MAXDOUBLE | 
|---|
|  | 193 | #define LN_MAXDOUBLE  (M_LN2 * DMAXEXP) | 
|---|
|  | 194 | #endif | 
|---|
|  | 195 |  | 
|---|
|  | 196 | r_8 TMatrix<r_8>::GausPiv(TMatrix<r_8>& a, TMatrix<r_8>& b) | 
|---|
|  | 197 | // Pivot de Gauss | 
|---|
|  | 198 | // * Attention: egcs impose que cette fonction soit mise dans le .cc | 
|---|
|  | 199 | //              avant ::Inverse() (car Inverse() l'utilise) | 
|---|
|  | 200 | // {TMatrix A(a); TMatrix B(b); return (r_8) TMatrix::GausPiv(A,B);} | 
|---|
|  | 201 | { | 
|---|
|  | 202 | uint_4 n = a.NRows(); | 
|---|
|  | 203 | if(n!=b.NRows()) | 
|---|
|  | 204 | throw(SzMismatchError("TMatrix::GausPiv size mismatch\n")); | 
|---|
|  | 205 | // On fait une normalisation un peu brutale... | 
|---|
|  | 206 | double vmin=MAXDOUBLE; | 
|---|
|  | 207 | double vmax=0; | 
|---|
|  | 208 | for(uint_4 iii=0; iii<a.NRows(); iii++) | 
|---|
|  | 209 | for(uint_4 jjj=0; jjj<a.NCols(); jjj++) { | 
|---|
|  | 210 | double v = TMatrixRC<r_8>::Abs_Value(a(iii,jjj)); | 
|---|
|  | 211 | if(v>vmax) vmax = v; | 
|---|
|  | 212 | if(v<vmin && v>0) vmin = v; | 
|---|
|  | 213 | } | 
|---|
|  | 214 | double nrm = sqrt(vmin*vmax); | 
|---|
|  | 215 | if(nrm > 1.e5 || nrm < 1.e-5) { | 
|---|
|  | 216 | a /= nrm; | 
|---|
|  | 217 | b /= nrm; | 
|---|
|  | 218 | //cout << "normalisation matrice " << nrm << endl; | 
|---|
|  | 219 | } else nrm=1; | 
|---|
|  | 220 |  | 
|---|
|  | 221 | double det = 1.0; | 
|---|
|  | 222 | if(nrm != 1) { | 
|---|
|  | 223 | double ld = a.NRows() * log(nrm); | 
|---|
|  | 224 | if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) { | 
|---|
|  | 225 | // cerr << "TMatrix warning, overflow for det" << endl; | 
|---|
|  | 226 | } else { | 
|---|
|  | 227 | det = exp(ld); | 
|---|
|  | 228 | } | 
|---|
|  | 229 | } | 
|---|
|  | 230 |  | 
|---|
|  | 231 | TMatrixRC<r_8> pivRowa(a,TmatrixRow); | 
|---|
|  | 232 | TMatrixRC<r_8> pivRowb(b,TmatrixRow); | 
|---|
|  | 233 |  | 
|---|
|  | 234 | for(uint_4 k=0; k<n-1; k++) { | 
|---|
|  | 235 | uint_4 iPiv = a.Col(k).IMaxAbs(k); | 
|---|
|  | 236 | if(iPiv != k) { | 
|---|
|  | 237 | TMatrixRC<r_8> aIPiv(a.Row(iPiv)); | 
|---|
|  | 238 | TMatrixRC<r_8> aK(a.Row(k)); | 
|---|
|  | 239 | TMatrixRC<r_8>::Swap(aIPiv,aK); | 
|---|
|  | 240 | TMatrixRC<r_8> bIPiv(b.Row(iPiv)); | 
|---|
|  | 241 | TMatrixRC<r_8> bK(b.Row(k)); | 
|---|
|  | 242 | TMatrixRC<r_8>::Swap(bIPiv,bK); | 
|---|
|  | 243 | } | 
|---|
|  | 244 | double pivot = a(k,k); | 
|---|
|  | 245 | if (fabs(pivot) < 1.e-50) return 0.0; | 
|---|
|  | 246 | //det *= pivot; | 
|---|
|  | 247 | pivRowa.SetRow(k); // to avoid constructors | 
|---|
|  | 248 | pivRowb.SetRow(k); | 
|---|
|  | 249 | for (uint_4 i=k+1; i<n; i++) { | 
|---|
|  | 250 | double r = -a(i,k)/pivot; | 
|---|
|  | 251 | a.Row(i).LinComb(r, pivRowa); // + rapide que -= r * pivRowa | 
|---|
|  | 252 | b.Row(i).LinComb(r, pivRowb); | 
|---|
|  | 253 | } | 
|---|
|  | 254 | } | 
|---|
|  | 255 | det *= a(n-1, n-1); | 
|---|
|  | 256 |  | 
|---|
|  | 257 | // on remonte | 
|---|
|  | 258 | for(uint_4 kk=n-1; kk>0; kk--) { | 
|---|
|  | 259 | double pivot = a(kk,kk); | 
|---|
|  | 260 | if (fabs(pivot) <= 1.e-50) return 0.0; | 
|---|
|  | 261 | pivRowa.SetRow(kk); // to avoid constructors | 
|---|
|  | 262 | pivRowb.SetRow(kk); | 
|---|
|  | 263 | for(uint_4 jj=0; jj<kk; jj++) { | 
|---|
|  | 264 | double r = -a(jj,kk)/pivot; | 
|---|
|  | 265 | a.Row(jj).LinComb(r, pivRowa); | 
|---|
|  | 266 | b.Row(jj).LinComb(r, pivRowb); | 
|---|
|  | 267 | } | 
|---|
|  | 268 | } | 
|---|
|  | 269 |  | 
|---|
|  | 270 | for(uint_4 l=0; l<n; l++) { | 
|---|
|  | 271 | if (fabs(a(l,l)) <= 1.e-50) return 0.0; | 
|---|
|  | 272 | b.Row(l) /= a(l,l); | 
|---|
|  | 273 | } | 
|---|
|  | 274 |  | 
|---|
|  | 275 | return det; | 
|---|
|  | 276 | } | 
|---|
|  | 277 |  | 
|---|
|  | 278 | TMatrix<r_8> TMatrix<r_8>::Inverse() const | 
|---|
|  | 279 | // Inversion | 
|---|
|  | 280 | { | 
|---|
|  | 281 | TMatrix<r_8> b(mNc,mNr); TMatrix<r_8> a(*this); b = 1.; | 
|---|
|  | 282 | if(fabs(TMatrix<r_8>::GausPiv(a,b)) < 1.e-50) | 
|---|
|  | 283 | throw(MathExc("TMatrix Inverse() Singular OMatrix")); | 
|---|
|  | 284 | return b; | 
|---|
|  | 285 | } | 
|---|
|  | 286 |  | 
|---|
|  | 287 | #include "generalfit.h" | 
|---|
|  | 288 | ////////////////////////////////////////////////////////// | 
|---|
|  | 289 | //**** Residus des fits | 
|---|
|  | 290 | TMatrix<r_8> TMatrix<r_8>::FitResidus(GeneralFit& gfit | 
|---|
|  | 291 | ,double xorg,double yorg,double dx,double dy) | 
|---|
|  | 292 | // Retourne une classe contenant les residus du fit ``gfit''. | 
|---|
|  | 293 | // On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j). | 
|---|
|  | 294 | // Les coordonnees de l'element (i,j) sont : | 
|---|
|  | 295 | //    (i,j) -> x = xorg+j*dx , y = yorg+i*dy | 
|---|
|  | 296 | { | 
|---|
|  | 297 | if(NCols()<=0||NRows()<=0) | 
|---|
|  | 298 | throw(SzMismatchError("TMatrix::FitResidus size mismatch\n")); | 
|---|
|  | 299 | GeneralFunction* f = gfit.GetFunction(); | 
|---|
|  | 300 | if(f==NULL) | 
|---|
|  | 301 | throw(NullPtrError("TMatrix::FitResidus GeneraFit==NULL\n")); | 
|---|
|  | 302 | int npar =  gfit.GetNPar(); | 
|---|
|  | 303 | if(npar==0) | 
|---|
|  | 304 | throw(SzMismatchError("TMatrix::FitResidus GeneraFit 0 parametre\n")); | 
|---|
|  | 305 | double* par = new double[npar]; | 
|---|
|  | 306 | {for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);} | 
|---|
|  | 307 | TMatrix<r_8> m(*this); | 
|---|
|  | 308 | for(uint_4 i=0;i<NRows();i++) for(uint_4 j=0;j<NCols();j++) { | 
|---|
|  | 309 | double x[2] = {xorg+j*dx,yorg+i*dy}; | 
|---|
|  | 310 | m(i,j) -= f->Value(x,par); | 
|---|
|  | 311 | } | 
|---|
|  | 312 | delete [] par; | 
|---|
|  | 313 | return m; | 
|---|
|  | 314 | } | 
|---|
|  | 315 |  | 
|---|
|  | 316 | TMatrix<r_8> TMatrix<r_8>::FitFunction(GeneralFit& gfit | 
|---|
|  | 317 | ,double xorg,double yorg,double dx,double dy) | 
|---|
|  | 318 | // Retourne une classe contenant la fonction du fit ``gfit''. | 
|---|
|  | 319 | // On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j). | 
|---|
|  | 320 | // Les coordonnees de l'element (i,j) sont : | 
|---|
|  | 321 | //    (i,j) -> x = xorg + j*dx , y = yorg + i*dy | 
|---|
|  | 322 | { | 
|---|
|  | 323 | if(NCols()<=0||NRows()<=0) | 
|---|
|  | 324 | throw(SzMismatchError("TMatrix::FitFunction size mismatch\n")); | 
|---|
|  | 325 | GeneralFunction* f = gfit.GetFunction(); | 
|---|
|  | 326 | if(f==NULL) | 
|---|
|  | 327 | throw(NullPtrError("TMatrix::FitFunction GeneraFit==NULL\n")); | 
|---|
|  | 328 | int npar =  gfit.GetNPar(); | 
|---|
|  | 329 | if(npar==0) | 
|---|
|  | 330 | throw(SzMismatchError("TMatrix::FitFunction GeneraFit 0 parametre\n")); | 
|---|
|  | 331 | double* par = new double[npar]; | 
|---|
|  | 332 | {for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);} | 
|---|
|  | 333 | TMatrix<r_8> m(*this); | 
|---|
|  | 334 | for(uint_4 i=0;i<NRows();i++) for(uint_4 j=0;j<NCols();j++) { | 
|---|
|  | 335 | double x[2] = {xorg+j*dx,yorg+i*dy}; | 
|---|
|  | 336 | m(i,j) = f->Value(x,par); | 
|---|
|  | 337 | } | 
|---|
|  | 338 | delete [] par; | 
|---|
|  | 339 | return m; | 
|---|
|  | 340 | } | 
|---|
|  | 341 |  | 
|---|
|  | 342 | /////////////////////////////////////////////////////////// | 
|---|
|  | 343 | // -------------------------------------------------------- | 
|---|
|  | 344 | //   Les objets delegues pour la gestion de persistance | 
|---|
|  | 345 | // -------------------------------------------------------- | 
|---|
|  | 346 | /////////////////////////////////////////////////////////// | 
|---|
|  | 347 |  | 
|---|
|  | 348 | template <class T> | 
|---|
|  | 349 | FIO_TMatrix<T>::FIO_TMatrix() | 
|---|
|  | 350 | { | 
|---|
|  | 351 | dobj=new TMatrix<T>; | 
|---|
|  | 352 | ownobj=true; | 
|---|
|  | 353 | } | 
|---|
|  | 354 |  | 
|---|
|  | 355 | template <class T> | 
|---|
|  | 356 | FIO_TMatrix<T>::FIO_TMatrix(string const & filename) | 
|---|
|  | 357 | { | 
|---|
|  | 358 | dobj=new TMatrix<T>; | 
|---|
|  | 359 | ownobj=true; | 
|---|
|  | 360 | Read(filename); | 
|---|
|  | 361 | } | 
|---|
|  | 362 |  | 
|---|
|  | 363 | template <class T> | 
|---|
|  | 364 | FIO_TMatrix<T>::FIO_TMatrix(const TMatrix<T> & obj) | 
|---|
|  | 365 | { | 
|---|
|  | 366 | dobj = new TMatrix<T>(obj); | 
|---|
|  | 367 | ownobj=true; | 
|---|
|  | 368 | } | 
|---|
|  | 369 |  | 
|---|
|  | 370 | template <class T> | 
|---|
|  | 371 | FIO_TMatrix<T>::FIO_TMatrix(TMatrix<T> * obj) | 
|---|
|  | 372 | { | 
|---|
|  | 373 | dobj = obj; | 
|---|
|  | 374 | ownobj=false; | 
|---|
|  | 375 | } | 
|---|
|  | 376 |  | 
|---|
|  | 377 | template <class T> | 
|---|
|  | 378 | FIO_TMatrix<T>::~FIO_TMatrix() | 
|---|
|  | 379 | { | 
|---|
|  | 380 | if (ownobj && dobj) delete dobj; | 
|---|
|  | 381 | } | 
|---|
|  | 382 |  | 
|---|
|  | 383 | template <class T> | 
|---|
|  | 384 | AnyDataObj* FIO_TMatrix<T>::DataObj() | 
|---|
|  | 385 | { | 
|---|
|  | 386 | return(dobj); | 
|---|
|  | 387 | } | 
|---|
|  | 388 |  | 
|---|
|  | 389 | template <class T> | 
|---|
|  | 390 | void FIO_TMatrix<T>::ReadSelf(PInPersist& is) | 
|---|
|  | 391 | { | 
|---|
|  | 392 | // On lit les 3 premiers uint_4 | 
|---|
|  | 393 | //  0: Numero de version,  1 : NRows,  2 : NCol | 
|---|
|  | 394 | uint_4 itab[3]; | 
|---|
|  | 395 | is.Get(itab,3); | 
|---|
|  | 396 | if (dobj == NULL) dobj = new TMatrix<T>(itab[1],itab[2]); | 
|---|
|  | 397 | else dobj->ReSize(itab[1],itab[2]); | 
|---|
|  | 398 | // On lit le NDataBlock | 
|---|
|  | 399 | FIO_NDataBlock<T> fio_nd(&dobj->DataBlock()); | 
|---|
|  | 400 | fio_nd.Read(is); | 
|---|
|  | 401 | } | 
|---|
|  | 402 |  | 
|---|
|  | 403 | template <class T> | 
|---|
|  | 404 | void FIO_TMatrix<T>::WriteSelf(POutPersist& os) const | 
|---|
|  | 405 | { | 
|---|
|  | 406 | if (dobj == NULL)   return; | 
|---|
|  | 407 | //  On ecrit 3 uint_4 .... | 
|---|
|  | 408 | //  0: Numero de version,  1 : NRows,  2 : NCol | 
|---|
|  | 409 | uint_4 itab[3]; | 
|---|
|  | 410 | itab[0] = 1;  // Numero de version a 1 | 
|---|
|  | 411 | itab[1] = dobj->NRows(); | 
|---|
|  | 412 | itab[2] = dobj->NCols(); | 
|---|
|  | 413 | os.Put(itab,3); | 
|---|
|  | 414 | // On ecrit le NDataBlock | 
|---|
|  | 415 | FIO_NDataBlock<T> fio_nd(&dobj->DataBlock()); | 
|---|
|  | 416 | fio_nd.Write(os); | 
|---|
|  | 417 | } | 
|---|
|  | 418 |  | 
|---|
|  | 419 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 420 | // ------------------------------------------------------------- | 
|---|
|  | 421 | //   La classe de gestion des lignes et colonnes d'une matrice | 
|---|
|  | 422 | // ------------------------------------------------------------- | 
|---|
|  | 423 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 424 | #include "tvector.h" | 
|---|
|  | 425 |  | 
|---|
|  | 426 | template <class T> TMatrixRC<T>::TMatrixRC() | 
|---|
|  | 427 | : matrix(NULL), data(NULL), index(0), step(0) | 
|---|
|  | 428 | {} | 
|---|
|  | 429 |  | 
|---|
|  | 430 | template <class T> TMatrixRC<T>::TMatrixRC(TMatrix<T>& m,TRCKind rckind,uint_4 ind) | 
|---|
|  | 431 | : matrix(&m), data(Org(m,rckind,ind)), | 
|---|
|  | 432 | index(ind), step(Step(m,rckind)), kind(rckind) | 
|---|
|  | 433 | { | 
|---|
|  | 434 | if (kind == TmatrixDiag && m.mNc != m.mNr) | 
|---|
|  | 435 | throw(SzMismatchError("TMatrixRC::TMatrixRC(...,TmatrixDiag,...) size mismatch\n")); | 
|---|
|  | 436 | } | 
|---|
|  | 437 |  | 
|---|
|  | 438 | template <class T> int_4 TMatrixRC<T>::Next() | 
|---|
|  | 439 | { | 
|---|
|  | 440 | if (!matrix || kind==TmatrixDiag) return -1; | 
|---|
|  | 441 | index++; | 
|---|
|  | 442 | if(kind == TmatrixRow) { | 
|---|
|  | 443 | if(index > (int_4)matrix->mNr) {index = (int_4)matrix->mNr; return -1;} | 
|---|
|  | 444 | data += matrix->mNc; | 
|---|
|  | 445 | } else { | 
|---|
|  | 446 | if (index > (int_4)matrix->mNc) {index = (int_4)matrix->mNc; return -1;} | 
|---|
|  | 447 | data++; | 
|---|
|  | 448 | } | 
|---|
|  | 449 | return index; | 
|---|
|  | 450 | } | 
|---|
|  | 451 |  | 
|---|
|  | 452 | template <class T> int_4 TMatrixRC<T>::Prev() | 
|---|
|  | 453 | { | 
|---|
|  | 454 | if (!matrix || kind == TmatrixDiag) return -1; | 
|---|
|  | 455 | index--; | 
|---|
|  | 456 | if(index < 0) {index = 0; return -1;} | 
|---|
|  | 457 | if(kind == TmatrixRow) data -= matrix->mNc; | 
|---|
|  | 458 | else data--; | 
|---|
|  | 459 | return index; | 
|---|
|  | 460 | } | 
|---|
|  | 461 |  | 
|---|
|  | 462 | template <class T> int_4 TMatrixRC<T>::SetCol(int_4 c) | 
|---|
|  | 463 | { | 
|---|
|  | 464 | if(!matrix) return -1; | 
|---|
|  | 465 | if(c<0 || c>(int_4)matrix->mNc) return -1; | 
|---|
|  | 466 | kind = TmatrixCol; | 
|---|
|  | 467 | index = c; | 
|---|
|  | 468 | step = Step(*matrix, TmatrixCol); | 
|---|
|  | 469 | data = Org(*matrix, TmatrixCol, c); | 
|---|
|  | 470 | return c; | 
|---|
|  | 471 | } | 
|---|
|  | 472 |  | 
|---|
|  | 473 | template <class T> int_4 TMatrixRC<T>::SetRow(int_4 r) | 
|---|
|  | 474 | { | 
|---|
|  | 475 | if(!matrix) return -1; | 
|---|
|  | 476 | if(r<0 && r>(int_4)matrix->mNr) return -1; | 
|---|
|  | 477 | kind = TmatrixRow; | 
|---|
|  | 478 | index = r; | 
|---|
|  | 479 | step = Step(*matrix, TmatrixRow); | 
|---|
|  | 480 | data = Org(*matrix, TmatrixRow, r); | 
|---|
|  | 481 | return r; | 
|---|
|  | 482 | } | 
|---|
|  | 483 |  | 
|---|
|  | 484 | template <class T> int_4 TMatrixRC<T>::SetDiag() | 
|---|
|  | 485 | { | 
|---|
|  | 486 | if (!matrix) return -1; | 
|---|
|  | 487 | if (matrix->mNc != matrix->mNr) | 
|---|
|  | 488 | throw(SzMismatchError("TMatrixRC::SetDiag size mismatch\n")); | 
|---|
|  | 489 | kind = TmatrixDiag; | 
|---|
|  | 490 | index = 0; | 
|---|
|  | 491 | step = Step(*matrix, TmatrixDiag); | 
|---|
|  | 492 | data = Org(*matrix, TmatrixDiag); | 
|---|
|  | 493 | return 0; | 
|---|
|  | 494 | } | 
|---|
|  | 495 |  | 
|---|
|  | 496 |  | 
|---|
|  | 497 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator = (const TMatrixRC<T>& rc) | 
|---|
|  | 498 | { | 
|---|
|  | 499 | matrix = rc.matrix; | 
|---|
|  | 500 | data   = rc.data; | 
|---|
|  | 501 | index  = rc.index; | 
|---|
|  | 502 | step   = rc.step; | 
|---|
|  | 503 | kind   = rc.kind; | 
|---|
|  | 504 | return *this; | 
|---|
|  | 505 | } | 
|---|
|  | 506 |  | 
|---|
|  | 507 | template <class T> TVector<T> TMatrixRC<T>::GetVect() const | 
|---|
|  | 508 | { | 
|---|
|  | 509 | TVector<T> v(NElts()); | 
|---|
|  | 510 | for (uint_4 i=0; i<NElts(); i++) v(i) = (*this)(i); | 
|---|
|  | 511 | return v; | 
|---|
|  | 512 | } | 
|---|
|  | 513 |  | 
|---|
|  | 514 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (const TMatrixRC<T>& rc) | 
|---|
|  | 515 | { | 
|---|
|  | 516 | if ( NElts() != rc.NElts() ) | 
|---|
|  | 517 | throw(SzMismatchError("TMatrixRC::operator+= size mismatch\n")); | 
|---|
|  | 518 | if ( kind != rc.kind ) | 
|---|
|  | 519 | throw(SzMismatchError("TMatrixRC::operator+= type mismatch\n")); | 
|---|
|  | 520 | for (uint_4 i=0; i<NElts(); i++) (*this)(i) += rc(i); | 
|---|
|  | 521 | return *this; | 
|---|
|  | 522 | } | 
|---|
|  | 523 |  | 
|---|
|  | 524 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (const TMatrixRC<T>& rc) | 
|---|
|  | 525 | { | 
|---|
|  | 526 | if( NElts() != rc.NElts() ) | 
|---|
|  | 527 | throw(SzMismatchError("TMatrixRC::operator-= size mismatch\n")); | 
|---|
|  | 528 | if( kind != rc.kind ) | 
|---|
|  | 529 | throw(SzMismatchError("TMatrixRC::operator-= type mismatch\n")); | 
|---|
|  | 530 | for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= rc(i); | 
|---|
|  | 531 | return *this; | 
|---|
|  | 532 | } | 
|---|
|  | 533 |  | 
|---|
|  | 534 |  | 
|---|
|  | 535 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x) | 
|---|
|  | 536 | { | 
|---|
|  | 537 | for(uint_4 i=0; i<NElts(); i++) (*this)(i) *= x; | 
|---|
|  | 538 | return *this; | 
|---|
|  | 539 | } | 
|---|
|  | 540 |  | 
|---|
|  | 541 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator /= (T x) | 
|---|
|  | 542 | { | 
|---|
|  | 543 | for(uint_4 i=0; i<NElts(); i++) (*this)(i) /= x; | 
|---|
|  | 544 | return *this; | 
|---|
|  | 545 | } | 
|---|
|  | 546 |  | 
|---|
|  | 547 |  | 
|---|
|  | 548 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (T x) | 
|---|
|  | 549 | { | 
|---|
|  | 550 | for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= x; | 
|---|
|  | 551 | return *this; | 
|---|
|  | 552 | } | 
|---|
|  | 553 |  | 
|---|
|  | 554 | template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (T x) | 
|---|
|  | 555 | { | 
|---|
|  | 556 | for(uint_4 i=0; i<NElts(); i++) (*this)(i) += x; | 
|---|
|  | 557 | return *this; | 
|---|
|  | 558 | } | 
|---|
|  | 559 |  | 
|---|
|  | 560 | template <class T> | 
|---|
|  | 561 | TMatrixRC<T>& TMatrixRC<T>::LinComb(T a, T b, const TMatrixRC<T>& rc, uint_4 first) | 
|---|
|  | 562 | { | 
|---|
|  | 563 | if ( NElts() != rc.NElts() ) | 
|---|
|  | 564 | throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n")); | 
|---|
|  | 565 | if ( kind != rc.kind ) | 
|---|
|  | 566 | throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n")); | 
|---|
|  | 567 | for(uint_4 i=first; i<NElts(); i++) (*this)(i) = (*this)(i)*a + rc(i)*b; | 
|---|
|  | 568 | return *this; | 
|---|
|  | 569 | } | 
|---|
|  | 570 |  | 
|---|
|  | 571 | template <class T> | 
|---|
|  | 572 | TMatrixRC<T>& TMatrixRC<T>::LinComb(T b, const TMatrixRC<T>& rc, uint_4 first) | 
|---|
|  | 573 | { | 
|---|
|  | 574 | if ( NElts() != rc.NElts() ) | 
|---|
|  | 575 | throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n")); | 
|---|
|  | 576 | if ( kind != rc.kind ) | 
|---|
|  | 577 | throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n")); | 
|---|
|  | 578 | for(uint_4 i=first; i<NElts(); i++) (*this)(i) += rc(i)*b; | 
|---|
|  | 579 | return *this; | 
|---|
|  | 580 | } | 
|---|
|  | 581 |  | 
|---|
|  | 582 | template <class T> uint_4 TMatrixRC<T>::IMaxAbs(uint_4 first) | 
|---|
|  | 583 | { | 
|---|
|  | 584 | if (first>NElts()) | 
|---|
|  | 585 | throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n")); | 
|---|
|  | 586 | uint_4 imax = first; | 
|---|
|  | 587 | double vmax = Abs_Value((*this)(first)); | 
|---|
|  | 588 | for(uint_4 i=first+1; i<NElts(); i++) { | 
|---|
|  | 589 | double v = Abs_Value((*this)(i)); | 
|---|
|  | 590 | if(v > vmax) {vmax = v; imax = i;} | 
|---|
|  | 591 | } | 
|---|
|  | 592 | return imax; | 
|---|
|  | 593 | } | 
|---|
|  | 594 |  | 
|---|
|  | 595 | template <class T> | 
|---|
|  | 596 | void TMatrixRC<T>::Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2) | 
|---|
|  | 597 | { | 
|---|
|  | 598 | if(rc1.NElts() != rc2.NElts()) | 
|---|
|  | 599 | throw(SzMismatchError("TMatrixRC::Swap size mismatch\n")); | 
|---|
|  | 600 | if(rc1.kind != rc2.kind) | 
|---|
|  | 601 | throw(SzMismatchError("TMatrixRC::Swap type mismatch\n")); | 
|---|
|  | 602 | if(rc1.data == rc2.data) return; | 
|---|
|  | 603 | for(uint_4 i=0; i<rc1.NElts(); i++) | 
|---|
|  | 604 | {T tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;} | 
|---|
|  | 605 | } | 
|---|
|  | 606 |  | 
|---|
|  | 607 | /////////////////////////////////////////////////////////////// | 
|---|
|  | 608 | #ifdef __CXX_PRAGMA_TEMPLATES__ | 
|---|
|  | 609 | #pragma define_template TMatrix<uint_1> | 
|---|
|  | 610 | #pragma define_template TMatrix<uint_2> | 
|---|
|  | 611 | #pragma define_template TMatrix<int_2> | 
|---|
|  | 612 | #pragma define_template TMatrix<int_4> | 
|---|
|  | 613 | #pragma define_template TMatrix<int_8> | 
|---|
|  | 614 | #pragma define_template TMatrix<uint_4> | 
|---|
|  | 615 | #pragma define_template TMatrix<uint_8> | 
|---|
|  | 616 | #pragma define_template TMatrix<r_4> | 
|---|
|  | 617 | #pragma define_template TMatrix<r_8> | 
|---|
|  | 618 | #pragma define_template TMatrix< complex<float> > | 
|---|
|  | 619 | #pragma define_template TMatrix< complex<double> > | 
|---|
|  | 620 | // Instances des delegues FileIO (PPersist) | 
|---|
|  | 621 | #pragma define_template FIO_TMatrix<uint_1> | 
|---|
|  | 622 | #pragma define_template FIO_TMatrix<uint_2> | 
|---|
|  | 623 | #pragma define_template FIO_TMatrix<int_2> | 
|---|
|  | 624 | #pragma define_template FIO_TMatrix<int_4> | 
|---|
|  | 625 | #pragma define_template FIO_TMatrix<int_8> | 
|---|
|  | 626 | #pragma define_template FIO_TMatrix<uint_4> | 
|---|
|  | 627 | #pragma define_template FIO_TMatrix<uint_8> | 
|---|
|  | 628 | #pragma define_template FIO_TMatrix<r_8> | 
|---|
|  | 629 | #pragma define_template FIO_TMatrix<r_4> | 
|---|
|  | 630 | #pragma define_template FIO_TMatrix< complex<float> > | 
|---|
|  | 631 | #pragma define_template FIO_TMatrix< complex<double> > | 
|---|
|  | 632 | // Instances gestion lignes/colonnes | 
|---|
|  | 633 | #pragma define_template TMatrixRC<uint_1> | 
|---|
|  | 634 | #pragma define_template TMatrixRC<uint_2> | 
|---|
|  | 635 | #pragma define_template TMatrixRC<int_2> | 
|---|
|  | 636 | #pragma define_template TMatrixRC<int_4> | 
|---|
|  | 637 | #pragma define_template TMatrixRC<int_8> | 
|---|
|  | 638 | #pragma define_template TMatrixRC<uint_4> | 
|---|
|  | 639 | #pragma define_template TMatrixRC<uint_8> | 
|---|
|  | 640 | #pragma define_template TMatrixRC<r_4> | 
|---|
|  | 641 | #pragma define_template TMatrixRC<r_8> | 
|---|
|  | 642 | #pragma define_template TMatrixRC< complex<float> > | 
|---|
|  | 643 | #pragma define_template TMatrixRC< complex<double> > | 
|---|
|  | 644 | #endif | 
|---|
|  | 645 |  | 
|---|
|  | 646 | #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) | 
|---|
|  | 647 | template class TMatrix<uint_1>; | 
|---|
|  | 648 | template class TMatrix<uint_2>; | 
|---|
|  | 649 | template class TMatrix<int_2>; | 
|---|
|  | 650 | template class TMatrix<int_4>; | 
|---|
|  | 651 | template class TMatrix<int_8>; | 
|---|
|  | 652 | template class TMatrix<uint_4>; | 
|---|
|  | 653 | template class TMatrix<uint_8>; | 
|---|
|  | 654 | template class TMatrix<r_4>; | 
|---|
|  | 655 | template class TMatrix<r_8>; | 
|---|
|  | 656 | template class TMatrix< complex<float> >; | 
|---|
|  | 657 | template class TMatrix< complex<double> >; | 
|---|
|  | 658 | // Instances des delegues FileIO (PPersist) | 
|---|
|  | 659 | template class FIO_TMatrix<uint_1>; | 
|---|
|  | 660 | template class FIO_TMatrix<uint_2>; | 
|---|
|  | 661 | template class FIO_TMatrix<int_2>; | 
|---|
|  | 662 | template class FIO_TMatrix<int_4>; | 
|---|
|  | 663 | template class FIO_TMatrix<int_8>; | 
|---|
|  | 664 | template class FIO_TMatrix<uint_4>; | 
|---|
|  | 665 | template class FIO_TMatrix<uint_8>; | 
|---|
|  | 666 | template class FIO_TMatrix<r_8>; | 
|---|
|  | 667 | template class FIO_TMatrix<r_4>; | 
|---|
|  | 668 | template class FIO_TMatrix< complex<float> >; | 
|---|
|  | 669 | template class FIO_TMatrix< complex<double> >; | 
|---|
|  | 670 | // Instances gestion lignes/colonnes | 
|---|
|  | 671 | template class TMatrixRC<uint_1>; | 
|---|
|  | 672 | template class TMatrixRC<uint_2>; | 
|---|
|  | 673 | template class TMatrixRC<int_2>; | 
|---|
|  | 674 | template class TMatrixRC<int_4>; | 
|---|
|  | 675 | template class TMatrixRC<int_8>; | 
|---|
|  | 676 | template class TMatrixRC<uint_4>; | 
|---|
|  | 677 | template class TMatrixRC<uint_8>; | 
|---|
|  | 678 | template class TMatrixRC<r_4>; | 
|---|
|  | 679 | template class TMatrixRC<r_8>; | 
|---|
|  | 680 | template class TMatrixRC< complex<float> >; | 
|---|
|  | 681 | template class TMatrixRC< complex<double> >; | 
|---|
|  | 682 | #endif | 
|---|