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//==============================================================================
34template <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//==============================================================================
52template <unsigned int I>
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//==============================================================================
65template <>
66struct 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//==============================================================================
77template <class Matrix, class Vector, unsigned int D2>
79public:
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
92protected:
93 const Matrix& lhs_;
94 const Vector& rhs_;
95};
96
97
98//==============================================================================
99// meta_col_dot
100//==============================================================================
101template <unsigned int I>
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//==============================================================================
115template <>
116struct 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//==============================================================================
127template <class Vector, class Matrix, unsigned int D1>
129public:
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
142protected:
143 const Vector& lhs_;
144 const Matrix& rhs_;
145};
146
147//==============================================================================
148// operator*: SMatrix * SVector
149//==============================================================================
150template <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//==============================================================================
161template <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//==============================================================================
172template <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//==============================================================================
183template <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//==============================================================================
194template <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//==============================================================================
205template <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//==============================================================================
216template <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//==============================================================================
227template <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//==============================================================================
238template <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//==============================================================================
253template <>
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//==============================================================================
266template <class MatrixA, class MatrixB, class T, unsigned int D>
268public:
270 MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) :
271 lhs_(lhs), rhs_(rhs) {}
272
275
277 inline T apply(unsigned int i) const {
279 }
280
281protected:
282 const MatrixA& lhs_;
283 const MatrixB& rhs_;
284};
285
286
287//==============================================================================
288// operator* (SMatrix * SMatrix, binary)
289//==============================================================================
290template < class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
301template <class A, class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
312template <class A, class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
323template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2>
324inline 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//==============================================================================
336template <class MatrixA, class MatrixB, unsigned int D>
337class MatrixMulOp {
338public:
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 {
349 }
350
351protected:
352 const MatrixA& lhs_;
353 const MatrixB& rhs_;
354};
355
356
357//==============================================================================
358// operator* (SMatrix * SMatrix, binary)
359//==============================================================================
360template < 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//==============================================================================
371template <class A, class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
382template <class A, class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
393template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int 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//==============================================================================
405template <class Matrix, class T, unsigned int D1, unsigned int D2=D1>
407public:
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
420protected:
421 const Matrix& rhs_;
422};
423
424
425//==============================================================================
426// transpose
427//==============================================================================
428template <class T, unsigned int D1, unsigned int D2>
429inline 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//==============================================================================
439template <class A, class T, unsigned int D1, unsigned int D2>
440inline 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//==============================================================================
450template <class T, unsigned int D>
451inline 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//==============================================================================
458template <class T, unsigned int D>
459inline 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//==============================================================================
466template <class A, class T, unsigned int D>
467inline 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//==============================================================================
474template <class A, class T, unsigned int D>
475inline 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//==============================================================================
482template <class A, class T, unsigned int D>
483inline 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//==============================================================================
490template <class A, class T, unsigned int D>
491inline 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//==============================================================================
498template <class A, class B, class T, unsigned int D>
499inline 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//==============================================================================
506template <class A, class B, class T, unsigned int D>
507inline 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< 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
T product(const SMatrix< T, D > &lhs, const SVector< T, D > &rhs)
Definition: MatrixFunctions.hh:451
Expr< TransposeOp< SMatrix< T, D1, D2 >, T, D1, D2 >, T, D2, D1 > transpose(const SMatrix< T, D1, D2 > &rhs)
Definition: MatrixFunctions.hh:430
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
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