FEDRA emulsion software from the OPERA Collaboration
MatrixFunctions.hh
Go to the documentation of this file.
1 #ifndef __MATRIXFUNCTIONS_HH
2 #define __MATRIXFUNCTIONS_HH
3 // ********************************************************************
4 //
5 // source:
6 //
7 // type: source code
8 //
9 // created: 20. Mar 2001
10 //
11 // author: Thorsten Glebe
12 // HERA-B Collaboration
13 // Max-Planck-Institut fuer Kernphysik
14 // Saupfercheckweg 1
15 // 69117 Heidelberg
16 // Germany
17 // E-mail: T.Glebe@mpi-hd.mpg.de
18 //
19 // Description: Functions/Operators special to Matrix
20 //
21 // changes:
22 // 20 Mar 2001 (TG) creation
23 // 20 Mar 2001 (TG) Added Matrix * Vector multiplication
24 // 21 Mar 2001 (TG) Added transpose, product
25 // 11 Apr 2001 (TG) transpose() speed improvment by removing rows(), cols()
26 // through static members of Matrix and Expr class
27 //
28 // ********************************************************************
29 
30 #ifdef XXX
31 //==============================================================================
32 // SMatrix * SVector
33 //==============================================================================
34 template <class T, unsigned int D1, unsigned int D2>
36 {
37  SVector<T,D1> tmp;
38  for(unsigned int i=0; i<D1; ++i) {
39  const unsigned int rpos = i*D2;
40  for(unsigned int j=0; j<D2; ++j) {
41  tmp[i] += rhs.apply(rpos+j) * lhs.apply(j);
42  }
43  }
44  return tmp;
45 }
46 #endif
47 
48 
49 //==============================================================================
50 // meta_row_dot
51 //==============================================================================
52 template <unsigned int I>
53 struct meta_row_dot {
54  template <class A, class B>
55  static inline typename A::value_type f(const A& lhs, const B& rhs,
56  const unsigned int offset) {
57  return lhs.apply(offset+I) * rhs.apply(I) + meta_row_dot<I-1>::f(lhs,rhs,offset);
58  }
59 };
60 
61 
62 //==============================================================================
63 // meta_row_dot<0>
64 //==============================================================================
65 template <>
66 struct meta_row_dot<0> {
67  template <class A, class B>
68  static inline typename A::value_type f(const A& lhs, const B& rhs,
69  const unsigned int offset) {
70  return lhs.apply(offset) * rhs.apply(0);
71  }
72 };
73 
74 //==============================================================================
75 // VectorMatrixRowOp
76 //==============================================================================
77 template <class Matrix, class Vector, unsigned int D2>
79 public:
81  VectorMatrixRowOp(const Matrix& lhs, const Vector& rhs) :
82  lhs_(lhs), rhs_(rhs) {}
83 
86 
88  inline typename Matrix::value_type apply(unsigned int i) const {
89  return meta_row_dot<D2-1>::f(lhs_, rhs_, i*D2);
90  }
91 
92 protected:
93  const Matrix& lhs_;
94  const Vector& rhs_;
95 };
96 
97 
98 //==============================================================================
99 // meta_col_dot
100 //==============================================================================
101 template <unsigned int I>
102 struct meta_col_dot {
103  template <class Matrix, class Vector>
104  static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs,
105  const unsigned int offset) {
106  return lhs.apply(Matrix::cols*I+offset) * rhs.apply(I) +
107  meta_col_dot<I-1>::f(lhs,rhs,offset);
108  }
109 };
110 
111 
112 //==============================================================================
113 // meta_col_dot<0>
114 //==============================================================================
115 template <>
116 struct meta_col_dot<0> {
117  template <class Matrix, class Vector>
118  static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs,
119  const unsigned int offset) {
120  return lhs.apply(offset) * rhs.apply(0);
121  }
122 };
123 
124 //==============================================================================
125 // VectorMatrixColOp
126 //==============================================================================
127 template <class Vector, class Matrix, unsigned int D1>
129 public:
131  VectorMatrixColOp(const Vector& lhs, const Matrix& rhs) :
132  lhs_(lhs), rhs_(rhs) {}
133 
136 
138  inline typename Matrix::value_type apply(unsigned int i) const {
139  return meta_col_dot<D1-1>::f(rhs_, lhs_, i);
140  }
141 
142 protected:
143  const Vector& lhs_;
144  const Matrix& rhs_;
145 };
146 
147 //==============================================================================
148 // operator*: SMatrix * SVector
149 //==============================================================================
150 template <class T, unsigned int D1, unsigned int D2>
152  operator*(const SMatrix<T,D1,D2>& lhs, const SVector<T,D2>& rhs) {
153 
155  return Expr<VMOp, T, D1>(VMOp(lhs,rhs));
156 }
157 
158 //==============================================================================
159 // operator*: SMatrix * Expr<A,T,D2>
160 //==============================================================================
161 template <class A, class T, unsigned int D1, unsigned int D2>
163  operator*(const SMatrix<T,D1,D2>& lhs, const Expr<A,T,D2>& rhs) {
164 
166  return Expr<VMOp, T, D1>(VMOp(lhs,rhs));
167 }
168 
169 //==============================================================================
170 // operator*: Expr<A,T,D1,D2> * SVector
171 //==============================================================================
172 template <class A, class T, unsigned int D1, unsigned int D2>
174  operator*(const Expr<A,T,D1,D2>& lhs, const SVector<T,D2>& rhs) {
175 
177  return Expr<VMOp, T, D1>(VMOp(lhs,rhs));
178 }
179 
180 //==============================================================================
181 // operator*: Expr<A,T,D1,D2> * Expr<B,T,D2>
182 //==============================================================================
183 template <class A, class B, class T, unsigned int D1, unsigned int D2>
185  operator*(const Expr<A,T,D1,D2>& lhs, const Expr<B,T,D2>& rhs) {
186 
188  return Expr<VMOp, T, D1>(VMOp(lhs,rhs));
189 }
190 
191 //==============================================================================
192 // operator*: SVector * SMatrix
193 //==============================================================================
194 template <class T, unsigned int D1, unsigned int D2>
196  operator*(const SVector<T,D1>& lhs, const SMatrix<T,D1,D2>& rhs) {
197 
199  return Expr<VMOp, T, D2>(VMOp(lhs,rhs));
200 }
201 
202 //==============================================================================
203 // operator*: SVector * Expr<A,T,D1,D2>
204 //==============================================================================
205 template <class A, class T, unsigned int D1, unsigned int D2>
207  operator*(const SVector<T,D1>& lhs, const Expr<A,T,D1,D2>& rhs) {
208 
210  return Expr<VMOp, T, D2>(VMOp(lhs,rhs));
211 }
212 
213 //==============================================================================
214 // operator*: Expr<A,T,D1> * SMatrix
215 //==============================================================================
216 template <class A, class T, unsigned int D1, unsigned int D2>
218  operator*(const Expr<A,T,D1>& lhs, const SMatrix<T,D1,D2>& rhs) {
219 
221  return Expr<VMOp, T, D2>(VMOp(lhs,rhs));
222 }
223 
224 //==============================================================================
225 // operator*: Expr<A,T,D1> * Expr<B,T,D1,D2>
226 //==============================================================================
227 template <class A, class B, class T, unsigned int D1, unsigned int D2>
229  operator*(const Expr<A,T,D1>& lhs, const Expr<B,T,D1,D2>& rhs) {
230 
232  return Expr<VMOp, T, D2>(VMOp(lhs,rhs));
233 }
234 
235 //==============================================================================
236 // meta_matrix_dot
237 //==============================================================================
238 template <unsigned int I>
240  template <class MatrixA, class MatrixB>
241  static inline typename MatrixA::value_type f(const MatrixA& lhs, const MatrixB& rhs,
242  const unsigned int offset) {
243  return lhs.apply(offset/MatrixB::cols*MatrixA::cols + I) *
244  rhs.apply(MatrixB::cols*I + offset%MatrixB::cols) +
245  meta_matrix_dot<I-1>::f(lhs,rhs,offset);
246  }
247 };
248 
249 
250 //==============================================================================
251 // meta_matrix_dot<0>
252 //==============================================================================
253 template <>
254 struct meta_matrix_dot<0> {
255  template <class MatrixA, class MatrixB>
256  static inline typename MatrixA::value_type f(const MatrixA& lhs, const MatrixB& rhs,
257  const unsigned int offset) {
258  return lhs.apply(offset/MatrixB::cols*MatrixA::cols) *
259  rhs.apply(offset%MatrixB::cols);
260  }
261 };
262 
263 //==============================================================================
264 // MatrixMulOp
265 //==============================================================================
266 template <class MatrixA, class MatrixB, class T, unsigned int D>
267 class MatrixMulOp {
268 public:
270  MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) :
271  lhs_(lhs), rhs_(rhs) {}
272 
275 
277  inline T apply(unsigned int i) const {
278  return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
279  }
280 
281 protected:
282  const MatrixA& lhs_;
283  const MatrixB& rhs_;
284 };
285 
286 
287 //==============================================================================
288 // operator* (SMatrix * SMatrix, binary)
289 //==============================================================================
290 template < class T, unsigned int D1, unsigned int D, unsigned int D2>
291 inline Expr<MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>,T,D>, T, D1, D2>
292  operator*(const SMatrix<T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) {
293  typedef MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>, T,D> MatMulOp;
294 
295  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
296 }
297 
298 //==============================================================================
299 // operator* (SMatrix * Expr, binary)
300 //==============================================================================
301 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2>
302 inline Expr<MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>,T,D>, T, D1, D2>
303  operator*(const SMatrix<T,D1,D>& lhs, const Expr<A,T,D,D2>& rhs) {
304  typedef MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>,T,D> MatMulOp;
305 
306  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
307 }
308 
309 //==============================================================================
310 // operator* (Expr * SMatrix, binary)
311 //==============================================================================
312 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2>
313 inline Expr<MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>,T,D>, T, D1, D2>
314  operator*(const Expr<A,T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) {
315  typedef MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>,T,D> MatMulOp;
316 
317  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
318 }
319 
320 //==============================================================================
321 // operator* (Expr * Expr, binary)
322 //==============================================================================
323 template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2>
324 inline Expr<MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>,T,D>, T, D1, D2>
325  operator*(const Expr<A,T,D1,D>& lhs, const Expr<B,T,D,D2>& rhs) {
326  typedef MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, T,D> MatMulOp;
327 
328  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
329 }
330 
331 
332 #ifdef XXX
333 //==============================================================================
334 // MatrixMulOp
335 //==============================================================================
336 template <class MatrixA, class MatrixB, unsigned int D>
337 class MatrixMulOp {
338 public:
340  MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) :
341  lhs_(lhs), rhs_(rhs) {}
342 
344  ~MatrixMulOp() {}
345 
347  inline typename MatrixA::value_type apply(unsigned int i) const {
348  return meta_matrix_dot<D-1>::f(lhs_, rhs_, i);
349  }
350 
351 protected:
352  const MatrixA& lhs_;
353  const MatrixB& rhs_;
354 };
355 
356 
357 //==============================================================================
358 // operator* (SMatrix * SMatrix, binary)
359 //==============================================================================
360 template < class T, unsigned int D1, unsigned int D, unsigned int D2>
362  operator*(const SMatrix<T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) {
363  typedef MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>, D> MatMulOp;
364 
365  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
366 }
367 
368 //==============================================================================
369 // operator* (SMatrix * Expr, binary)
370 //==============================================================================
371 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2>
372 inline Expr<MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>, D>, T, D1, D2>
373  operator*(const SMatrix<T,D1,D>& lhs, const Expr<A,T,D,D2>& rhs) {
374  typedef MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>, D> MatMulOp;
375 
376  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
377 }
378 
379 //==============================================================================
380 // operator* (Expr * SMatrix, binary)
381 //==============================================================================
382 template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2>
383 inline Expr<MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>, D>, T, D1, D2>
384  operator*(const Expr<A,T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) {
385  typedef MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>, D> MatMulOp;
386 
387  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
388 }
389 
390 //==============================================================================
391 // operator* (Expr * Expr, binary)
392 //==============================================================================
393 template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2>
394 inline Expr<MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, D>, T, D1, D2>
395  operator*(const Expr<A,T,D1,D>& lhs, const Expr<B,T,D,D2>& rhs) {
396  typedef MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, D> MatMulOp;
397 
398  return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs));
399 }
400 #endif
401 
402 //==============================================================================
403 // TransposeOp
404 //==============================================================================
405 template <class Matrix, class T, unsigned int D1, unsigned int D2=D1>
406 class TransposeOp {
407 public:
409  TransposeOp( const Matrix& rhs) :
410  rhs_(rhs) {}
411 
414 
416  inline T apply(unsigned int i) const {
417  return rhs_.apply( (i%D1)*D2 + i/D1);
418  }
419 
420 protected:
421  const Matrix& rhs_;
422 };
423 
424 
425 //==============================================================================
426 // transpose
427 //==============================================================================
428 template <class T, unsigned int D1, unsigned int D2>
429 inline Expr<TransposeOp<SMatrix<T,D1,D2>,T,D1,D2>, T, D2, D1>
431  typedef TransposeOp<SMatrix<T,D1,D2>,T,D1,D2> MatTrOp;
432 
433  return Expr<MatTrOp, T, D2, D1>(MatTrOp(rhs));
434 }
435 
436 //==============================================================================
437 // transpose
438 //==============================================================================
439 template <class A, class T, unsigned int D1, unsigned int D2>
440 inline Expr<TransposeOp<Expr<A,T,D1,D2>,T,D1,D2>, T, D2, D1>
442  typedef TransposeOp<Expr<A,T,D1,D2>,T,D1,D2> MatTrOp;
443 
444  return Expr<MatTrOp, T, D2, D1>(MatTrOp(rhs));
445 }
446 
447 //==============================================================================
448 // product: SMatrix/SVector calculate v^T * A * v
449 //==============================================================================
450 template <class T, unsigned int D>
451 inline T product(const SMatrix<T,D>& lhs, const SVector<T,D>& rhs) {
452  return dot(rhs, lhs * rhs);
453 }
454 
455 //==============================================================================
456 // product: SVector/SMatrix calculate v^T * A * v
457 //==============================================================================
458 template <class T, unsigned int D>
459 inline T product(const SVector<T,D>& lhs, const SMatrix<T,D>& rhs) {
460  return dot(lhs, rhs * lhs);
461 }
462 
463 //==============================================================================
464 // product: SMatrix/Expr calculate v^T * A * v
465 //==============================================================================
466 template <class A, class T, unsigned int D>
467 inline T product(const SMatrix<T,D>& lhs, const Expr<A,T,D>& rhs) {
468  return dot(rhs, lhs * rhs);
469 }
470 
471 //==============================================================================
472 // product: Expr/SMatrix calculate v^T * A * v
473 //==============================================================================
474 template <class A, class T, unsigned int D>
475 inline T product(const Expr<A,T,D>& lhs, const SMatrix<T,D>& rhs) {
476  return dot(lhs, rhs * lhs);
477 }
478 
479 //==============================================================================
480 // product: SVector/Expr calculate v^T * A * v
481 //==============================================================================
482 template <class A, class T, unsigned int D>
483 inline T product(const SVector<T,D>& lhs, const Expr<A,T,D,D>& rhs) {
484  return dot(lhs, rhs * lhs);
485 }
486 
487 //==============================================================================
488 // product: Expr/SVector calculate v^T * A * v
489 //==============================================================================
490 template <class A, class T, unsigned int D>
491 inline T product(const Expr<A,T,D,D>& lhs, const SVector<T,D>& rhs) {
492  return dot(rhs, lhs * rhs);
493 }
494 
495 //==============================================================================
496 // product: Expr/Expr calculate v^T * A * v
497 //==============================================================================
498 template <class A, class B, class T, unsigned int D>
499 inline T product(const Expr<A,T,D,D>& lhs, const Expr<B,T,D>& rhs) {
500  return dot(rhs, lhs * rhs);
501 }
502 
503 //==============================================================================
504 // product: Expr/Expr calculate v^T * A * v
505 //==============================================================================
506 template <class A, class B, class T, unsigned int D>
507 inline T product(const Expr<A,T,D>& lhs, const Expr<B,T,D,D>& rhs) {
508  return dot(lhs, rhs * lhs);
509 }
510 
511 #endif
T dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Definition: Functions.hh:132
Expr< TransposeOp< SMatrix< T, D1, D2 >, T, D1, D2 >, T, D2, D1 > transpose(const SMatrix< T, D1, D2 > &rhs)
Definition: MatrixFunctions.hh:430
T product(const SMatrix< T, D > &lhs, const SVector< T, D > &rhs)
Definition: MatrixFunctions.hh:451
Expr< VectorMatrixRowOp< SMatrix< T, D1, D2 >, SVector< T, D2 >, D2 >, T, D1 > operator*(const SMatrix< T, D1, D2 > &lhs, const SVector< T, D2 > &rhs)
Definition: MatrixFunctions.hh:152
Definition: Expression.hh:43
Definition: MatrixFunctions.hh:267
const MatrixB & rhs_
Definition: MatrixFunctions.hh:283
MatrixMulOp(const MatrixA &lhs, const MatrixB &rhs)
Definition: MatrixFunctions.hh:270
T apply(unsigned int i) const
calc $\sum_{j} a_{ik} * b_{kj}$
Definition: MatrixFunctions.hh:277
const MatrixA & lhs_
Definition: MatrixFunctions.hh:282
~MatrixMulOp()
Definition: MatrixFunctions.hh:274
Definition: SMatrix.hh:53
T apply(unsigned int i) const
access the parse tree
Definition: SVector.hh:51
T apply(unsigned int i) const
access the parse tree
Definition: MatrixFunctions.hh:406
T apply(unsigned int i) const
Definition: MatrixFunctions.hh:416
TransposeOp(const Matrix &rhs)
Definition: MatrixFunctions.hh:409
const Matrix & rhs_
Definition: MatrixFunctions.hh:421
~TransposeOp()
Definition: MatrixFunctions.hh:413
Definition: MatrixFunctions.hh:128
VectorMatrixColOp(const Vector &lhs, const Matrix &rhs)
Definition: MatrixFunctions.hh:131
const Vector & lhs_
Definition: MatrixFunctions.hh:143
Matrix::value_type apply(unsigned int i) const
calc $\sum_{j} a_{ij} * v_j$
Definition: MatrixFunctions.hh:138
~VectorMatrixColOp()
Definition: MatrixFunctions.hh:135
const Matrix & rhs_
Definition: MatrixFunctions.hh:144
Definition: MatrixFunctions.hh:78
~VectorMatrixRowOp()
Definition: MatrixFunctions.hh:85
const Matrix & lhs_
Definition: MatrixFunctions.hh:93
VectorMatrixRowOp(const Matrix &lhs, const Vector &rhs)
Definition: MatrixFunctions.hh:81
Matrix::value_type apply(unsigned int i) const
calc $\sum_{j} a_{ij} * v_j$
Definition: MatrixFunctions.hh:88
const Vector & rhs_
Definition: MatrixFunctions.hh:94
struct @6 B
Definition: Struct.h:13
static Matrix::value_type f(const Matrix &lhs, const Vector &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:118
Definition: MatrixFunctions.hh:102
static Matrix::value_type f(const Matrix &lhs, const Vector &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:104
static MatrixA::value_type f(const MatrixA &lhs, const MatrixB &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:256
Definition: MatrixFunctions.hh:239
static MatrixA::value_type f(const MatrixA &lhs, const MatrixB &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:241
static A::value_type f(const A &lhs, const B &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:68
Definition: MatrixFunctions.hh:53
static A::value_type f(const A &lhs, const B &rhs, const unsigned int offset)
Definition: MatrixFunctions.hh:55