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

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

Suite merge avec PEIDA , Reza+cmv 21/10/99

File size: 7.6 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 "anydataobj.h"
12#include "ppersist.h"
13
14namespace PlanckDPC {
15 class GeneralFit;
16 template <class T> class TMatrix;
17}
18// <summary> Operations matricielles </summary>
19// Operations matricielles, algebre lineaire...
20class Matrix : public PPersist, public AnyDataObj {
21 friend class Vector;
22 friend class MatrixRC;
23 friend class TMatrix<r_8>;
24public:
25 Matrix();
26 // Constructeur, matrice a zero
27 Matrix(int r, int c);
28 // Constructeur avec des valeurs. Pas d'allocation, juste pointe.
29 Matrix(int r, int c, double* values);
30 // Constructeur par copie
31 Matrix(const Matrix& a);
32 // Constructeur par copie a partir d'une TMatrix<r_8>
33 Matrix(const TMatrix<r_8>& a);
34 // Destructeur
35 virtual ~Matrix();
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 Matrix(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 Matrix& operator = (const Matrix& a);
52 // Affectation depuis scalaire : identite * scalaire
53 Matrix& operator = (double x);
54
55 // Impression
56 friend ostream& operator << (ostream& s, const Matrix& 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 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 friend Matrix operator - (double b, const Matrix& a);
82 friend Matrix operator / (const Matrix& 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 * Vector(2), BUG !
88 // <group>
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 friend Matrix operator - (int b, const Matrix& a);
95 friend Matrix operator / (const Matrix& a, int b);
96 // </group>
97
98 // Operations matricielles "en place", avec scalaire
99 // <group>
100 Matrix& operator *= (double b);
101 Matrix& operator += (double b);
102 Matrix& operator -= (double b);
103 Matrix& operator /= (double b);
104 // </group>
105
106 // Operations matricielles
107 // <group>
108 friend Matrix operator * (const Matrix& a, const Matrix& b);
109 friend Matrix operator + (const Matrix& a, const Matrix& b);
110 friend Matrix operator - (const Matrix& a, const Matrix& b);
111
112 Matrix& operator *= (const Matrix& a);
113 Matrix& operator += (const Matrix& b);
114 Matrix& operator -= (const Matrix& b);
115 // </group>
116
117 // Matrice transposee
118 Matrix Transpose() const;
119 // Matrice inverse
120 // <thrown> singMatxErr </thrown>
121 Matrix 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 MatrixRC Row(int r) const;
137 MatrixRC Col(int c) const;
138 MatrixRC Diag() const;
139 // </group>
140 /* Versions const ? Alors il faut constructeur const pour MatrixRC, */
141 /* mais MatrixRC contient un Matrix* 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(Matrix& A, Matrix& B);
148
149 // Residus et fonction fittees.
150 Matrix FitResidus(GeneralFit& gfit
151 ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
152 Matrix FitFunction(GeneralFit& gfit
153 ,double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
154
155protected:
156 int_4 nr;
157 int_4 nc;
158 int ndata;
159 int nalloc;
160 r_8* data;
161 bool FromTmatrix;
162};
163
164
165inline r_8& Matrix::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
174inline r_8 const& Matrix::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
182enum 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.
188class MatrixRC EXC_AWARE {
189friend class Vector;
190friend class Matrix;
191public:
192 MatrixRC();
193
194 virtual ~MatrixRC() {}
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 Matrix& m, RCKind rckind);
203 static double* Org(const Matrix&, 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 MatrixRC& operator = (const MatrixRC& rc);
210 //operator Vector() const;
211 Vector GetVect() const;
212
213 MatrixRC& operator += (const MatrixRC& rc);
214 MatrixRC& operator -= (const MatrixRC& rc);
215
216 MatrixRC& operator *= (double x);
217 MatrixRC& operator /= (double x);
218 MatrixRC& operator -= (double x);
219 MatrixRC& operator += (double x);
220
221 friend double operator * (const MatrixRC& a, const MatrixRC& b);
222
223 MatrixRC& LinComb(double a, double b, const MatrixRC& rc, int first=0);
224 MatrixRC& LinComb(double b, const MatrixRC& rc, int first=0);
225
226 int IMaxAbs(int first=0);
227
228 static void Swap(MatrixRC& rc1, MatrixRC& rc2);
229 // comme c'est symetrique, soit c'est static MatrixRC, soit static Matrix,
230 // soit Matrix avec verification qu'on parle bien de la meme...
231
232protected:
233 MatrixRC(Matrix& m, RCKind kind, int index=0);
234 Matrix* matrix;
235 r_8* data;
236 int index;
237 int step;
238 RCKind kind;
239};
240
241
242inline int MatrixRC::Step(const Matrix& 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
257inline double* MatrixRC::Org(const Matrix& 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
272inline int MatrixRC::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
289inline double& MatrixRC::operator()(int i)
290{
291 return data[i*step];
292}
293
294
295inline double MatrixRC::operator()(int i) const
296{
297 return data[i*step];
298}
299
300
301#endif /* MATRIX_SEEN */
302
Note: See TracBrowser for help on using the repository browser.