Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/linalg/densemat.hpp
3206 views
1
#ifndef FILE_DENSEMAT
2
#define FILE_DENSEMAT
3
4
/**************************************************************************/
5
/* File: densemat.hh */
6
/* Author: Joachim Schoeberl */
7
/* Date: 01. Oct. 94 */
8
/**************************************************************************/
9
10
/**
11
Data type dense matrix
12
*/
13
14
15
#include <assert.h>
16
17
18
class DenseMatrix
19
{
20
protected:
21
int height;
22
int width;
23
double * data;
24
25
public:
26
///
27
DenseMatrix ();
28
///
29
DenseMatrix (int h, int w = 0);
30
///
31
DenseMatrix (const DenseMatrix & m2);
32
///
33
~DenseMatrix ();
34
35
///
36
void SetSize (int h, int w = 0);
37
38
int Height() const { return height; }
39
int Width() const {return width; }
40
41
double & operator() (int i, int j) { return data[i*width+j]; }
42
double operator() (int i, int j) const { return data[i*width+j]; }
43
double & operator() (int i) { return data[i]; }
44
double operator() (int i) const { return data[i]; }
45
46
///
47
DenseMatrix & operator= (const DenseMatrix & m2);
48
///
49
DenseMatrix & operator+= (const DenseMatrix & m2);
50
///
51
DenseMatrix & operator-= (const DenseMatrix & m2);
52
53
///
54
DenseMatrix & operator= (double v);
55
///
56
DenseMatrix & operator*= (double v);
57
58
///
59
void Mult (const FlatVector & v, FlatVector & prod) const
60
{
61
double sum;
62
const double * mp, * sp;
63
double * dp;
64
65
#ifdef DEBUG
66
if (prod.Size() != height)
67
{
68
cerr << "Mult: wrong vector size " << endl;
69
assert (1);
70
// prod.SetSize (height);
71
}
72
73
74
if (!height)
75
{
76
cout << "DenseMatrix::Mult height = 0" << endl;
77
}
78
if (!width)
79
{
80
cout << "DenseMatrix::Mult width = 0" << endl;
81
}
82
83
if (width != v.Size())
84
{
85
(*myerr) << "\nMatrix and Vector don't fit" << endl;
86
}
87
else if (Height() != prod.Size())
88
{
89
(*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl;
90
}
91
else
92
#endif
93
{
94
mp = data;
95
dp = &prod.Elem(1);
96
for (int i = 1; i <= height; i++)
97
{
98
sum = 0;
99
sp = &v.Get(1);
100
101
for (int j = 1; j <= width; j++)
102
{
103
// sum += Get(i,j) * v.Get(j);
104
sum += *mp * *sp;
105
mp++;
106
sp++;
107
}
108
109
*dp = sum;
110
dp++;
111
}
112
}
113
}
114
115
///
116
void MultTrans (const Vector & v, Vector & prod) const;
117
///
118
void Residuum (const Vector & x, const Vector & b, Vector & res) const;
119
///
120
double Det () const;
121
122
///
123
friend DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2);
124
///
125
friend DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2);
126
127
///
128
friend void Transpose (const DenseMatrix & m1, DenseMatrix & m2);
129
///
130
friend void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3);
131
///
132
friend void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2);
133
///
134
friend void CalcAAt (const DenseMatrix & a, DenseMatrix & m2);
135
///
136
friend void CalcAtA (const DenseMatrix & a, DenseMatrix & m2);
137
///
138
friend void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2);
139
///
140
friend void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2);
141
///
142
void Solve (const Vector & b, Vector & x) const;
143
///
144
void SolveDestroy (const Vector & b, Vector & x);
145
///
146
const double & Get(int i, int j) const { return data[(i-1)*width+j-1]; }
147
///
148
const double & Get(int i) const { return data[i-1]; }
149
///
150
void Set(int i, int j, double v) { data[(i-1)*width+j-1] = v; }
151
///
152
double & Elem(int i, int j) { return data[(i-1)*width+j-1]; }
153
///
154
const double & ConstElem(int i, int j) const { return data[(i-1)*width+j-1]; }
155
};
156
157
158
extern ostream & operator<< (ostream & ost, const DenseMatrix & m);
159
160
161
162
template <int WIDTH>
163
class MatrixFixWidth
164
{
165
protected:
166
int height;
167
double * data;
168
169
public:
170
///
171
MatrixFixWidth ()
172
{ height = 0; data = 0; }
173
///
174
MatrixFixWidth (int h)
175
{ height = h; data = new double[WIDTH*height]; }
176
///
177
~MatrixFixWidth ()
178
{ delete [] data; }
179
180
void SetSize (int h)
181
{
182
if (h != height)
183
{
184
delete data;
185
height = h;
186
data = new double[WIDTH*height];
187
}
188
}
189
190
///
191
int Height() const { return height; }
192
193
///
194
int Width() const { return WIDTH; }
195
196
///
197
MatrixFixWidth & operator= (double v)
198
{
199
for (int i = 0; i < height*WIDTH; i++)
200
data[i] = v;
201
return *this;
202
}
203
204
///
205
void Mult (const FlatVector & v, FlatVector & prod) const
206
{
207
double sum;
208
const double * mp, * sp;
209
double * dp;
210
211
/*
212
if (prod.Size() != height)
213
{
214
cerr << "MatrixFixWidth::Mult: wrong vector size " << endl;
215
assert (1);
216
}
217
*/
218
219
mp = data;
220
dp = &prod[0];
221
for (int i = 0; i < height; i++)
222
{
223
sum = 0;
224
sp = &v[0];
225
226
for (int j = 0; j < WIDTH; j++)
227
{
228
sum += *mp * *sp;
229
mp++;
230
sp++;
231
}
232
233
*dp = sum;
234
dp++;
235
}
236
}
237
238
double & operator() (int i, int j)
239
{ return data[i*WIDTH+j]; }
240
241
const double & operator() (int i, int j) const
242
{ return data[i*WIDTH+j]; }
243
244
245
MatrixFixWidth & operator*= (double v)
246
{
247
if (data)
248
for (int i = 0; i < height*WIDTH; i++)
249
data[i] *= v;
250
return *this;
251
}
252
253
254
255
const double & Get(int i, int j) const { return data[(i-1)*WIDTH+j-1]; }
256
///
257
const double & Get(int i) const { return data[i-1]; }
258
///
259
void Set(int i, int j, double v) { data[(i-1)*WIDTH+j-1] = v; }
260
///
261
double & Elem(int i, int j) { return data[(i-1)*WIDTH+j-1]; }
262
///
263
const double & ConstElem(int i, int j) const { return data[(i-1)*WIDTH+j-1]; }
264
};
265
266
267
template <int WIDTH>
268
extern ostream & operator<< (ostream & ost, const MatrixFixWidth<WIDTH> & m)
269
{
270
for (int i = 0; i < m.Height(); i++)
271
{
272
for (int j = 0; j < m.Width(); j++)
273
ost << m.Get(i+1,j+1) << " ";
274
ost << endl;
275
}
276
return ost;
277
};
278
279
280
281
extern void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2);
282
283
284
#endif
285
286