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
|
---|