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 
19 template <unsigned Rows, unsigned Columns, typename T>
20 class Matrix : public Vector< Rows, Vector<Columns,T> >
21 {
22 public:
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 
67 template<unsigned Rows, unsigned Columns, typename T, typename U>
68 const 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 
78 template<unsigned Rows, unsigned Columns, typename T, typename U>
79 const Vector<Columns,U> operator * (const Vector<Rows,U>& b,
80  const Matrix<Rows,Columns,T>& m)
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 
90 template<unsigned R1, unsigned C1R2, unsigned C2, typename T>
92 operator * (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 
102 template <unsigned Rows, unsigned C1, typename T, unsigned C2, typename U>
103 void 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 
190 template <unsigned RC, typename T>
191 void 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 
202 template<unsigned Square, typename T>
203 T 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 
211 template <unsigned RC, typename T>
212 const 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 
224 template <unsigned Rows, unsigned Columns, typename T>
225 const 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 
236 template <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 
249 template<unsigned Rows, unsigned Columns, typename T, typename U>
251 outer (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 
263 template<unsigned Ar, unsigned Ac, typename At,
264  unsigned Br, unsigned Bc, typename Bt>
266 direct (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 
280 template<unsigned U, unsigned L, unsigned B, unsigned R, typename T>
281 void 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 
307 template<unsigned U, unsigned L, unsigned B, unsigned R, typename T>
308 void 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 
334 template<unsigned M, typename T>
335 void 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 
351 template<unsigned M, typename T>
352 void 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 
374 template<typename T>
375 Matrix<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 
394 template<unsigned R, unsigned C, typename T>
395 T 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 
404 template<unsigned R, unsigned C, typename T>
405 struct 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 
418 template<unsigned R, unsigned C, typename T>
419 std::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 
Matrix & operator=(const Vector< Rows, Vector< Columns, U > > &s)
friend const friend Matrix operator-(Matrix s)
Vector.
Definition: Vector.h:22
Matrix is a column vector of row vectors.
Definition: Matrix.h:20
Template class manages Reference::Able objects.
Definition: Reference.h:74
Manages Reference::To references to the instance.
Definition: ReferenceAble.h:40
Traits of the data type.
Definition: Traits.h:70

Generated using doxygen 1.8.17