Changeset 1007 in Sophya for trunk/SophyaLib/TArray/sopemtx.cc


Ignore:
Timestamp:
May 16, 2000, 7:54:20 PM (25 years ago)
Author:
ansari
Message:

gestion det dans GausPiv et new norm cmv 16/5/00

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/TArray/sopemtx.cc

    r999 r1007  
    438438#define M_LN2 0.69314718055994530942
    439439#endif
     440//// CMV BUG BUG : sur OSF 5.0 DMINEXP est deconnant (~1.e+19 !!!)
    440441#ifndef LN_MINDOUBLE
    441442#define LN_MINDOUBLE  (M_LN2 * (DMINEXP - 1))
     
    445446#endif
    446447
     448template <class T>
     449int SimpleMatrixOperation<T>::GausPivScaling = PIV_GLOB_SCALE;
     450
    447451//! Gaussian pivoting
    448452/*!
    449453  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.
    451456  \verbatim
    452457  Solve linear system A(n,n) * X(n,m) = B(n,m)
     
    457462 */ 
    458463template <class T>
    459 T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b)
     464T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b,bool computedet)
    460465// Pivot de Gauss
    461466// * Attention: egcs impose que cette fonction soit mise dans le .cc
     
    466471if(n!=b.NRows())
    467472  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;
    483473
    484474T 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
     481if(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////////////////////////////////////////
    493527
    494528TMatrixRC<T> pivRowa(a,TMatrixRC<T>::TmatrixRow);
     
    507541  T pivot = a(k,k);
    508542  if( TMatrixRC<T>::Abs_Value(pivot) < 1.e-50 ) return (T) 0;
    509   //det *= pivot;
     543  if(computedet) det *= pivot;
    510544  pivRowa.SetRow(k); // to avoid constructors
    511545  pivRowb.SetRow(k);
     
    516550  }
    517551}
    518 det *= a(n-1, n-1);
     552if(computedet) det *= a(n-1, n-1);
    519553
    520554// on remonte
     
    545579TMatrix<T> a(A,false);
    546580TMatrix<T> b(a.NCols(),a.NRows());  b = IdentityMatrix(1.);
    547 if( TMatrixRC<T>::Abs_Value(GausPiv(a,b)) < 1.e-50)
     581if(GausPiv(a,b)==(T) 0)
    548582  throw(MathExc("TMatrix Inverse() Singular Matrix"));
    549583b.SetTemp(true);
     
    620654     a(j,k) = a(k,j) = TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), j)
    621655                     * TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), k);
    622                                 /* $CHECK$ Reza 10/3/2000 */
    623656
    624657c = fx * y;
    625658
    626659if(SimpleMatrixOperation<T>::GausPiv(a,c)==(T) 0) THROW(singMatxErr);
    627                    /* $CHECK$ Reza 10/3/2000 */
    628660
    629661r_8 xi2 = 0., ax;
     
    718750
    719751if(SimpleMatrixOperation<T>::GausPiv(a,d)==(T) 0) THROW(singMatxErr);
    720                                             /* $CHECK$ Reza 10/3/2000 */
    721752
    722753for(uint_4 l=0; l<nf; l++) {
     
    806837#endif
    807838
    808 
    809 
    810 
    811 
    812 
    813 
    814 
    815 
    816 
    817 
    818 
    819 
Note: See TracChangeset for help on using the changeset viewer.