// This may look like C code, but it is really -*- C++ -*- #ifndef SOpeMatrix_SEEN #define SOpeMatrix_SEEN #include "machdefs.h" #include "tmatrix.h" #include "tvector.h" //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //------------------------------------------------------------// // Classe TMatrixRC // //------------------------------------------------------------// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// namespace SOPHYA { /*! \class SimpleMatrixOperation \ingroup TArray Class for simple operation on TMatrix \sa TMatrix TArray */ //! Class for simple operation on TMatrix template class SimpleMatrixOperation { public: static TMatrix Inverse(TMatrix const & A); static T GausPiv(TMatrix& A, TMatrix& B); }; } // Fin du namespace //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //------------------------------------------------------------// // Resolution de systemes lineaires // //------------------------------------------------------------// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// namespace SOPHYA { //------------------------------------------------------------ // Resolution du systeme A*C = B //------------------------------------------------------------ //! Solve A*C = B for C in place and return determinant /*! \ingroup TArray \fn LinSolveInPlace */ inline r_4 LinSolveInPlace(TMatrix& a, TVector& b) { if(a.NCols() != b.NRows() || a.NCols() != a.NRows()) throw(SzMismatchError("LinSolveInPlace(TMatrix,TVector) size mismatch")); return SimpleMatrixOperation::GausPiv(a,b); } //! Solve A*X = B in place and return determinant /*! \ingroup TArray \fn LinSolveInPlace */ inline r_8 LinSolveInPlace(TMatrix& a, TVector& b) { if(a.NCols() != b.NRows() || a.NCols() != a.NRows()) throw(SzMismatchError("LinSolveInPlace(TMatrix,TVector) size mismatch")); return SimpleMatrixOperation::GausPiv(a,b); } //! Solve A*X = B in place and return determinant /*! \ingroup TArray \fn LinSolveInPlace */ inline complex LinSolveInPlace(TMatrix< complex >& a, TVector< complex >& b) { if(a.NCols() != b.NRows() || a.NCols() != a.NRows()) throw(SzMismatchError("LinSolveInPlace(TMatrix< complex >,TVector< complex >) size mismatch")); return SimpleMatrixOperation< complex >::GausPiv(a,b); } //! Solve A*X = B in place and return determinant /*! \ingroup TArray \fn LinSolveInPlace */ inline complex LinSolveInPlace(TMatrix< complex >& a, TVector< complex >& b) { if(a.NCols() != b.NRows() || a.NCols() != a.NRows()) throw(SzMismatchError("LinSolveInPlace(TMatrix< complex >,TVector< complex >) size mismatch")); return SimpleMatrixOperation< complex >::GausPiv(a,b); } //------------------------------------------------------------ // Resolution du systeme A*C = B, avec C retourne dans B //------------------------------------------------------------ //! Solve A*C = B and return C and determinant /*! \ingroup TArray \fn LinSolve */ inline r_4 LinSolve(const TMatrix& a, const TVector& b, TVector& c) { if(a.NCols()!=b.NRows() || a.NCols()!=a.NRows()) throw(SzMismatchError("LinSolve(TMatrix,TVector) size mismatch")); c = b; TMatrix a1(a); return SimpleMatrixOperation::GausPiv(a1,c); } //! Solve A*C = B and return C and determinant /*! \ingroup TArray \fn LinSolve */ inline r_8 LinSolve(const TMatrix& a, const TVector& b, TVector& c) { if(a.NCols()!=b.NRows() || a.NCols()!=a.NRows()) throw(SzMismatchError("LinSolve(TMatrix,TVector) size mismatch")); c = b; TMatrix a1(a); return SimpleMatrixOperation::GausPiv(a1,c); } //! Solve A*C = B and return C and determinant /*! \ingroup TArray \fn LinSolve */ inline complex LinSolve(const TMatrix< complex >& a, const TVector< complex >& b, TVector< complex >& c) { if(a.NCols()!=b.NRows() || a.NCols()!=a.NRows()) throw(SzMismatchError("LinSolve(TMatrix< complex >,TVector< complex >) size mismatch")); c = b; TMatrix< complex > a1(a); return SimpleMatrixOperation< complex >::GausPiv(a1,c); } //! Solve A*C = B and return C and determinant /*! \ingroup TArray \fn LinSolve */ inline complex LinSolve(const TMatrix< complex >& a, const TVector< complex >& b, TVector< complex >& c) { if(a.NCols()!=b.NRows() || a.NCols()!=a.NRows()) throw(SzMismatchError("LinSolve(TMatrix< complex >,TVector< complex >) size mismatch")); c = b; TMatrix< complex > a1(a); return SimpleMatrixOperation< complex >::GausPiv(a1,c); } } // Fin du namespace //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //------------------------------------------------------------// // Inverse d'une matrice // //------------------------------------------------------------// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// namespace SOPHYA { //! To inverse a TMatrix /*! \ingroup TArray \fn Inverse */ inline TMatrix Inverse(TMatrix const & A) {return SimpleMatrixOperation::Inverse(A);} //! To inverse a TMatrix /*! \ingroup TArray \fn Inverse */ inline TMatrix Inverse(TMatrix const & A) {return SimpleMatrixOperation::Inverse(A);} //! To inverse a TMatrix /*! \ingroup TArray \fn Inverse */ inline TMatrix< complex > Inverse(TMatrix< complex > const & A) {return SimpleMatrixOperation< complex >::Inverse(A);} //! To inverse a TMatrix /*! \ingroup TArray \fn Inverse */ inline TMatrix< complex > Inverse(TMatrix< complex > const & A) {return SimpleMatrixOperation< complex >::Inverse(A);} } // Fin du namespace //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //------------------------------------------------------------// // Linear fitting // //------------------------------------------------------------// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// namespace SOPHYA { /*! \class LinFitter \ingroup TArray Class for linear fitting \sa TMatrix TArray */ //! Class for linear fitting class LinFitter { public : LinFitter(); virtual ~LinFitter(); double LinFit(const Vector& x, const Vector& y, int nf, double (*f)(int, double), Vector& c); // fit lineaire des y en tant que somme de c(i)f(i,x), i=0..nf-1; double LinFit(const Matrix& fx, const Vector& y, Vector& c); // fit lineaire des y en tant que somme de c(i)f(i,x), i=0..nf-1, // la matrice fx contient les valeurs des f: // fx(i,j) = f(i, x(j)). double LinFit(const Vector& x, const Vector& y, const Vector& errY2, int nf, double (*f)(int, double), Vector& c, Vector& errC); // fit lineaire des y en tant que somme de c(i)f(i,x), i=0..nf-1, // errY2 contient les carres des erreurs sur les Y. // au retour, errC contient les erreurs sur les coefs. double LinFit(const Matrix& fx, const Vector& y, const Vector& errY2, Vector& c, Vector& errC); // fit lineaire des y en tant que somme de c(i)f(i,x), i=0..nf-1, // la matrice fx contient les valeurs des f: // fx(i,j) = f(i, x(j)). // errY2 contient les carres des erreurs sur les Y. // au retour, errC contient les erreurs sur les coefs. }; } // Fin du namespace #endif