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