Changeset 304 in Sophya for trunk/SophyaLib/NTools/tmatrix.cc
- Timestamp:
- May 18, 1999, 7:19:37 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.