[772] | 1 | // This may look like C code, but it is really -*- C++ -*-
|
---|
| 2 | #ifndef SOpeMatrix_SEEN
|
---|
| 3 | #define SOpeMatrix_SEEN
|
---|
| 4 |
|
---|
| 5 | #include "machdefs.h"
|
---|
| 6 | #include "tmatrix.h"
|
---|
| 7 | #include "tvector.h"
|
---|
| 8 |
|
---|
| 9 | namespace SOPHYA {
|
---|
| 10 |
|
---|
| 11 | /////////////////////////////////////////////////////////////////////////
|
---|
| 12 | // Classe de lignes/colonnes de matrices
|
---|
| 13 | enum TRCKind {TmatrixRow=0, TmatrixCol=1, TmatrixDiag=2};
|
---|
| 14 | template <class T>
|
---|
| 15 | class TMatrixRC {
|
---|
| 16 | public:
|
---|
| 17 | TMatrixRC();
|
---|
| 18 | TMatrixRC(TMatrix<T>& m, TRCKind kind, uint_4 index=0);
|
---|
| 19 | virtual ~TMatrixRC() {}
|
---|
| 20 |
|
---|
| 21 | // Acces aux rangees et colonnes de matrices
|
---|
| 22 | static TMatrixRC<T> Row(TMatrix<T> & m, uint_4 r);
|
---|
| 23 | static TMatrixRC<T> Col(TMatrix<T> & m, uint_4 c);
|
---|
| 24 | static TMatrixRC<T> Diag(TMatrix<T> & m);
|
---|
| 25 |
|
---|
| 26 | int_4 Next();
|
---|
| 27 | int_4 Prev();
|
---|
| 28 | int_4 SetCol(int_4 c);
|
---|
| 29 | int_4 SetRow(int_4 r);
|
---|
| 30 | int_4 SetDiag();
|
---|
| 31 |
|
---|
| 32 | static uint_4 Step(const TMatrix<T>& m, TRCKind rckind);
|
---|
| 33 | static T* Org(const TMatrix<T>&, TRCKind rckind, uint_4 ind=0);
|
---|
| 34 |
|
---|
| 35 | TRCKind Kind() const { return kind; }
|
---|
| 36 | uint_4 NElts() const;
|
---|
| 37 | T& operator()(uint_4 i);
|
---|
| 38 | T operator()(uint_4 i) const;
|
---|
| 39 |
|
---|
| 40 | TMatrixRC<T>& operator = (const TMatrixRC<T>& rc);
|
---|
| 41 | TVector<T> GetVect() const;
|
---|
| 42 |
|
---|
| 43 | TMatrixRC<T>& operator += (const TMatrixRC<T>& rc);
|
---|
| 44 | TMatrixRC<T>& operator -= (const TMatrixRC<T>& rc);
|
---|
| 45 |
|
---|
| 46 | TMatrixRC<T>& operator *= (T x);
|
---|
| 47 | TMatrixRC<T>& operator /= (T x);
|
---|
| 48 | TMatrixRC<T>& operator -= (T x);
|
---|
| 49 | TMatrixRC<T>& operator += (T x);
|
---|
| 50 |
|
---|
| 51 | TMatrixRC<T>& LinComb(T a, T b, const TMatrixRC& rc, uint_4 first=0);
|
---|
| 52 | TMatrixRC<T>& LinComb(T b, const TMatrixRC<T>& rc, uint_4 first=0);
|
---|
| 53 |
|
---|
| 54 | uint_4 IMaxAbs(uint_4 first=0);
|
---|
| 55 |
|
---|
| 56 | static void Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2);
|
---|
| 57 |
|
---|
| 58 | inline static double Abs_Value(uint_1 v) {return (double) v;}
|
---|
| 59 | inline static double Abs_Value(uint_2 v) {return (double) v;}
|
---|
| 60 | inline static double Abs_Value(int_2 v) {return (v>0)? (double) v: (double) -v;}
|
---|
| 61 | inline static double Abs_Value(int_4 v) {return (v>0)? (double) v: (double) -v;}
|
---|
| 62 | inline static double Abs_Value(int_8 v) {return (v>0)? (double) v: (double) -v;}
|
---|
| 63 | inline static double Abs_Value(uint_4 v) {return (double) v;}
|
---|
| 64 | inline static double Abs_Value(uint_8 v) {return (double) v;}
|
---|
| 65 | inline static double Abs_Value(r_4 v) {return (double) fabsf(v);}
|
---|
| 66 | inline static double Abs_Value(r_8 v) {return fabs(v);}
|
---|
| 67 | inline static double Abs_Value(complex<float> v)
|
---|
| 68 | {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
|
---|
| 69 | inline static double Abs_Value(complex<double> v)
|
---|
| 70 | {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
|
---|
| 71 |
|
---|
| 72 | protected:
|
---|
| 73 | TMatrix<T>* matrix;
|
---|
| 74 | T* data;
|
---|
| 75 | int_4 index;
|
---|
| 76 | uint_4 step;
|
---|
| 77 | TRCKind kind;
|
---|
| 78 | };
|
---|
| 79 |
|
---|
| 80 |
|
---|
| 81 | template <class T>
|
---|
| 82 | inline T operator * (const TMatrixRC<T>& a, const TMatrixRC<T>& b)
|
---|
| 83 | {
|
---|
| 84 | if ( a.NElts() != b.NElts() )
|
---|
| 85 | throw(SzMismatchError("TMatrixRC::operator * size mismatch\n"));
|
---|
| 86 | if ( a.Kind() != b.Kind() )
|
---|
| 87 | throw(SzMismatchError("TMatrixRC::operator * type mismatch\n"));
|
---|
| 88 | T sum = 0;
|
---|
| 89 | for(uint_4 i=0; i<a.NElts(); i++) sum += a(i)*b(i);
|
---|
| 90 | return sum;
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | template <class T>
|
---|
| 94 | inline uint_4 TMatrixRC<T>::Step(const TMatrix<T>& m, TRCKind rckind)
|
---|
| 95 | { switch (rckind) { case TmatrixRow : return 1;
|
---|
| 96 | case TmatrixCol : return m.NCols();
|
---|
| 97 | case TmatrixDiag : return m.NCols()+1; }
|
---|
| 98 | return 0; }
|
---|
| 99 |
|
---|
| 100 | template <class T>
|
---|
| 101 | inline T* TMatrixRC<T>::Org(const TMatrix<T>& m, TRCKind rckind, uint_4 index)
|
---|
| 102 | { switch (rckind) { case TmatrixRow : return const_cast<T *>(m.Data()) + index * m.NCols();
|
---|
| 103 | case TmatrixCol : return const_cast<T *>(m.Data()) + index;
|
---|
| 104 | case TmatrixDiag : return const_cast<T *>(m.Data()); }
|
---|
| 105 | return NULL; }
|
---|
| 106 |
|
---|
| 107 | template <class T> inline uint_4 TMatrixRC<T>::NElts() const
|
---|
| 108 | { if (!matrix) return 0;
|
---|
| 109 | switch (kind) { case TmatrixRow : return matrix->NCols();
|
---|
| 110 | case TmatrixCol : return matrix->NRows();
|
---|
| 111 | case TmatrixDiag : return matrix->NCols(); }
|
---|
| 112 | return 0; }
|
---|
| 113 |
|
---|
| 114 | template <class T>
|
---|
| 115 | inline T& TMatrixRC<T>::operator()(uint_4 i) {return data[i*step];}
|
---|
| 116 | template <class T>
|
---|
| 117 | inline T TMatrixRC<T>::operator()(uint_4 i) const {return data[i*step];}
|
---|
| 118 |
|
---|
| 119 | ////////////////////////////////////////////////////////////////
|
---|
| 120 | // Typedef pour simplifier et compatibilite Peida
|
---|
| 121 | typedef TMatrixRC<r_8> MatrixRC;
|
---|
| 122 |
|
---|
| 123 | ////////////////////////////////////////////////////////////////
|
---|
| 124 | template <class T>
|
---|
| 125 | class SimpleMatrixOperation {
|
---|
| 126 | public:
|
---|
| 127 | // Pivot de Gauss : diagonalise la matrice A, en effectuant les memes
|
---|
| 128 | // operations sur la matrice B
|
---|
| 129 | static TMatrix<T> Inverse(TMatrix<T> const & A);
|
---|
| 130 | static T GausPiv(TMatrix<T>& A, TMatrix<T>& B);
|
---|
| 131 | };
|
---|
| 132 |
|
---|
| 133 | // Resolution du systeme A*C = B
|
---|
| 134 | inline r_8 LinSolveInPlace(TMatrix<r_8>& a, TVector<r_8>& b)
|
---|
| 135 | {
|
---|
| 136 | if(a.NCols() != b.NRows() || a.NCols() != a.NRows())
|
---|
| 137 | throw(SzMismatchError("LinSolveInPlace(TMatrix<r_8>,TVector<r_8>) size mismatch"));
|
---|
| 138 | return SimpleMatrixOperation<r_8>::GausPiv(a,b);
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | // Resolution du systeme A*C = B, avec C retourne dans B
|
---|
| 142 | inline r_8 LinSolve(const TMatrix<r_8>& a, const TVector<r_8>& b, TVector<r_8>& c)
|
---|
| 143 | {
|
---|
| 144 | if(a.NCols() != b.NRows() || a.NCols() != a.NRows())
|
---|
| 145 | throw(SzMismatchError("LinSolve(TMatrix<r_8>,TVector<r_8>) size mismatch"));
|
---|
| 146 | c = b;
|
---|
| 147 | TMatrix<r_8> a1(a);
|
---|
| 148 | return SimpleMatrixOperation<r_8>::GausPiv(a1,c);
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 |
|
---|
| 152 | } // Fin du namespace
|
---|
| 153 |
|
---|
| 154 | #endif
|
---|