rivet is hosted by Hepforge, IPPP Durham
Rivet  2.7.0
MatrixN.hh
1 #ifndef RIVET_MATH_MATRIXN
2 #define RIVET_MATH_MATRIXN
3 
4 #include "Rivet/Math/MathHeader.hh"
5 #include "Rivet/Math/MathUtils.hh"
6 #include "Rivet/Math/Vectors.hh"
7 
8 #include "Rivet/Math/eigen/matrix.h"
9 
10 namespace Rivet {
11 
12 
13  template <size_t N>
14  class Matrix;
15  typedef Matrix<4> Matrix4;
16 
17  template <size_t N>
18  Matrix<N> multiply(const Matrix<N>& a, const Matrix<N>& b);
19  template <size_t N>
20  Matrix<N> divide(const Matrix<N>&, const double);
21  template <size_t N>
22  Matrix<N> operator*(const Matrix<N>& a, const Matrix<N>& b);
23 
24 
26 
27 
29  template <size_t N>
30  class Matrix {
31  template <size_t M>
32  friend Matrix<M> add(const Matrix<M>&, const Matrix<M>&);
33  template <size_t M>
34  friend Matrix<M> multiply(const double, const Matrix<M>&);
35  template <size_t M>
36  friend Matrix<M> multiply(const Matrix<M>&, const Matrix<M>&);
37  template <size_t M>
38  friend Vector<M> multiply(const Matrix<M>&, const Vector<M>&);
39  template <size_t M>
40  friend Matrix<M> divide(const Matrix<M>&, const double);
41 
42  public:
43  static Matrix<N> mkZero() {
44  Matrix<N> rtn;
45  return rtn;
46  }
47 
48  static Matrix<N> mkDiag(Vector<N> diag) {
49  Matrix<N> rtn;
50  for (size_t i = 0; i < N; ++i) {
51  rtn.set(i, i, diag[i]);
52  }
53  return rtn;
54  }
55 
56  static Matrix<N> mkIdentity() {
57  Matrix<N> rtn;
58  for (size_t i = 0; i < N; ++i) {
59  rtn.set(i, i, 1);
60  }
61  return rtn;
62  }
63 
64 
65  public:
66 
67  Matrix() {
68  _matrix.loadZero();
69  }
70 
71  Matrix(const Matrix<N>& other) {
72  _matrix = other._matrix;
73  }
74 
75  Matrix& set(const size_t i, const size_t j, const double value) {
76  if (i < N && j < N) {
77  _matrix(i, j) = value;
78  } else {
79  throw std::runtime_error("Attempted set access outside matrix bounds.");
80  }
81  return *this;
82  }
83 
84  double get(const size_t i, const size_t j) const {
85  if (i < N && j < N) {
86  return _matrix(i, j);
87  } else {
88  throw std::runtime_error("Attempted get access outside matrix bounds.");
89  }
90  }
91 
92  Vector<N> getRow(const size_t row) const {
93  Vector<N> rtn;
94  for (size_t i = 0; i < N; ++i) {
95  rtn.set(i, _matrix(row,i));
96  }
97  return rtn;
98  }
99 
100  Matrix<N>& setRow(const size_t row, const Vector<N>& r) {
101  for (size_t i = 0; i < N; ++i) {
102  _matrix(row,i) = r.get(i);
103  }
104  return *this;
105  }
106 
107  Vector<N> getColumn(const size_t col) const {
108  Vector<N> rtn;
109  for (size_t i = 0; i < N; ++i) {
110  rtn.set(i, _matrix(i,col));
111  }
112  return rtn;
113  }
114 
115  Matrix<N>& setColumn(const size_t col, const Vector<N>& c) {
116  for (size_t i = 0; i < N; ++i) {
117  _matrix(i,col) = c.get(i);
118  }
119  return *this;
120  }
121 
122  Matrix<N> transpose() const {
123  Matrix<N> tmp = *this;
124  tmp._matrix.replaceWithAdjoint();
125  return tmp;
126  }
127 
128  // Matrix<N>& transposeInPlace() {
129  // _matrix.replaceWithAdjoint();
130  // return *this;
131  // }
132 
134  Matrix<N> inverse() const {
135  Matrix<N> tmp;
136  tmp._matrix = _matrix.inverse();
137  return tmp;
138  }
139 
141  double det() const {
142  return _matrix.determinant();
143  }
144 
146  double trace() const {
147  double tr = 0.0;
148  for (size_t i = 0; i < N; ++i) {
149  tr += _matrix(i,i);
150  }
151  return tr;
152  // return _matrix.trace();
153  }
154 
157  Matrix<N> rtn;
158  rtn._matrix = -_matrix;
159  return rtn;
160  }
161 
163  size_t size() const {
164  return N;
165  }
166 
168  bool isZero(double tolerance=1E-5) const {
169  for (size_t i=0; i < N; ++i) {
170  for (size_t j=0; j < N; ++j) {
171  if (! Rivet::isZero(_matrix(i,j), tolerance) ) return false;
172  }
173  }
174  return true;
175  }
176 
178  bool isEqual(Matrix<N> other) const {
179  for (size_t i=0; i < N; ++i) {
180  for (size_t j=i; j < N; ++j) {
181  if (! Rivet::isZero(_matrix(i,j) - other._matrix(i,j)) ) return false;
182  }
183  }
184  return true;
185  }
186 
188  bool isSymm() const {
189  return isEqual(this->transpose());
190  }
191 
193  bool isDiag() const {
194  for (size_t i=0; i < N; ++i) {
195  for (size_t j=0; j < N; ++j) {
196  if (i == j) continue;
197  if (! Rivet::isZero(_matrix(i,j)) ) return false;
198  }
199  }
200  return true;
201  }
202 
203  bool operator == (const Matrix<N>& a) const {
204  return _matrix == a._matrix;
205  }
206 
207  bool operator != (const Matrix<N>& a) const {
208  return _matrix != a._matrix;
209  }
210 
211  bool operator < (const Matrix<N>& a) const {
212  return _matrix < a._matrix;
213  }
214 
215  bool operator <= (const Matrix<N>& a) const {
216  return _matrix <= a._matrix;
217  }
218 
219  bool operator > (const Matrix<N>& a) const {
220  return _matrix > a._matrix;
221  }
222 
223  bool operator >= (const Matrix<N>& a) const {
224  return _matrix >= a._matrix;
225  }
226 
227  Matrix<N>& operator *= (const Matrix<N>& m) {
228  _matrix = _matrix * m._matrix;
229  return *this;
230  }
231 
232  Matrix<N>& operator *= (const double a) {
233  _matrix *= a;
234  return *this;
235  }
236 
237  Matrix<N>& operator /= (const double a) {
238  _matrix /= a;
239  return *this;
240  }
241 
242  Matrix<N>& operator += (const Matrix<N>& m) {
243  _matrix += m._matrix;
244  return *this;
245  }
246 
247  Matrix<N>& operator -= (const Matrix<N>& m) {
248  _matrix -= m._matrix;
249  return *this;
250  }
251 
252  protected:
253 
254  typedef Eigen::Matrix<double,N> EMatrix;
255  EMatrix _matrix;
256 
257  };
258 
259 
261 
262 
263  template <size_t N>
264  inline Matrix<N> add(const Matrix<N>& a, const Matrix<N>& b) {
265  Matrix<N> result;
266  result._matrix = a._matrix + b._matrix;
267  return result;
268  }
269 
270  template <size_t N>
271  inline Matrix<N> subtract(const Matrix<N>& a, const Matrix<N>& b) {
272  return add(a, -b);
273  }
274 
275  template <size_t N>
276  inline Matrix<N> operator + (const Matrix<N> a, const Matrix<N>& b) {
277  return add(a, b);
278  }
279 
280  template <size_t N>
281  inline Matrix<N> operator - (const Matrix<N> a, const Matrix<N>& b) {
282  return subtract(a, b);
283  }
284 
285  template <size_t N>
286  inline Matrix<N> multiply(const double a, const Matrix<N>& m) {
287  Matrix<N> rtn;
288  rtn._matrix = a * m._matrix;
289  return rtn;
290  }
291 
292  template <size_t N>
293  inline Matrix<N> multiply(const Matrix<N>& m, const double a) {
294  return multiply(a, m);
295  }
296 
297  template <size_t N>
298  inline Matrix<N> divide(const Matrix<N>& m, const double a) {
299  return multiply(1/a, m);
300  }
301 
302  template <size_t N>
303  inline Matrix<N> operator * (const double a, const Matrix<N>& m) {
304  return multiply(a, m);
305  }
306 
307  template <size_t N>
308  inline Matrix<N> operator * (const Matrix<N>& m, const double a) {
309  return multiply(a, m);
310  }
311 
312  template <size_t N>
313  inline Matrix<N> multiply(const Matrix<N>& a, const Matrix<N>& b) {
314  Matrix<N> tmp;
315  tmp._matrix = a._matrix * b._matrix;
316  return tmp;
317  }
318 
319  template <size_t N>
320  inline Matrix<N> operator * (const Matrix<N>& a, const Matrix<N>& b) {
321  return multiply(a, b);
322  }
323 
324 
325  template <size_t N>
326  inline Vector<N> multiply(const Matrix<N>& a, const Vector<N>& b) {
327  Vector<N> tmp;
328  tmp._vec = a._matrix * b._vec;
329  return tmp;
330  }
331 
332  template <size_t N>
333  inline Vector<N> operator * (const Matrix<N>& a, const Vector<N>& b) {
334  return multiply(a, b);
335  }
336 
337  template <size_t N>
338  inline Matrix<N> transpose(const Matrix<N>& m) {
339  // Matrix<N> tmp;
340  // for (size_t i = 0; i < N; ++i) {
341  // for (size_t j = 0; j < N; ++j) {
342  // tmp.set(i, j, m.get(j, i));
343  // }
344  // }
345  // return tmp;
346  return m.transpose();
347  }
348 
349  template <size_t N>
350  inline Matrix<N> inverse(const Matrix<N>& m) {
351  return m.inverse();
352  }
353 
354  template <size_t N>
355  inline double det(const Matrix<N>& m) {
356  return m.determinant();
357  }
358 
359  template <size_t N>
360  inline double trace(const Matrix<N>& m) {
361  return m.trace();
362  }
363 
364 
366 
367 
369  template <size_t N>
370  inline string toString(const Matrix<N>& m) {
371  ostringstream ss;
372  ss << "[ ";
373  for (size_t i = 0; i < m.size(); ++i) {
374  ss << "( ";
375  for (size_t j = 0; j < m.size(); ++j) {
376  const double e = m.get(i, j);
377  ss << (Rivet::isZero(e) ? 0.0 : e) << " ";
378  }
379  ss << ") ";
380  }
381  ss << "]";
382  return ss.str();
383  }
384 
385 
387  template <size_t N>
388  inline ostream& operator << (std::ostream& out, const Matrix<N>& m) {
389  out << toString(m);
390  return out;
391  }
392 
393 
395 
396 
398  template <size_t N>
399  inline bool fuzzyEquals(const Matrix<N>& ma, const Matrix<N>& mb, double tolerance=1E-5) {
400  for (size_t i = 0; i < N; ++i) {
401  for (size_t j = 0; j < N; ++j) {
402  const double a = ma.get(i, j);
403  const double b = mb.get(i, j);
404  if (!Rivet::fuzzyEquals(a, b, tolerance)) return false;
405  }
406  }
407  return true;
408  }
409 
410 
412  template <size_t N>
413  inline bool isZero(const Matrix<N>& m, double tolerance=1E-5) {
414  return m.isZero(tolerance);
415  }
416 
417 
418 }
419 
420 #endif
Definition: ALICE_2010_I880049.cc:13
Matrix< N > inverse() const
Calculate inverse.
Definition: MatrixN.hh:134
bool isSymm() const
Check for symmetry under transposition.
Definition: MatrixN.hh:188
double det() const
Calculate determinant.
Definition: MatrixN.hh:141
Vector< N > & set(const size_t index, const double value)
Set indexed value.
Definition: VectorN.hh:60
bool isZero(double tolerance=1E-5) const
Index-wise check for nullness, allowing for numerical precision.
Definition: MatrixN.hh:168
General -dimensional mathematical matrix object.
Definition: MatrixN.hh:14
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&(std::is_floating_point< N1 >::value||std::is_floating_point< N2 >::value), bool >::type fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition: MathUtils.hh:45
A minimal base class for -dimensional vectors.
Definition: VectorN.hh:13
double trace() const
Calculate trace.
Definition: MatrixN.hh:146
Matrix< N > operator-() const
Negate.
Definition: MatrixN.hh:156
std::enable_if< std::is_floating_point< NUM >::value, bool >::type isZero(NUM val, double tolerance=1e-8)
Compare a number to zero.
Definition: MathUtils.hh:21
bool isEqual(Matrix< N > other) const
Check for index-wise equality, allowing for numerical precision.
Definition: MatrixN.hh:178
std::string toString(const AnalysisInfo &ai)
String representation.
Definition: AnalysisInfo.cc:144
size_t size() const
Get dimensionality.
Definition: MatrixN.hh:163
bool isDiag() const
Check that all off-diagonal elements are zero, allowing for numerical precision.
Definition: MatrixN.hh:193