Changeset 304 in Sophya for trunk/SophyaLib/NTools/tmatrix.cc


Ignore:
Timestamp:
May 18, 1999, 7:19:37 PM (26 years ago)
Author:
ansari
Message:

TMatrixRC<T> + GausPiv interne a TMatrix (sans Matrix)
Resolution pb des friend template (namesapce!)
createur Vector a partir de TVector<r_8> cmv 18/5/99

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:24 ansari Exp $
     1// $Id: tmatrix.cc,v 1.8 1999-05-18 17:19:36 ansari Exp $
    22//                         C.Magneville          04/99
    33#include "machdefs.h"
     
    55#include <stdlib.h>
    66#include <iostream.h>
     7#include <values.h>
    78#include <complex>
    89#include "pexceptions.h"
     
    162163}
    163164
     165////////////////////////////////////////////////////////////////
     166//**** Pour gestion des lignes et des colonnes
     167
     168template <class T> TMatrixRC<T> TMatrix<T>::Row(uint_4 r) const
     169{
     170TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixRow, r);
     171return rc;
     172}
     173
     174template <class T> TMatrixRC<T> TMatrix<T>::Col(uint_4 c) const
     175{
     176TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixCol, c);
     177return rc;
     178}
     179
     180template <class T> TMatrixRC<T> TMatrix<T>::Diag() const
     181{
     182TMatrixRC<T> rc((TMatrix<T>&)*this, TmatrixDiag);
     183return rc;
     184}
     185
    164186#include "matrix.h"
    165187////////////////////////////////////////////////////////////////
    166188//**** 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
    167199r_8 TMatrix<r_8>::GausPiv(TMatrix<r_8>& a, TMatrix<r_8>& b)
    168200// Pivot de Gauss
    169201// * Attention: egcs impose que cette fonction soit mise dans le .cc
    170202//              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{
     205uint_4 n = a.NRows();
     206if(n!=b.NRows())
     207  throw(SzMismatchError("TMatrix::GausPiv size mismatch\n"));
     208// On fait une normalisation un peu brutale...
     209double vmin=MAXDOUBLE;
     210double vmax=0;
     211for(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}
     217double nrm = sqrt(vmin*vmax);
     218if(nrm > 1.e5 || nrm < 1.e-5) {
     219  a /= nrm;
     220  b /= nrm;
     221  //cout << "normalisation matrice " << nrm << endl;
     222} else nrm=1;
     223
     224double det = 1.0;
     225if(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
     234TMatrixRC<r_8> pivRowa(a,TmatrixRow);
     235TMatrixRC<r_8> pivRowb(b,TmatrixRow);
     236
     237for(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}
     258det *= a(n-1, n-1);
     259
     260// on remonte
     261for(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
     273for(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
     278return det;
    175279}
    176280
     
    178282// Inversion
    179283{
    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)
     284TMatrix<r_8> b(mNc,mNr); TMatrix<r_8> a(*this); b = 1.;
     285if(fabs(TMatrix<r_8>::GausPiv(a,b)) < 1.e-50)
    184286  throw(MathExc("TMatrix Inverse() Singular Matrix"));
    185287return b;
     
    241343}
    242344
    243 ////////////////////////////////////////////////////////////////
    244 // -------------------------------------------------------------------------
     345///////////////////////////////////////////////////////////
     346// --------------------------------------------------------
    245347//   Les objets delegues pour la gestion de persistance
    246 // -------------------------------------------------------------------------
     348// --------------------------------------------------------
     349///////////////////////////////////////////////////////////
    247350
    248351template <class T>
     
    316419FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
    317420fio_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
     430template <class T> TMatrixRC<T>::TMatrixRC()
     431: matrix(NULL), data(NULL), index(0), step(0)
     432{}
     433
     434template <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{
     438if (kind == TmatrixDiag && m.mNc != m.mNr)
     439  throw(SzMismatchError("TMatrixRC::TMatrixRC(...,TmatrixDiag,...) size mismatch\n"));
     440}
     441
     442template <class T> int_4 TMatrixRC<T>::Next()
     443{
     444if (!matrix || kind==TmatrixDiag) return -1;
     445index++;
     446if(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}
     453return index;
     454}
     455
     456template <class T> int_4 TMatrixRC<T>::Prev()
     457{
     458if (!matrix || kind == TmatrixDiag) return -1;
     459index--;
     460if(index < 0) {index = 0; return -1;}
     461if(kind == TmatrixRow) data -= matrix->mNc;
     462else data--;
     463return index;
     464}
     465
     466template <class T> int_4 TMatrixRC<T>::SetCol(int_4 c)
     467{
     468if(!matrix) return -1;
     469if(c<0 || c>(int_4)matrix->mNc) return -1;
     470kind = TmatrixCol;
     471index = c;
     472step = Step(*matrix, TmatrixCol);
     473data = Org(*matrix, TmatrixCol, c);
     474return c;
     475}
     476
     477template <class T> int_4 TMatrixRC<T>::SetRow(int_4 r)
     478{
     479if(!matrix) return -1;
     480if(r<0 && r>(int_4)matrix->mNr) return -1;
     481kind = TmatrixRow;
     482index = r;
     483step = Step(*matrix, TmatrixRow);
     484data = Org(*matrix, TmatrixRow, r);
     485return r;
     486}
     487
     488template <class T> int_4 TMatrixRC<T>::SetDiag()
     489{
     490if (!matrix) return -1;
     491if (matrix->mNc != matrix->mNr)
     492  throw(SzMismatchError("TMatrixRC::SetDiag size mismatch\n"));
     493kind = TmatrixDiag;
     494index = 0;
     495step = Step(*matrix, TmatrixDiag);
     496data = Org(*matrix, TmatrixDiag);
     497return 0;
     498}
     499
     500
     501template <class T> TMatrixRC<T>& TMatrixRC<T>::operator = (const TMatrixRC<T>& rc)
     502{
     503matrix = rc.matrix;
     504data   = rc.data;
     505index  = rc.index;
     506step   = rc.step;
     507kind   = rc.kind;
     508return *this;
     509}
     510
     511template <class T> TVector<T> TMatrixRC<T>::GetVect() const
     512{
     513TVector<T> v(NElts());
     514for (uint_4 i=0; i<NElts(); i++) v(i) = (*this)(i);
     515return v;
     516}
     517
     518template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (const TMatrixRC<T>& rc)
     519{
     520if ( NElts() != rc.NElts() )
     521  throw(SzMismatchError("TMatrixRC::operator+= size mismatch\n"));
     522if ( kind != rc.kind )
     523  throw(SzMismatchError("TMatrixRC::operator+= type mismatch\n"));
     524for (uint_4 i=0; i<NElts(); i++) (*this)(i) += rc(i);
     525return *this;
     526}
     527
     528template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (const TMatrixRC<T>& rc)
     529{
     530if( NElts() != rc.NElts() )
     531  throw(SzMismatchError("TMatrixRC::operator-= size mismatch\n"));
     532if( kind != rc.kind )
     533  throw(SzMismatchError("TMatrixRC::operator-= type mismatch\n"));
     534for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= rc(i);
     535return *this;
     536}
     537
     538
     539template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x)
     540{
     541for(uint_4 i=0; i<NElts(); i++) (*this)(i) *= x;
     542return *this;
     543}
     544
     545template <class T> TMatrixRC<T>& TMatrixRC<T>::operator /= (T x)
     546{
     547for(uint_4 i=0; i<NElts(); i++) (*this)(i) /= x;
     548return *this;
     549}
     550
     551
     552template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (T x)
     553{
     554for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= x;
     555return *this;
     556}
     557
     558template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (T x)
     559{
     560for(uint_4 i=0; i<NElts(); i++) (*this)(i) += x;
     561return *this;
     562}
     563
     564template <class T>
     565TMatrixRC<T>& TMatrixRC<T>::LinComb(T a, T b, const TMatrixRC<T>& rc, uint_4 first)
     566{
     567if ( NElts() != rc.NElts() )
     568  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
     569if ( kind != rc.kind )
     570  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
     571for(uint_4 i=first; i<NElts(); i++) (*this)(i) = (*this)(i)*a + rc(i)*b;
     572return *this;
     573}
     574
     575template <class T>
     576TMatrixRC<T>& TMatrixRC<T>::LinComb(T b, const TMatrixRC<T>& rc, uint_4 first)
     577{
     578if ( NElts() != rc.NElts() )
     579  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
     580if ( kind != rc.kind )
     581  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
     582for(uint_4 i=first; i<NElts(); i++) (*this)(i) += rc(i)*b;
     583return *this;
     584}
     585
     586template <class T> uint_4 TMatrixRC<T>::IMaxAbs(uint_4 first)
     587{
     588if (first>NElts())
     589  throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n"));
     590uint_4 imax = first;
     591double vmax = Abs_Value((*this)(first));
     592for(uint_4 i=first+1; i<NElts(); i++) {
     593  double v = Abs_Value((*this)(i));
     594  if(v > vmax) {vmax = v; imax = i;}
     595}
     596return imax;
     597}
     598
     599template <class T>
     600void TMatrixRC<T>::Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2)
     601{
     602if(rc1.NElts() != rc2.NElts())
     603  throw(SzMismatchError("TMatrixRC::Swap size mismatch\n"));
     604if(rc1.kind != rc2.kind)
     605  throw(SzMismatchError("TMatrixRC::Swap type mismatch\n"));
     606if(rc1.data == rc2.data) return;
     607for(uint_4 i=0; i<rc1.NElts(); i++)
     608  {T tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;}
    318609}
    319610
     
    343634#pragma define_template FIO_TMatrix< complex<float> >
    344635#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> >
    345648#endif
    346649
     
    369672template class FIO_TMatrix< complex<float> >;
    370673template class FIO_TMatrix< complex<double> >;
     674// Instances gestion lignes/colonnes
     675template class TMatrixRC<uint_1>;
     676template class TMatrixRC<uint_2>;
     677template class TMatrixRC<int_2>;
     678template class TMatrixRC<int_4>;
     679template class TMatrixRC<int_8>;
     680template class TMatrixRC<uint_4>;
     681template class TMatrixRC<uint_8>;
     682template class TMatrixRC<r_4>;
     683template class TMatrixRC<r_8>;
     684template class TMatrixRC< complex<float> >;
     685template class TMatrixRC< complex<double> >;
    371686#endif
Note: See TracChangeset for help on using the changeset viewer.