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

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

namespace changed to SOPHYA cmv 5/11/99

File size: 7.8 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 SOPHYA {
15 class GeneralFit;
16 template <class T> class TMatrix;
17}
18// <summary> Operations matricielles </summary>
19// Operations matricielles, algebre lineaire...
20class OMatrix : public PPersist, public AnyDataObj {
21 friend class OVector;
22 friend class OMatrixRC;
23 friend class TMatrix<r_8>;
24public:
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
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& 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
174inline 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
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 OMatrixRC EXC_AWARE {
189friend class OVector;
190friend class OMatrix;
191public:
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
232protected:
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
242inline 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
257inline 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
272inline 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
289inline double& OMatrixRC::operator()(int i)
290{
291 return data[i*step];
292}
293
294
295inline double OMatrixRC::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.