| 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 | 
|---|