Changeset 304 in Sophya for trunk/SophyaLib/NTools
- Timestamp:
- May 18, 1999, 7:19:37 PM (26 years ago)
- Location:
- trunk/SophyaLib/NTools
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/NTools/cvector.h
r303 r304 6 6 7 7 class GeneralFit; 8 #include "tvector.h" 9 //cmv template <class T> class TVector; 8 namespace PlanckDPC {template <class T> class TVector;} 10 9 11 10 // <summary> Vecteur colonne pour operations matricielles </summary> -
trunk/SophyaLib/NTools/matrix.h
r288 r304 12 12 13 13 class GeneralFit; 14 #include "tmatrix.h" 15 //cmv template <class T> class TMatrix; 14 namespace PlanckDPC {template <class T> class TMatrix;} 16 15 17 16 // <summary> Operations matricielles </summary> -
trunk/SophyaLib/NTools/tmatrix.cc
r302 r304 1 // $Id: tmatrix.cc,v 1. 7 1999-05-18 12:58:24ansari Exp $1 // $Id: tmatrix.cc,v 1.8 1999-05-18 17:19:36 ansari Exp $ 2 2 // C.Magneville 04/99 3 3 #include "machdefs.h" … … 5 5 #include <stdlib.h> 6 6 #include <iostream.h> 7 #include <values.h> 7 8 #include <complex> 8 9 #include "pexceptions.h" … … 162 163 } 163 164 165 //////////////////////////////////////////////////////////////// 166 //**** Pour gestion des lignes et des colonnes 167 168 template <class T> TMatrixRC<T> TMatrix<T>::Row(uint_4 r) const 169 { 170 TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixRow, r); 171 return rc; 172 } 173 174 template <class T> TMatrixRC<T> TMatrix<T>::Col(uint_4 c) const 175 { 176 TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixCol, c); 177 return rc; 178 } 179 180 template <class T> TMatrixRC<T> TMatrix<T>::Diag() const 181 { 182 TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixDiag); 183 return rc; 184 } 185 164 186 #include "matrix.h" 165 187 //////////////////////////////////////////////////////////////// 166 188 //**** Pour inversion 189 #ifndef M_LN2 190 #define M_LN2 0.69314718055994530942 191 #endif 192 #ifndef LN_MINDOUBLE 193 #define LN_MINDOUBLE (M_LN2 * (DMINEXP - 1)) 194 #endif 195 #ifndef LN_MAXDOUBLE 196 #define LN_MAXDOUBLE (M_LN2 * DMAXEXP) 197 #endif 198 167 199 r_8 TMatrix<r_8>::GausPiv(TMatrix<r_8>& a, TMatrix<r_8>& b) 168 200 // Pivot de Gauss 169 201 // * Attention: egcs impose que cette fonction soit mise dans le .cc 170 202 // avant ::Inverse() (car Inverse() l'utilise) 171 { 172 Matrix A(a); 173 Matrix B(b); 174 return (r_8) Matrix::GausPiv(A,B); 203 // {Matrix A(a); Matrix B(b); return (r_8) Matrix::GausPiv(A,B);} 204 { 205 uint_4 n = a.NRows(); 206 if(n!=b.NRows()) 207 throw(SzMismatchError("TMatrix::GausPiv size mismatch\n")); 208 // On fait une normalisation un peu brutale... 209 double vmin=MAXDOUBLE; 210 double vmax=0; 211 for(uint_4 iii=0; iii<a.NRows(); iii++) 212 for(uint_4 jjj=0; jjj<a.NCols(); jjj++) { 213 double v = TMatrixRC<r_8>::Abs_Value(a(iii,jjj)); 214 if(v>vmax) vmax = v; 215 if(v<vmin && v>0) vmin = v; 216 } 217 double nrm = sqrt(vmin*vmax); 218 if(nrm > 1.e5 || nrm < 1.e-5) { 219 a /= nrm; 220 b /= nrm; 221 //cout << "normalisation matrice " << nrm << endl; 222 } else nrm=1; 223 224 double det = 1.0; 225 if(nrm != 1) { 226 double ld = a.NRows() * log(nrm); 227 if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) { 228 // cerr << "Matrix warning, overflow for det" << endl; 229 } else { 230 det = exp(ld); 231 } 232 } 233 234 TMatrixRC<r_8> pivRowa(a,TmatrixRow); 235 TMatrixRC<r_8> pivRowb(b,TmatrixRow); 236 237 for(uint_4 k=0; k<n-1; k++) { 238 uint_4 iPiv = a.Col(k).IMaxAbs(k); 239 if(iPiv != k) { 240 TMatrixRC<r_8> aIPiv(a.Row(iPiv)); 241 TMatrixRC<r_8> aK(a.Row(k)); 242 TMatrixRC<r_8>::Swap(aIPiv,aK); 243 TMatrixRC<r_8> bIPiv(b.Row(iPiv)); 244 TMatrixRC<r_8> bK(b.Row(k)); 245 TMatrixRC<r_8>::Swap(bIPiv,bK); 246 } 247 double pivot = a(k,k); 248 if (fabs(pivot) < 1.e-50) return 0.0; 249 //det *= pivot; 250 pivRowa.SetRow(k); // to avoid constructors 251 pivRowb.SetRow(k); 252 for (uint_4 i=k+1; i<n; i++) { 253 double r = -a(i,k)/pivot; 254 a.Row(i).LinComb(r, pivRowa); // + rapide que -= r * pivRowa 255 b.Row(i).LinComb(r, pivRowb); 256 } 257 } 258 det *= a(n-1, n-1); 259 260 // on remonte 261 for(uint_4 kk=n-1; kk>0; kk--) { 262 double pivot = a(kk,kk); 263 if (fabs(pivot) <= 1.e-50) return 0.0; 264 pivRowa.SetRow(kk); // to avoid constructors 265 pivRowb.SetRow(kk); 266 for(uint_4 jj=0; jj<kk; jj++) { 267 double r = -a(jj,kk)/pivot; 268 a.Row(jj).LinComb(r, pivRowa); 269 b.Row(jj).LinComb(r, pivRowb); 270 } 271 } 272 273 for(uint_4 l=0; l<n; l++) { 274 if (fabs(a(l,l)) <= 1.e-50) return 0.0; 275 b.Row(l) /= a(l,l); 276 } 277 278 return det; 175 279 } 176 280 … … 178 282 // Inversion 179 283 { 180 TMatrix<r_8> b(mNc,mNr); 181 TMatrix<r_8> a(*this); 182 b = 1.; 183 if (fabs(TMatrix<r_8>::GausPiv(a,b)) < 1.e-50) 284 TMatrix<r_8> b(mNc,mNr); TMatrix<r_8> a(*this); b = 1.; 285 if(fabs(TMatrix<r_8>::GausPiv(a,b)) < 1.e-50) 184 286 throw(MathExc("TMatrix Inverse() Singular Matrix")); 185 287 return b; … … 241 343 } 242 344 243 /////////////////////////////////////////////////////////// /////244 // -------------------------------------------------------- -----------------345 /////////////////////////////////////////////////////////// 346 // -------------------------------------------------------- 245 347 // Les objets delegues pour la gestion de persistance 246 // ------------------------------------------------------------------------- 348 // -------------------------------------------------------- 349 /////////////////////////////////////////////////////////// 247 350 248 351 template <class T> … … 316 419 FIO_NDataBlock<T> fio_nd(&dobj->DataBlock()); 317 420 fio_nd.Write(os); 421 } 422 423 //////////////////////////////////////////////////////////////// 424 // ------------------------------------------------------------- 425 // La classe de gestion des lignes et colonnes d'une matrice 426 // ------------------------------------------------------------- 427 //////////////////////////////////////////////////////////////// 428 #include "tvector.h" 429 430 template <class T> TMatrixRC<T>::TMatrixRC() 431 : matrix(NULL), data(NULL), index(0), step(0) 432 {} 433 434 template <class T> TMatrixRC<T>::TMatrixRC(TMatrix<T>& m,TRCKind rckind,uint_4 ind) 435 : matrix(&m), data(Org(m,rckind,ind)), 436 index(ind), step(Step(m,rckind)), kind(rckind) 437 { 438 if (kind == TmatrixDiag && m.mNc != m.mNr) 439 throw(SzMismatchError("TMatrixRC::TMatrixRC(...,TmatrixDiag,...) size mismatch\n")); 440 } 441 442 template <class T> int_4 TMatrixRC<T>::Next() 443 { 444 if (!matrix || kind==TmatrixDiag) return -1; 445 index++; 446 if(kind == TmatrixRow) { 447 if(index > (int_4)matrix->mNr) {index = (int_4)matrix->mNr; return -1;} 448 data += matrix->mNc; 449 } else { 450 if (index > (int_4)matrix->mNc) {index = (int_4)matrix->mNc; return -1;} 451 data++; 452 } 453 return index; 454 } 455 456 template <class T> int_4 TMatrixRC<T>::Prev() 457 { 458 if (!matrix || kind == TmatrixDiag) return -1; 459 index--; 460 if(index < 0) {index = 0; return -1;} 461 if(kind == TmatrixRow) data -= matrix->mNc; 462 else data--; 463 return index; 464 } 465 466 template <class T> int_4 TMatrixRC<T>::SetCol(int_4 c) 467 { 468 if(!matrix) return -1; 469 if(c<0 || c>(int_4)matrix->mNc) return -1; 470 kind = TmatrixCol; 471 index = c; 472 step = Step(*matrix, TmatrixCol); 473 data = Org(*matrix, TmatrixCol, c); 474 return c; 475 } 476 477 template <class T> int_4 TMatrixRC<T>::SetRow(int_4 r) 478 { 479 if(!matrix) return -1; 480 if(r<0 && r>(int_4)matrix->mNr) return -1; 481 kind = TmatrixRow; 482 index = r; 483 step = Step(*matrix, TmatrixRow); 484 data = Org(*matrix, TmatrixRow, r); 485 return r; 486 } 487 488 template <class T> int_4 TMatrixRC<T>::SetDiag() 489 { 490 if (!matrix) return -1; 491 if (matrix->mNc != matrix->mNr) 492 throw(SzMismatchError("TMatrixRC::SetDiag size mismatch\n")); 493 kind = TmatrixDiag; 494 index = 0; 495 step = Step(*matrix, TmatrixDiag); 496 data = Org(*matrix, TmatrixDiag); 497 return 0; 498 } 499 500 501 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator = (const TMatrixRC<T>& rc) 502 { 503 matrix = rc.matrix; 504 data = rc.data; 505 index = rc.index; 506 step = rc.step; 507 kind = rc.kind; 508 return *this; 509 } 510 511 template <class T> TVector<T> TMatrixRC<T>::GetVect() const 512 { 513 TVector<T> v(NElts()); 514 for (uint_4 i=0; i<NElts(); i++) v(i) = (*this)(i); 515 return v; 516 } 517 518 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (const TMatrixRC<T>& rc) 519 { 520 if ( NElts() != rc.NElts() ) 521 throw(SzMismatchError("TMatrixRC::operator+= size mismatch\n")); 522 if ( kind != rc.kind ) 523 throw(SzMismatchError("TMatrixRC::operator+= type mismatch\n")); 524 for (uint_4 i=0; i<NElts(); i++) (*this)(i) += rc(i); 525 return *this; 526 } 527 528 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (const TMatrixRC<T>& rc) 529 { 530 if( NElts() != rc.NElts() ) 531 throw(SzMismatchError("TMatrixRC::operator-= size mismatch\n")); 532 if( kind != rc.kind ) 533 throw(SzMismatchError("TMatrixRC::operator-= type mismatch\n")); 534 for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= rc(i); 535 return *this; 536 } 537 538 539 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x) 540 { 541 for(uint_4 i=0; i<NElts(); i++) (*this)(i) *= x; 542 return *this; 543 } 544 545 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator /= (T x) 546 { 547 for(uint_4 i=0; i<NElts(); i++) (*this)(i) /= x; 548 return *this; 549 } 550 551 552 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (T x) 553 { 554 for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= x; 555 return *this; 556 } 557 558 template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (T x) 559 { 560 for(uint_4 i=0; i<NElts(); i++) (*this)(i) += x; 561 return *this; 562 } 563 564 template <class T> 565 TMatrixRC<T>& TMatrixRC<T>::LinComb(T a, T b, const TMatrixRC<T>& rc, uint_4 first) 566 { 567 if ( NElts() != rc.NElts() ) 568 throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n")); 569 if ( kind != rc.kind ) 570 throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n")); 571 for(uint_4 i=first; i<NElts(); i++) (*this)(i) = (*this)(i)*a + rc(i)*b; 572 return *this; 573 } 574 575 template <class T> 576 TMatrixRC<T>& TMatrixRC<T>::LinComb(T b, const TMatrixRC<T>& rc, uint_4 first) 577 { 578 if ( NElts() != rc.NElts() ) 579 throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n")); 580 if ( kind != rc.kind ) 581 throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n")); 582 for(uint_4 i=first; i<NElts(); i++) (*this)(i) += rc(i)*b; 583 return *this; 584 } 585 586 template <class T> uint_4 TMatrixRC<T>::IMaxAbs(uint_4 first) 587 { 588 if (first>NElts()) 589 throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n")); 590 uint_4 imax = first; 591 double vmax = Abs_Value((*this)(first)); 592 for(uint_4 i=first+1; i<NElts(); i++) { 593 double v = Abs_Value((*this)(i)); 594 if(v > vmax) {vmax = v; imax = i;} 595 } 596 return imax; 597 } 598 599 template <class T> 600 void TMatrixRC<T>::Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2) 601 { 602 if(rc1.NElts() != rc2.NElts()) 603 throw(SzMismatchError("TMatrixRC::Swap size mismatch\n")); 604 if(rc1.kind != rc2.kind) 605 throw(SzMismatchError("TMatrixRC::Swap type mismatch\n")); 606 if(rc1.data == rc2.data) return; 607 for(uint_4 i=0; i<rc1.NElts(); i++) 608 {T tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;} 318 609 } 319 610 … … 343 634 #pragma define_template FIO_TMatrix< complex<float> > 344 635 #pragma define_template FIO_TMatrix< complex<double> > 636 // Instances gestion lignes/colonnes 637 #pragma define_template TMatrixRC<uint_1> 638 #pragma define_template TMatrixRC<uint_2> 639 #pragma define_template TMatrixRC<int_2> 640 #pragma define_template TMatrixRC<int_4> 641 #pragma define_template TMatrixRC<int_8> 642 #pragma define_template TMatrixRC<uint_4> 643 #pragma define_template TMatrixRC<uint_8> 644 #pragma define_template TMatrixRC<r_4> 645 #pragma define_template TMatrixRC<r_8> 646 #pragma define_template TMatrixRC< complex<float> > 647 #pragma define_template TMatrixRC< complex<double> > 345 648 #endif 346 649 … … 369 672 template class FIO_TMatrix< complex<float> >; 370 673 template class FIO_TMatrix< complex<double> >; 674 // Instances gestion lignes/colonnes 675 template class TMatrixRC<uint_1>; 676 template class TMatrixRC<uint_2>; 677 template class TMatrixRC<int_2>; 678 template class TMatrixRC<int_4>; 679 template class TMatrixRC<int_8>; 680 template class TMatrixRC<uint_4>; 681 template class TMatrixRC<uint_8>; 682 template class TMatrixRC<r_4>; 683 template class TMatrixRC<r_8>; 684 template class TMatrixRC< complex<float> >; 685 template class TMatrixRC< complex<double> >; 371 686 #endif -
trunk/SophyaLib/NTools/tmatrix.h
r302 r304 7 7 #include <stdio.h> 8 8 #include <iostream.h> 9 #include <complex> 9 10 #include "ppersist.h" 10 11 #include "anydataobj.h" 11 12 #include "ndatablock.h" 13 12 14 class GeneralFit; 13 15 14 16 namespace PlanckDPC { 15 17 18 template <class T> class TVector; 19 template <class T> class TMatrixRC; 20 16 21 template <class T> 17 22 class TMatrix : public AnyDataObj { 23 friend class TMatrixRC<T>; 24 friend class TVector<T>; 18 25 public: 19 26 … … 105 112 ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.); 106 113 114 // Acces aux rangees et colonnes 115 TMatrixRC<T> Row(uint_4 r) const; 116 TMatrixRC<T> Col(uint_4 c) const; 117 TMatrixRC<T> Diag() const; 118 107 119 protected: 108 120 // partage les donnees si "a" temporaire, clone sinon. … … 184 196 }; 185 197 198 ///////////////////////////////////////////////////////////////////////// 199 // Classe de lignes/colonnes de matrices 200 enum TRCKind {TmatrixRow=0, TmatrixCol=1, TmatrixDiag=2}; 201 template <class T> 202 class TMatrixRC { 203 friend class TVector<T>; 204 friend class TMatrix<T>; 205 public: 206 TMatrixRC(); 207 208 virtual ~TMatrixRC() {} 209 210 int_4 Next(); 211 int_4 Prev(); 212 int_4 SetCol(int_4 c); 213 int_4 SetRow(int_4 r); 214 int_4 SetDiag(); 215 216 static uint_4 Step(const TMatrix<T>& m, TRCKind rckind); 217 static T* Org(const TMatrix<T>&, TRCKind rckind, uint_4 ind=0); 218 219 uint_4 NElts() const; 220 T& operator()(uint_4 i); 221 T operator()(uint_4 i) const; 222 223 TMatrixRC<T>& operator = (const TMatrixRC<T>& rc); 224 TVector<T> GetVect() const; 225 226 TMatrixRC<T>& operator += (const TMatrixRC<T>& rc); 227 TMatrixRC<T>& operator -= (const TMatrixRC<T>& rc); 228 229 TMatrixRC<T>& operator *= (T x); 230 TMatrixRC<T>& operator /= (T x); 231 TMatrixRC<T>& operator -= (T x); 232 TMatrixRC<T>& operator += (T x); 233 234 TMatrixRC<T>& LinComb(T a, T b, const TMatrixRC& rc, uint_4 first=0); 235 TMatrixRC<T>& LinComb(T b, const TMatrixRC<T>& rc, uint_4 first=0); 236 237 uint_4 IMaxAbs(uint_4 first=0); 238 239 static void Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2); 240 241 protected: 242 TMatrixRC(TMatrix<T>& m, TRCKind kind, uint_4 index=0); 243 TMatrix<T>* matrix; 244 inline static double Abs_Value(uint_1 v) {return (double) v;} 245 inline static double Abs_Value(uint_2 v) {return (double) v;} 246 inline static double Abs_Value(int_2 v) {return (v>0)? (double) v: (double) -v;} 247 inline static double Abs_Value(int_4 v) {return (v>0)? (double) v: (double) -v;} 248 inline static double Abs_Value(int_8 v) {return (v>0)? (double) v: (double) -v;} 249 inline static double Abs_Value(uint_4 v) {return (double) v;} 250 inline static double Abs_Value(uint_8 v) {return (double) v;} 251 inline static double Abs_Value(r_4 v) {return (double) fabsf(v);} 252 inline static double Abs_Value(r_8 v) {return fabs(v);} 253 inline static double Abs_Value(complex<float> v) 254 {return sqrt(v.real()*v.real()+v.imag()*v.imag());} 255 inline static double Abs_Value(complex<double> v) 256 {return sqrt(v.real()*v.real()+v.imag()*v.imag());} 257 258 T* data; 259 int_4 index; 260 uint_4 step; 261 TRCKind kind; 262 }; 263 264 265 template <class T> inline T operator * (const TMatrixRC<T>& a, const TMatrixRC<T>& b) 266 { 267 if ( a.NElts() != b.NElts() ) 268 throw(SzMismatchError("TMatrixRC::operator * size mismatch\n")); 269 if ( a.kind != b.kind ) 270 throw(SzMismatchError("TMatrixRC::operator * type mismatch\n")); 271 T sum = 0; 272 for(uint_4 i=0; i<a.NElts(); i++) sum += a(i)*b(i); 273 return sum; 274 } 275 276 template <class T> 277 inline uint_4 TMatrixRC<T>::Step(const TMatrix<T>& m, TRCKind rckind) 278 { switch (rckind) { case TmatrixRow : return 1; 279 case TmatrixCol : return m.mNc; 280 case TmatrixDiag : return m.mNc+1; } 281 return 0; } 282 283 template <class T> 284 inline T* TMatrixRC<T>::Org(const TMatrix<T>& m, TRCKind rckind, uint_4 index) 285 { switch (rckind) { case TmatrixRow : return const_cast<T *>(m.Data()) + index * m.mNc; 286 case TmatrixCol : return const_cast<T *>(m.Data()) + index; 287 case TmatrixDiag : return const_cast<T *>(m.Data()); } 288 return NULL; } 289 290 template <class T> inline uint_4 TMatrixRC<T>::NElts() const 291 { if (!matrix) return 0; 292 switch (kind) { case TmatrixRow : return matrix->mNc; 293 case TmatrixCol : return matrix->mNr; 294 case TmatrixDiag : return matrix->mNc; } 295 return 0; } 296 297 template <class T> 298 inline T& TMatrixRC<T>::operator()(uint_4 i) {return data[i*step];} 299 template <class T> 300 inline T TMatrixRC<T>::operator()(uint_4 i) const {return data[i*step];} 301 186 302 } // Fin du namespace 187 303
Note:
See TracChangeset
for help on using the changeset viewer.