Matrix.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2003 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// epsic/src/util/Matrix.h
10
11#ifndef __Matrix_H
12#define __Matrix_H
13
14#include "Vector.h"
15#include "complex_promote.h"
16#include <stdexcept>
17
19template <unsigned Rows, unsigned Columns, typename T>
20class Matrix : public Vector< Rows, Vector<Columns,T> >
21{
22public:
23
25 Matrix () { zero (); }
26
28 Matrix (T s)
29 {
30 zero ();
31 for (unsigned i=0; i<Rows; i++)
32 this->x[i][i] = s;
33 }
34
36 template<typename U> Matrix (const Vector< Rows, Vector<Columns,U> >& s)
37 { operator=(s); }
38
40 template<typename U> Matrix& operator =
42 {
43 for (unsigned i=0; i<Rows; i++)
44 this->x[i] = s.x[i];
45 return *this;
46 }
47
49 const friend Matrix operator - (Matrix s)
50 {
51 for (unsigned i=0; i<Rows; i++)
52 for (unsigned j=0; j<Columns; j++)
53 s.x[i][j] = -s.x[i][j];
54 return s;
55 }
56
57 void zero ()
58 {
59 for (unsigned i=0; i<Rows; i++)
60 for (unsigned j=0; j<Columns; j++)
61 this->x[i][j] = T(0.0);
62 }
63};
64
65
67template<unsigned Rows, unsigned Columns, typename T, typename U>
68const Vector<Rows,U> operator * (const Matrix<Rows,Columns,T>& m,
69 const Vector<Columns,U>& b)
70{
72 for (unsigned i=0; i<Rows; i++)
73 r[i] = Vector<Columns,U>(m[i]) * b;
74 return r;
75}
76
78template<unsigned Rows, unsigned Columns, typename T, typename U>
79const Vector<Columns,U> operator * (const Vector<Rows,U>& b,
81{
83 for (unsigned j=0; j<Columns; j++)
84 for (unsigned i=0; i<Rows; i++)
85 r[j] += m[i][j] * b[i];
86 return r;
87}
88
90template<unsigned R1, unsigned C1R2, unsigned C2, typename T>
92operator * (const Matrix<R1, C1R2, T>& a, const Matrix<C1R2, C2, T>& b)
93{
95 for (unsigned i=0; i<R1; i++)
96 for (unsigned j=0; j<C2; j++)
97 for (unsigned k=0; k<C1R2; k++)
98 r[i][j] += a[i][k]*b[k][j];
99 return r;
100}
101
102template <unsigned Rows, unsigned C1, typename T, unsigned C2, typename U>
103void GaussJordan (Matrix<Rows,C1,T>& a, Matrix<Rows,C2,U>& b)
104{
108
109 unsigned irow = 0;
110 unsigned icol = 0;
111
112 unsigned i, j, k;
113 for (i=0; i<Rows; i++) {
114
115 double big = 0.0;
116
117 //cerr << "0" << endl;
118
119 for (j=0; j<Rows; j++) {
120 if (ipiv[j] != 1)
121 for (k=0; k<Rows; k++) {
122 if (ipiv[k] == 0) {
123 if (fabs(a[j][k]) >= big) {
124 big=fabs(a[j][k]);
125 irow=j;
126 icol=k;
127 }
128 }
129 else if (ipiv[k] > 1)
130 throw std::runtime_error("GaussJordan (Matrix) Singular Matrix-1");
131 }
132 }
133
134 //cerr << "1" << endl;
135
136 ipiv[icol]++;
137
138 if (irow != icol) {
139 for (j=0; j<Rows; j++)
140 std::swap (a[irow][j], a[icol][j]);
141 for (j=0; j<C2; j++)
142 std::swap (b[irow][j], b[icol][j]);
143 }
144
145 //cerr << "2" << endl;
146
147 indxr[i]=irow;
148 indxc[i]=icol;
149
150 if (a[icol][icol] == 0.0)
151 throw std::runtime_error ("GaussJordan (Matrix) Singular Matrix-2");
152
153 //cerr << "3" << endl;
154
155 T pivinv = 1.0/a[icol][icol];
156 a[icol][icol]=1.0;
157
158 for (j=0; j<Rows; j++)
159 a[icol][j] *= pivinv;
160 for (j=0; j<C2; j++)
161 b[icol][j] *= pivinv;
162
163 //cerr << "4" << endl;
164
165 for (j=0; j<Rows; j++)
166 if (j != icol) {
167 T dum = a[j][icol];
168 a[j][icol]=0.0;
169 for (k=0; k<Rows; k++)
170 a[j][k] -= a[icol][k]*dum;
171 for (k=0; k<C2; k++)
172 b[j][k] -= b[icol][k]*dum;
173 }
174
175 //cerr << "5" << endl;
176 }
177
178 //cerr << "6" << endl;
179
180 for (i=Rows; i>0; i--) {
181 if (indxr[i-1] != indxc[i-1])
182 for (j=0; j<Rows; j++)
183 std::swap(a[j][indxr[i-1]],a[j][indxc[i-1]]);
184 }
185
186 //cerr << "7" << endl;
187
188}
189
190template <unsigned RC, typename T>
191void matrix_identity (Matrix<RC, RC, T>& m)
192{
193 for (unsigned i=0; i<RC; i++)
194 for (unsigned j=0; j<RC; j++)
195 if (i==j)
196 m[i][j] = 1;
197 else
198 m[i][j] = 0;
199}
200
202template<unsigned Square, typename T>
203T trace (const Matrix<Square,Square,T>& M)
204{
205 T result (0);
206 for (unsigned i=0; i<Square; i++)
207 result += M[i][i];
208 return result;
209}
210
211template <unsigned RC, typename T>
212const Matrix<RC, RC, T> inv (const Matrix<RC, RC, T>& m)
213{
214 Matrix<RC, RC, T> copy (m);
215
216 Matrix<RC, RC, T> inverse;
217 matrix_identity (inverse);
218
219 GaussJordan (copy, inverse);
220
221 return inverse;
222}
223
224template <unsigned Rows, unsigned Columns, typename T>
225const Matrix<Columns, Rows, T> transpose (const Matrix<Rows, Columns,T>& m)
226{
228
229 for (unsigned i=0; i<Rows; i++)
230 for (unsigned j=0; j<Columns; j++)
231 result[j][i] = m[i][j];
232
233 return result;
234}
235
236template <unsigned Rows, unsigned Columns, typename T>
238{
240
241 for (unsigned i=0; i<Rows; i++)
242 for (unsigned j=0; j<Columns; j++)
243 result[j][i] = myconj( m[i][j] );
244
245 return result;
246}
247
249template<unsigned Rows, unsigned Columns, typename T, typename U>
251outer (const Vector<Rows,T>& a, const Vector<Columns,U>& b)
252{
254
255 for (unsigned i=0; i<Rows; i++)
256 for (unsigned j=0; j<Columns; j++)
257 result[i][j] = a[i] * b[j];
258
259 return result;
260}
261
263template<unsigned Ar, unsigned Ac, typename At,
264 unsigned Br, unsigned Bc, typename Bt>
266direct (const Matrix<Ar,Ac,At>& a, const Matrix<Br,Bc,Bt>& b)
267{
269
270 for (unsigned ar=0; ar<Ar; ar++)
271 for (unsigned ac=0; ac<Ac; ac++)
272 for (unsigned br=0; br<Br; br++)
273 for (unsigned bc=0; bc<Bc; bc++)
274 result[ar*Br+br][ac*Bc+bc] = a[ar][ac] * b[br][bc];
275
276 return result;
277}
278
280template<unsigned U, unsigned L, unsigned B, unsigned R, typename T>
281void partition (const Matrix<U+B,L+R,T>& A,
282 Matrix<U,L,T>& upper_left,
283 Matrix<U,R,T>& upper_right,
284 Matrix<B,L,T>& bottom_left,
285 Matrix<B,R,T>& bottom_right)
286{
287 unsigned i, j;
288
289 for (i=0; i<U; i++)
290 {
291 for (j=0; j<L; j++)
292 upper_left[i][j] = A[i][j];
293 for (j=0; j<R; j++)
294 upper_right[i][j] = A[i][j+L];
295 }
296
297 for (i=0; i<B; i++)
298 {
299 for (j=0; j<L; j++)
300 bottom_left[i][j] = A[i+U][j];
301 for (j=0; j<R; j++)
302 bottom_right[i][j] = A[i+U][j+L];
303 }
304}
305
307template<unsigned U, unsigned L, unsigned B, unsigned R, typename T>
308void compose (Matrix<U+B,L+R,T>& A,
309 const Matrix<U,L,T>& upper_left,
310 const Matrix<U,R,T>& upper_right,
311 const Matrix<B,L,T>& bottom_left,
312 const Matrix<B,R,T>& bottom_right)
313{
314 unsigned i, j;
315
316 for (i=0; i<U; i++)
317 {
318 for (j=0; j<L; j++)
319 A[i][j] = upper_left[i][j];
320 for (j=0; j<R; j++)
321 A[i][j+L] = upper_right[i][j];
322 }
323
324 for (i=0; i<B; i++)
325 {
326 for (j=0; j<L; j++)
327 A[i+U][j] = bottom_left[i][j];
328 for (j=0; j<R; j++)
329 A[i+U][j+L] = bottom_right[i][j];
330 }
331}
332
334template<unsigned M, typename T>
335void partition (const Matrix<M+1,M+1,T>& covariance,
336 T& variance,
337 Vector <M,T>& cov_vector,
338 Matrix <M,M,T>& cov_matrix)
339{
340 Matrix<1,1,T> ul;
341 Matrix<M,1,T> bl;
342 Matrix<1,M,T> ur;
343
344 partition (covariance, ul, ur, bl, cov_matrix);
345
346 variance = ul[0][0];
347 cov_vector = ur[0];
348}
349
351template<unsigned M, typename T>
352void compose (Matrix<M+1,M+1,T>& covariance,
353 T variance,
354 const Vector <M,T>& cov_vector,
355 const Matrix <M,M,T>& cov_matrix)
356{
357 Matrix<1,1,T> ul;
358 Matrix<M,1,T> bl;
359 Matrix<1,M,T> ur;
360
361 ul[0][0] = variance;
362
363 for (unsigned i=0; i<M; i++)
364 ur[0][i] = bl[i][0] = cov_vector[i];
365
366 compose (covariance, ul, ur, bl, cov_matrix);
367}
368
370
373
374template<typename T>
375Matrix<3,3,T> rotation (const Vector<3,T>& v, double radians)
376{
377 double s = sin(radians);
378 double c = cos(radians);
379 double u = 1.0 - c;
380
381 Matrix<3,3,T> result;
382
383 result[0] = Vector<3,T>
384 ( v[0]*v[0]*u + c , v[1]*v[0]*u - v[2]*s, v[2]*v[0]*u + v[1]*s );
385 result[1] = Vector<3,T>
386 ( v[0]*v[1]*u + v[2]*s, v[1]*v[1]*u + c , v[2]*v[1]*u - v[0]*s );
387 result[2] = Vector<3,T>
388 ( v[0]*v[2]*u - v[1]*s, v[1]*v[2]*u + v[0]*s, v[2]*v[2]*u + c );
389
390 return result;
391}
392
394template<unsigned R, unsigned C, typename T>
395T normsq (const Matrix<R,C,T>& v)
396{
397 T sum = normsq(v[0]);
398 for (unsigned i=1; i < R; i++)
399 sum += normsq(v[i]);
400 return sum;
401}
402
404template<unsigned R, unsigned C, typename T>
405struct DatumTraits< Matrix<R,C,T> >
406{
407 typedef T element_type;
408
409 static inline unsigned ndim () { return R*C; }
410 static inline T& element (Matrix<R,C,T>& t, unsigned i)
411 { return t[i/C][i%C]; }
412 static inline const T element (const Matrix<R,C,T>& t, unsigned i)
413 { return t[i/C][i%C]; }
414};
415
416
418template<unsigned R, unsigned C, typename T>
419std::ostream& operator<< (std::ostream& ostr, const Matrix<R,C,T>& m)
420{
421 ostr << "[" << m[0];
422 for (unsigned i=1; i<R; i++)
423 ostr << ",\n " << m[i];
424 return ostr << "]";
425}
426
427#endif /* not __Matrix_H defined */
428
friend const friend Matrix operator-(Matrix s)
Matrix & operator=(const Vector< Rows, Vector< Columns, U > > &s)

Generated using doxygen 1.14.0