Changeset 1007 in Sophya for trunk/SophyaLib/TArray/sopemtx.cc
- Timestamp:
- May 16, 2000, 7:54:20 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/TArray/sopemtx.cc
r999 r1007 438 438 #define M_LN2 0.69314718055994530942 439 439 #endif 440 //// CMV BUG BUG : sur OSF 5.0 DMINEXP est deconnant (~1.e+19 !!!) 440 441 #ifndef LN_MINDOUBLE 441 442 #define LN_MINDOUBLE (M_LN2 * (DMINEXP - 1)) … … 445 446 #endif 446 447 448 template <class T> 449 int SimpleMatrixOperation<T>::GausPivScaling = PIV_GLOB_SCALE; 450 447 451 //! Gaussian pivoting 448 452 /*! 449 453 Do Gauss pivoting of \b a, doing the same operations on matrix \b b 450 \return determinant of \b a. 454 \param computedet = true : return determimant of \b a (beware of over/underfloat) 455 \param computedet = false : return 1 if OK, 0 if not. 451 456 \verbatim 452 457 Solve linear system A(n,n) * X(n,m) = B(n,m) … … 457 462 */ 458 463 template <class T> 459 T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b )464 T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b,bool computedet) 460 465 // Pivot de Gauss 461 466 // * Attention: egcs impose que cette fonction soit mise dans le .cc … … 466 471 if(n!=b.NRows()) 467 472 throw(SzMismatchError("TMatrix::GausPiv size mismatch\n")); 468 // On fait une normalisation un peu brutale...469 double vmin=MAXDOUBLE;470 double vmax=0;471 for(uint_4 iii=0; iii<a.NRows(); iii++)472 for(uint_4 jjj=0; jjj<a.NCols(); jjj++) {473 double v = TMatrixRC<T>::Abs_Value(a(iii,jjj));474 if(v>vmax) vmax = v;475 if(v<vmin && v>0) vmin = v;476 }477 double nrm = sqrt(vmin*vmax);478 if(nrm > 1.e5 || nrm < 1.e-5) {479 a /= (T) nrm;480 b /= (T) nrm;481 //cout << "normalisation matrice " << nrm << endl;482 } else nrm=1;483 473 484 474 T det = 1; 485 if(nrm != 1) { 486 double ld = a.NRows() * log(nrm); 487 if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) { 488 // cerr << "TMatrix warning, overflow for det" << endl; 489 } else { 490 det = (T) exp(ld); 491 } 492 } 475 476 ////////////////// 477 // Data scaling // 478 ////////////////// 479 480 // Pas de normalisation des donnees 481 if(GausPivScaling==PIV_NO_SCALE) { 482 if(computedet) det = (T) 1; 483 // normalisation des donnees ligne par ligne 484 } else if(GausPivScaling==PIV_ROW_SCALE) { 485 double nrm = 0.; 486 for(uint_4 iii=0; iii<a.NRows(); iii++) { 487 uint_4 jjj; double vmax = -1.; 488 for(jjj=0; jjj<a.NCols(); jjj++) { 489 double v = TMatrixRC<T>::Abs_Value(a(iii,jjj)); 490 if(v>vmax) vmax = v; 491 } 492 if(vmax>0.) { 493 for(jjj=0; jjj<a.NCols(); jjj++) a(iii,jjj) /= (T) vmax; 494 for(jjj=0; jjj<b.NCols(); jjj++) b(iii,jjj) /= (T) vmax; 495 nrm += log(vmax); 496 } else return (T) 0; 497 } 498 if(computedet) { 499 if(nrm <= LN_MINDOUBLE || nrm >= LN_MAXDOUBLE) { 500 cerr<<"GausPiv_Row: normalisation failure, " 501 <<"determinant has to be multiplied by exp("<<nrm<<")"<<endl; 502 } else det = (T) exp(nrm); 503 } 504 // On fait une normalisation un peu brutale globale 505 } else { 506 double vmin=MAXDOUBLE, vmax=0; 507 for(uint_4 iii=0; iii<a.NRows(); iii++) 508 for(uint_4 jjj=0; jjj<a.NCols(); jjj++) { 509 double v = TMatrixRC<T>::Abs_Value(a(iii,jjj)); 510 if(v>vmax) vmax = v; 511 if(v<vmin && v>0.) vmin = v; 512 } 513 double nrm = sqrt(vmin*vmax); 514 if(nrm>0.) { a /= (T) nrm; b /= (T) nrm;} else return (T) 0; 515 if(computedet) { 516 nrm = a.NRows() * log(nrm); 517 if (nrm <= LN_MINDOUBLE || nrm >= LN_MAXDOUBLE) { 518 cerr<<"GausPiv_Glob: normalisation failure, " 519 <<"determinant has to be multiplied by exp("<<nrm<<")"<<endl; 520 } else det = (T) exp(nrm); 521 } 522 } 523 524 //////////////////////////////////////// 525 // Gaussian elimination with pivoting // 526 //////////////////////////////////////// 493 527 494 528 TMatrixRC<T> pivRowa(a,TMatrixRC<T>::TmatrixRow); … … 507 541 T pivot = a(k,k); 508 542 if( TMatrixRC<T>::Abs_Value(pivot) < 1.e-50 ) return (T) 0; 509 //det *= pivot;543 if(computedet) det *= pivot; 510 544 pivRowa.SetRow(k); // to avoid constructors 511 545 pivRowb.SetRow(k); … … 516 550 } 517 551 } 518 det *= a(n-1, n-1);552 if(computedet) det *= a(n-1, n-1); 519 553 520 554 // on remonte … … 545 579 TMatrix<T> a(A,false); 546 580 TMatrix<T> b(a.NCols(),a.NRows()); b = IdentityMatrix(1.); 547 if( TMatrixRC<T>::Abs_Value(GausPiv(a,b)) < 1.e-50)581 if(GausPiv(a,b)==(T) 0) 548 582 throw(MathExc("TMatrix Inverse() Singular Matrix")); 549 583 b.SetTemp(true); … … 620 654 a(j,k) = a(k,j) = TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), j) 621 655 * TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), k); 622 /* $CHECK$ Reza 10/3/2000 */623 656 624 657 c = fx * y; 625 658 626 659 if(SimpleMatrixOperation<T>::GausPiv(a,c)==(T) 0) THROW(singMatxErr); 627 /* $CHECK$ Reza 10/3/2000 */628 660 629 661 r_8 xi2 = 0., ax; … … 718 750 719 751 if(SimpleMatrixOperation<T>::GausPiv(a,d)==(T) 0) THROW(singMatxErr); 720 /* $CHECK$ Reza 10/3/2000 */721 752 722 753 for(uint_4 l=0; l<nf; l++) { … … 806 837 #endif 807 838 808 809 810 811 812 813 814 815 816 817 818 819
Note:
See TracChangeset
for help on using the changeset viewer.