Changeset 304 in Sophya


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

Location:
trunk/SophyaLib/NTools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/NTools/cvector.h

    r303 r304  
    66
    77class GeneralFit;
    8 #include "tvector.h"
    9 //cmv template <class T> class TVector;
     8namespace PlanckDPC {template <class T> class TVector;}
    109
    1110// <summary> Vecteur colonne pour operations matricielles </summary>
  • trunk/SophyaLib/NTools/matrix.h

    r288 r304  
    1212
    1313class GeneralFit;
    14 #include "tmatrix.h"
    15 //cmv template <class T> class TMatrix;
     14namespace PlanckDPC {template <class T> class TMatrix;}
    1615
    1716// <summary> Operations matricielles </summary>
  • 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
  • trunk/SophyaLib/NTools/tmatrix.h

    r302 r304  
    77#include <stdio.h>
    88#include <iostream.h>
     9#include <complex>
    910#include "ppersist.h"
    1011#include "anydataobj.h"
    1112#include "ndatablock.h"
     13
    1214class GeneralFit;
    1315
    1416namespace PlanckDPC {
    1517
     18template <class T> class TVector;
     19template <class T> class TMatrixRC;
     20
    1621template <class T>
    1722class TMatrix : public AnyDataObj {
     23  friend class TMatrixRC<T>;
     24  friend class TVector<T>;
    1825public:
    1926
     
    105112            ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
    106113
     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
    107119protected:
    108120  // partage les donnees si "a" temporaire, clone sinon.
     
    184196};
    185197
     198/////////////////////////////////////////////////////////////////////////
     199// Classe de lignes/colonnes de matrices
     200enum TRCKind {TmatrixRow=0, TmatrixCol=1, TmatrixDiag=2};
     201template <class T>
     202class TMatrixRC {
     203  friend class TVector<T>;
     204  friend class TMatrix<T>;
     205public:
     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
     241protected:
     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
     265template <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
     276template <class T>
     277inline 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
     283template <class T>
     284inline 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
     290template <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
     297template <class T>
     298inline T& TMatrixRC<T>::operator()(uint_4 i) {return data[i*step];}
     299template <class T>
     300inline T  TMatrixRC<T>::operator()(uint_4 i) const {return data[i*step];}
     301
    186302} // Fin du namespace
    187303
Note: See TracChangeset for help on using the changeset viewer.