// $Id: matrix.cc,v 1.2 1999-04-22 16:18:41 ansari Exp $ #include "machdefs.h" #include #include #include #include #include "peida.h" #include "matrix.h" #include "cvector.h" #include "generalfit.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 Matrix // Lib Outils++ // include matrix.h // // Classe générale de matrice, calculs matriciels et algèbre linéaire. //-- //++ // Titre Constructeurs //-- //++ Matrix::Matrix() // // Construit une matrice 1x1 (pour ppersist). //-- : nr(1), nc(1), ndata(1), nalloc(1), data(new double[1]) { // if (r<=0 || c<=0) THROW(rangeCheckErr); memset(data, 0, nalloc*sizeof(double)); END_CONSTRUCTOR } //++ Matrix::Matrix(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]) { // if (r<=0 || c<=0) THROW(rangeCheckErr); memset(data, 0, nalloc*sizeof(double)); END_CONSTRUCTOR } //++ Matrix::Matrix(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) { END_CONSTRUCTOR } //++ Matrix::Matrix(const Matrix& 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]) { memcpy(data, a.data, nalloc * sizeof(double)); END_CONSTRUCTOR } Matrix::~Matrix() { DBASSERT(ndata == nr*nc); if (nalloc) delete[] data; } //++ // Titre Méthodes //-- //++ void Matrix::Zero() // // Remise à zero de tous les éléments //-- { DBASSERT(ndata == nr*nc); for (int i=0; i> r >> c; Realloc(r,c); DBASSERT(ndata == nr*nc); s.GetR8s(data, ndata); } MatrixRC::MatrixRC() : matrix(0), data(0), index(0), step(0) {} MatrixRC::MatrixRC(Matrix& 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 MatrixRC::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 MatrixRC::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 MatrixRC::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 MatrixRC::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 MatrixRC::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; } MatrixRC& MatrixRC::operator = (const MatrixRC& rc) { matrix = rc.matrix; data = rc.data; index = rc.index; step = rc.step; kind = rc.kind; return *this; } //MatrixRC::operator Vector() const Vector MatrixRC::GetVect() const #if HAS_NAMED_RETURN return v(NElts()) #endif { #if !HAS_NAMED_RETURN Vector 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 MatrixRC::Swap(MatrixRC& rc1, MatrixRC& 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 << "Matrix warning, overflow for det" << endl; } else { det = exp(ld); } } MatrixRC pivRowa(a,matrixRow); MatrixRC 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; jjValue(x,par.Data()); } return m; } //++ Matrix* Matrix::FitFunction(GeneralFit& gfit) // // Retourne une classe contenant la fonction du fit ``gfit''. // On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j). //-- { if(NCol()<=0||NRows()<=0) return NULL; GeneralFunction* f = gfit.GetFunction(); if(f==NULL) return NULL; Vector par = gfit.GetParm(); Matrix* m = new Matrix(*this); for(int i=0;iValue(x,par.Data()); } return m; }