// $Id: matrix.cc,v 1.6 1999-10-25 10:36:09 ansari Exp $ #include "machdefs.h" #include #include #include #include #include "peida.h" #include "matrix.h" #include "cvector.h" #include "generalfit.h" #include "tmatrix.h" // Sous Linux, LN_MAXDOUBLE LN_MINDOUBLE ne semblent pas etre definies // Reza 11/02/99 #ifndef M_LN2 #define M_LN2 0.69314718055994530942 #endif #ifndef LN_MINDOUBLE #define LN_MINDOUBLE (M_LN2 * (DMINEXP - 1)) #endif #ifndef LN_MAXDOUBLE #define LN_MAXDOUBLE (M_LN2 * DMAXEXP) #endif //++ // Class OMatrix // Lib Outils++ // include matrix.h // // Classe générale de matrice, calculs matriciels et algèbre linéaire. //-- //++ // Titre Constructeurs //-- //++ OMatrix::OMatrix() // // Construit une matrice 1x1 (pour ppersist). //-- : nr(1), nc(1), ndata(1), nalloc(1), data(new double[1]), FromTmatrix(false) { // if (r<=0 || c<=0) THROW(rangeCheckErr); memset(data, 0, nalloc*sizeof(double)); END_CONSTRUCTOR } //++ OMatrix::OMatrix(int r, int c) // // Construit une matrice de r lignes et c colonnes. //-- : nr(r), nc(c), ndata(r*c), nalloc(r*c), data(new double[r*c]), FromTmatrix(false) { // if (r<=0 || c<=0) THROW(rangeCheckErr); memset(data, 0, nalloc*sizeof(double)); END_CONSTRUCTOR } //++ OMatrix::OMatrix(int r, int c, double* values) // // Construit une matrice de r lignes et c colonnes. On fournit // le tableau des valeurs : pas d'allocation. //-- : nr(r), nc(c), ndata(r*c), nalloc(0), data(values), FromTmatrix(false) { END_CONSTRUCTOR } //++ OMatrix::OMatrix(const OMatrix& a) // // Constructeur par copie. //-- : nr(a.nr), nc(a.nc), ndata(a.nr*a.nc), nalloc(a.nr*a.nc), data(new double[a.nr*a.nc]), FromTmatrix(false) { memcpy(data, a.data, nalloc * sizeof(double)); END_CONSTRUCTOR } //++ OMatrix::OMatrix(const TMatrix& a) // // Constructeur par copie a partir d'une TMatrix. // Attention, les donnees sont partagees. //-- : nr(a.NRows()), nc(a.NCols()), ndata(a.NRows()*a.NCols()) , nalloc(a.NRows()*a.NCols()) , data(const_cast(a.Data())) , FromTmatrix(true) { END_CONSTRUCTOR } OMatrix::~OMatrix() { DBASSERT(ndata == nr*nc); if (nalloc && !FromTmatrix) delete[] data; } //++ // Titre Méthodes //-- //++ void OMatrix::Zero() // // Remise à zero de tous les éléments //-- { DBASSERT(ndata == nr*nc); for (int i=0; i> r >> c; Realloc(r,c); ASSERT(ndata == nr*nc); s.GetR8s(data, ndata); } OMatrixRC::OMatrixRC() : matrix(0), data(0), index(0), step(0) {} OMatrixRC::OMatrixRC(OMatrix& m, RCKind rckind, int ind) : matrix(&m), data(Org(m,rckind,ind)), index(ind), step(Step(m,rckind)), kind(rckind) { if (kind == matrixDiag & m.nc != m.nr) THROW(sizeMismatchErr); } int OMatrixRC::Next() { if (!matrix) return -1; // Failure ? if (kind == matrixDiag) return -1; // Failure ? index++; if (kind == matrixRow) { if (index > matrix->nr) { index = matrix->nr; return -1; } data += matrix->nc; } else { if (index > matrix->nc) { index = matrix->nc; return -1; } data++; } return index; } int OMatrixRC::Prev() { if (!matrix) return -1; // Failure ? if (kind == matrixDiag) return -1; // Failure ? index--; if (index < 0) { index = 0; return -1; } if (kind == matrixRow) data -= matrix->nc; else data--; return index; } int OMatrixRC::SetCol(int c) { if (!matrix) return -1; // Failure ? if (c<0 || c>matrix->nc) return -1; kind = matrixCol; index = c; step = Step(*matrix, matrixCol); data = Org(*matrix, matrixCol, c); return c; } int OMatrixRC::SetRow(int r) { if (!matrix) return -1; // Failure ? if (r<0 || r>matrix->nr) return -1; kind = matrixRow; index = r; step = Step(*matrix, matrixRow); data = Org(*matrix, matrixRow, r); return r; } int OMatrixRC::SetDiag() { if (!matrix) return -1; // Failure ? if (matrix->nc != matrix->nr) THROW(sizeMismatchErr); kind = matrixDiag; index = 0; step = Step(*matrix, matrixDiag); data = Org(*matrix, matrixDiag); return 0; } OMatrixRC& OMatrixRC::operator = (const OMatrixRC& rc) { matrix = rc.matrix; data = rc.data; index = rc.index; step = rc.step; kind = rc.kind; return *this; } //OMatrixRC::operator OVector() const OVector OMatrixRC::GetVect() const #if HAS_NAMED_RETURN return v(NElts()) #endif { #if !HAS_NAMED_RETURN OVector v(NElts()); #endif int n = NElts(); for (int i=0; in) THROW(rangeCheckErr); int imax=first; double vmax = fabs((*this)(first)); double v; for (int i=first+1; i vmax) { vmax = v; imax = i; } return imax; } void OMatrixRC::Swap(OMatrixRC& rc1, OMatrixRC& rc2) { int n=rc1.NElts(); if (n != rc2.NElts()) THROW(sizeMismatchErr); if (rc1.kind != rc2.kind) THROW(sizeMismatchErr); if (rc1.data == rc2.data) return; // C'est le meme for (int i=0; i vmax) vmax = fabs(a(iii,jjj)); if (fabs(a(iii,jjj)) < vmin && fabs(a(iii,jjj))>0) vmin = fabs(a(iii,jjj)); } double nrm = sqrt(vmin*vmax); if (nrm > 1.e5 || nrm < 1.e-5) { a /= nrm; b /= nrm; //cout << "normalisation matrice " << nrm << endl; } else nrm=1; double det = 1.0; if (nrm != 1) { double ld = a.NRows() * log(nrm); if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) { // cerr << "OMatrix warning, overflow for det" << endl; } else { det = exp(ld); } } OMatrixRC pivRowa(a,matrixRow); OMatrixRC pivRowb(b,matrixRow); for (int k=0; k0; kk--) { double pivot = a(kk,kk); if (fabs(pivot) <= 1.e-50) return 0.0; pivRowa.SetRow(kk); // to avoid constructors pivRowb.SetRow(kk); for (int jj=0; jj x = xorg + j*dx , y = yorg + i*dy //-- { if(NCol()<=0||NRows()<=0) throw(SzMismatchError("OMatrix::FitResidus: size mismatch\n")); GeneralFunction* f = gfit.GetFunction(); if(f==NULL) throw(NullPtrError("OMatrix::FitResidus: NULL pointer\n")); OVector par = gfit.GetParm(); OMatrix m(*this); for(int i=0;iValue(x,par.Data()); } return m; } //++ OMatrix OMatrix::FitFunction(GeneralFit& gfit ,double xorg,double yorg,double dx,double dy) // // Retourne une classe contenant la fonction du fit ``gfit''. // Les coordonnees de l'element (i,j) sont : // (i,j) -> x = xorg + j*dx , y = yorg + i*dy //-- { if(NCol()<=0||NRows()<=0) throw(SzMismatchError("OMatrix::FitFunction: size mismatch\n")); GeneralFunction* f = gfit.GetFunction(); if(f==NULL) throw(NullPtrError("OMatrix::FitFunction: NULL pointer\n")); OVector par = gfit.GetParm(); OMatrix m(*this); for(int i=0;iValue(x,par.Data()); } return m; }