source: Sophya/trunk/SophyaLib/NTools/matrix.h@ 304

Last change on this file since 304 was 304, checked in by ansari, 26 years ago

TMatrixRC<T> + GausPiv interne a TMatrix (sans Matrix)
Resolution pb des friend template (namesapce!)
createur Vector a partir de TVector<r_8> cmv 18/5/99

File size: 7.5 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2// Eric Aubourg, Septembre 94
3#ifndef MATRIX_SEEN
4#define MATRIX_SEEN
5
6#define RGCHECK
7
8#include <stdio.h>
9#include <iostream.h>
10#include "peida.h"
11#include "ppersist.h"
12
13class GeneralFit;
14namespace PlanckDPC {template <class T> class TMatrix;}
15
16// <summary> Operations matricielles </summary>
17// Operations matricielles, algebre lineaire...
18class Matrix : public PPersist {
19 friend class Vector;
20 friend class MatrixRC;
21 friend class TMatrix<r_8>;
22public:
23 Matrix();
24 // Constructeur, matrice a zero
25 Matrix(int r, int c);
26 // Constructeur avec des valeurs. Pas d'allocation, juste pointe.
27 Matrix(int r, int c, double* values);
28 // Constructeur par copie
29 Matrix(const Matrix& a);
30 // Constructeur par copie a partir d'une TMatrix<r_8>
31 Matrix(const TMatrix<r_8>& a);
32 // Destructeur
33 virtual ~Matrix();
34
35 // Construction automatique pour PPF
36 // <group>
37 enum {classId = ClassId_Matrix};
38 int_4 ClassId() const { return classId; }
39 static PPersist* Create() {return new Matrix(1,1);}
40 // </group>
41
42 // Remise a zero de tous les elements
43 void Zero();
44 // Change la taille de la matrice. Reallocation physique seulement si
45 // pas assez de place, ou forcee si force=true
46 void Realloc(int r, int c, bool force=false);
47
48 // Operateur d'affectation
49 Matrix& operator = (const Matrix& a);
50 // Affectation depuis scalaire : identite * scalaire
51 Matrix& operator = (double x);
52
53 // Impression
54 friend ostream& operator << (ostream& s, const Matrix& a);
55
56 // Acces aux elements
57 // <group>
58 r_8& operator()(int r, int c);
59 r_8 const& operator()(int r, int c) const;
60 // </group>
61
62 // Acces au tableau des elements
63 // <group>
64 inline r_8* Data() {return data;}
65 inline const r_8* Data() const {return data;}
66 // </group>
67 // Norme 1 : somme des valeurs absolues
68 double Norm1();
69 // Norme 2, euclidienne
70 double Norm2();
71
72 // Operations matricielles avec scalaire, allocation d'une nouvelle matrice
73 // <group>
74 friend Matrix operator * (const Matrix& a, double b);
75 friend Matrix operator * (double b, const Matrix& a);
76 friend Matrix operator + (const Matrix& a, double b);
77 friend Matrix operator + (double b, const Matrix& a);
78 friend Matrix operator - (const Matrix& a, double b);
79 friend Matrix operator - (double b, const Matrix& a);
80 friend Matrix operator / (const Matrix& a, double b);
81 // </group>
82
83 // Operations matricielles avec scalaires entiers, pour eviter l'appel
84 // du constructeur de vecteur a partir d'un entier...
85 // sinon v*2 = v * Vector(2), BUG !
86 // <group>
87 friend Matrix operator * (const Matrix& a, int b);
88 friend Matrix operator * (int b, const Matrix& a);
89 friend Matrix operator + (const Matrix& a, int b);
90 friend Matrix operator + (int b, const Matrix& a);
91 friend Matrix operator - (const Matrix& a, int b);
92 friend Matrix operator - (int b, const Matrix& a);
93 friend Matrix operator / (const Matrix& a, int b);
94 // </group>
95
96 // Operations matricielles "en place", avec scalaire
97 // <group>
98 Matrix& operator *= (double b);
99 Matrix& operator += (double b);
100 Matrix& operator -= (double b);
101 Matrix& operator /= (double b);
102 // </group>
103
104 // Operations matricielles
105 // <group>
106 friend Matrix operator * (const Matrix& a, const Matrix& b);
107 friend Matrix operator + (const Matrix& a, const Matrix& b);
108 friend Matrix operator - (const Matrix& a, const Matrix& b);
109
110 Matrix& operator *= (const Matrix& a);
111 Matrix& operator += (const Matrix& b);
112 Matrix& operator -= (const Matrix& b);
113 // </group>
114
115 // Matrice transposee
116 Matrix Transpose() const;
117 // Matrice inverse
118 // <thrown> singMatxErr </thrown>
119 Matrix Inverse() const;
120
121 // Nombre de lignes
122 inline int NRows() const {return nr;}
123 // Nombre de colonnes
124 inline int NCol() const {return nc;}
125
126 // Entrees-sorties PPF
127 // <group>
128 void ReadSelf(PInPersist&);
129 void WriteSelf(POutPersist&) const;
130 // </group>
131
132 // Acces aux rangees et colonnes
133 // <group>
134 MatrixRC Row(int r) const;
135 MatrixRC Col(int c) const;
136 MatrixRC Diag() const;
137 // </group>
138 /* Versions const ? Alors il faut constructeur const pour MatrixRC, */
139 /* mais MatrixRC contient un Matrix* qui detruit const.... */
140 /* mais en eux-meme, ils ne modifient pas la matrice. Ils permettent */
141 /* de le faire... */
142
143 // Pivot de Gauss : diagonalise la matrice A, en effectuant les memes
144 // operations sur la matrice B
145 static double GausPiv(Matrix& A, Matrix& B);
146
147 // Residus et fonction fittees.
148 Matrix* FitResidus(GeneralFit& gfit);
149 Matrix* FitFunction(GeneralFit& gfit);
150
151protected:
152 int_4 nr;
153 int_4 nc;
154 int ndata;
155 int nalloc;
156 r_8* data;
157 bool FromTmatrix;
158};
159
160
161inline r_8& Matrix::operator()(int r, int c)
162{
163#ifdef RGCHECK
164 if (r<0 || r>=nr || c<0 || c>=nc) THROW(rangeCheckErr);
165#endif
166 return(data[r*nc + c]);
167}
168
169
170inline r_8 const& Matrix::operator()(int r, int c) const
171{
172#ifdef RGCHECK
173 if (r<0 || r>=nr || c<0 || c>=nc) THROW(rangeCheckErr);
174#endif
175 return(data[r*nc + c]);
176}
177
178enum RCKind {matrixRow=0, matrixCol=1, matrixDiag=2};
179
180
181// <summary> Acces aux lignes et colonnes des matrices </summary>
182// Permet d'acceder a une ligne ou colonne d'une matrice, en place, comme
183// avec un vecteur.
184class MatrixRC EXC_AWARE {
185friend class Vector;
186friend class Matrix;
187public:
188 MatrixRC();
189
190 virtual ~MatrixRC() {}
191
192 int Next();
193 int Prev();
194 int SetCol(int c);
195 int SetRow(int r);
196 int SetDiag();
197
198 static int Step(const Matrix& m, RCKind rckind);
199 static double* Org(const Matrix&, RCKind rckind, int ind=0);
200
201 int NElts() const;
202 r_8& operator()(int i);
203 r_8 operator()(int i) const;
204
205 MatrixRC& operator = (const MatrixRC& rc);
206 //operator Vector() const;
207 Vector GetVect() const;
208
209 MatrixRC& operator += (const MatrixRC& rc);
210 MatrixRC& operator -= (const MatrixRC& rc);
211
212 MatrixRC& operator *= (double x);
213 MatrixRC& operator /= (double x);
214 MatrixRC& operator -= (double x);
215 MatrixRC& operator += (double x);
216
217 friend double operator * (const MatrixRC& a, const MatrixRC& b);
218
219 MatrixRC& LinComb(double a, double b, const MatrixRC& rc, int first=0);
220 MatrixRC& LinComb(double b, const MatrixRC& rc, int first=0);
221
222 int IMaxAbs(int first=0);
223
224 static void Swap(MatrixRC& rc1, MatrixRC& rc2);
225 // comme c'est symetrique, soit c'est static MatrixRC, soit static Matrix,
226 // soit Matrix avec verification qu'on parle bien de la meme...
227
228protected:
229 MatrixRC(Matrix& m, RCKind kind, int index=0);
230 Matrix* matrix;
231 r_8* data;
232 int index;
233 int step;
234 RCKind kind;
235};
236
237
238inline int MatrixRC::Step(const Matrix& m, RCKind rckind)
239{
240 switch (rckind)
241 {
242 case matrixRow :
243 return 1;
244 case matrixCol :
245 return m.nc;
246 case matrixDiag :
247 return m.nc+1;
248 }
249 return -1;
250}
251
252
253inline double* MatrixRC::Org(const Matrix& m, RCKind rckind, int index)
254{
255 switch (rckind)
256 {
257 case matrixRow :
258 return m.data + index * m.nc;
259 case matrixCol :
260 return m.data + index;
261 case matrixDiag :
262 return m.data;
263 }
264 return (double*) -1;
265}
266
267
268inline int MatrixRC::NElts() const
269{
270 if (!matrix) return -1; // Failure ?
271 switch (kind)
272 {
273 case matrixRow :
274 return matrix->nc;
275 case matrixCol :
276 return matrix->nr;
277 case matrixDiag :
278 return matrix->nc;
279 }
280 return -1;
281}
282
283
284
285inline double& MatrixRC::operator()(int i)
286{
287 return data[i*step];
288}
289
290
291inline double MatrixRC::operator()(int i) const
292{
293 return data[i*step];
294}
295
296#endif /* MATRIX_SEEN */
297
Note: See TracBrowser for help on using the repository browser.