Rivet API documentation

Rivet 4.1.3
MatrixN.hh
1#ifndef RIVET_MATH_MATRIXN
2#define RIVET_MATH_MATRIXN
3
4#include "Rivet/Math/MathConstants.hh"
5#include "Rivet/Math/MathUtils.hh"
6#include "Rivet/Math/Vectors.hh"
7
8#include "Rivet/Math/eigen3/Dense"
9
10namespace 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
32 template <size_t M>
33 friend Matrix<M> add(const Matrix<M>&, const Matrix<M>&);
34 template <size_t M>
35 friend Matrix<M> multiply(const double, const Matrix<M>&);
36 template <size_t M>
37 friend Matrix<M> multiply(const Matrix<M>&, const Matrix<M>&);
38 template <size_t M>
39 friend Vector<M> multiply(const Matrix<M>&, const Vector<M>&);
40 template <size_t M>
41 friend Matrix<M> divide(const Matrix<M>&, const double);
42
43
44 public:
45
46 static Matrix<N> mkZero() {
47 Matrix<N> rtn;
48 return rtn;
49 }
50
51 static Matrix<N> mkDiag(Vector<N> diag) {
52 Matrix<N> rtn;
53 for (size_t i = 0; i < N; ++i) {
54 rtn.set(i, i, diag[i]);
55 }
56 return rtn;
57 }
58
59 static Matrix<N> mkIdentity() {
60 Matrix<N> rtn;
61 for (size_t i = 0; i < N; ++i) {
62 rtn.set(i, i, 1);
63 }
64 return rtn;
65 }
66
67
68 public:
69
70 Matrix()
71 : _matrix(EMatrix::Zero()) { }
72
73 Matrix& set(const size_t i, const size_t j, const double value) {
74 if (i < N && j < N) {
75 _matrix(i, j) = value;
76 }
77 else {
78 throw std::runtime_error("Attempted set access outside matrix bounds.");
79 }
80 return *this;
81 }
82
83 double get(const size_t i, const size_t j) const {
84 if (i < N && j < N) {
85 return _matrix(i, j);
86 }
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;
124 tmp._matrix = _matrix.transpose();
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
156 Matrix<N> operator-() const {
157 Matrix<N> rtn;
158 rtn._matrix = -_matrix;
159 return rtn;
160 }
161
163 constexpr 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 *= 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 using EMatrix = RivetEigen::Matrix<double, N, N>;
255 EMatrix _matrix;
256 };
257
258
260
261
262 template <size_t N>
263 inline Matrix<N> add(const Matrix<N>& a, const Matrix<N>& b) {
264 Matrix<N> result;
265 result._matrix = a._matrix + b._matrix;
266 return result;
267 }
268
269 template <size_t N>
270 inline Matrix<N> subtract(const Matrix<N>& a, const Matrix<N>& b) {
271 return add(a, -b);
272 }
273
274 template <size_t N>
275 inline Matrix<N> operator+(const Matrix<N> a, const Matrix<N>& b) {
276 return add(a, b);
277 }
278
279 template <size_t N>
280 inline Matrix<N> operator-(const Matrix<N> a, const Matrix<N>& b) {
281 return subtract(a, b);
282 }
283
284 template <size_t N>
285 inline Matrix<N> multiply(const double a, const Matrix<N>& m) {
286 Matrix<N> rtn;
287 rtn._matrix = a * m._matrix;
288 return rtn;
289 }
290
291 template <size_t N>
292 inline Matrix<N> multiply(const Matrix<N>& m, const double a) {
293 return multiply(a, m);
294 }
295
296 template <size_t N>
297 inline Matrix<N> divide(const Matrix<N>& m, const double a) {
298 return multiply(1 / a, m);
299 }
300
301 template <size_t N>
302 inline Matrix<N> operator*(const double a, const Matrix<N>& m) {
303 return multiply(a, m);
304 }
305
306 template <size_t N>
307 inline Matrix<N> operator*(const Matrix<N>& m, const double a) {
308 return multiply(a, m);
309 }
310
311 template <size_t N>
312 inline Matrix<N> multiply(const Matrix<N>& a, const Matrix<N>& b) {
313 Matrix<N> tmp;
314 tmp._matrix = a._matrix * b._matrix;
315 return tmp;
316 }
317
318 template <size_t N>
319 inline Matrix<N> operator*(const Matrix<N>& a, const Matrix<N>& b) {
320 return multiply(a, b);
321 }
322
323
324 template <size_t N>
325 inline Vector<N> multiply(const Matrix<N>& a, const Vector<N>& b) {
326 Vector<N> tmp;
327 tmp._vec = a._matrix * b._vec;
328 return tmp;
329 }
330
331 template <size_t N>
332 inline Vector<N> operator*(const Matrix<N>& a, const Vector<N>& b) {
333 return multiply(a, b);
334 }
335
336 template <size_t N>
337 inline Matrix<N> transpose(const Matrix<N>& m) {
338 // Matrix<N> tmp;
339 // for (size_t i = 0; i < N; ++i) {
340 // for (size_t j = 0; j < N; ++j) {
341 // tmp.set(i, j, m.get(j, i));
342 // }
343 // }
344 // return tmp;
345 return m.transpose();
346 }
347
348 template <size_t N>
349 inline Matrix<N> inverse(const Matrix<N>& m) {
350 return m.inverse();
351 }
352
353 template <size_t N>
354 inline double det(const Matrix<N>& m) {
355 return m.determinant();
356 }
357
358 template <size_t N>
359 inline double trace(const Matrix<N>& m) {
360 return m.trace();
361 }
362
363
365
366
368 template <size_t N>
369 inline string toString(const Matrix<N>& m) {
370 std::ostringstream ss;
371 ss << "[ ";
372 for (size_t i = 0; i < m.size(); ++i) {
373 ss << "( ";
374 for (size_t j = 0; j < m.size(); ++j) {
375 const double e = m.get(i, j);
376 ss << (Rivet::isZero(e) ? 0.0 : e) << " ";
377 }
378 ss << ") ";
379 }
380 ss << "]";
381 return ss.str();
382 }
383
384
386 template <size_t N>
387 inline std::ostream& operator<<(std::ostream& out, const Matrix<N>& m) {
388 out << toString(m);
389 return out;
390 }
391
392
394
395
397 template <size_t N>
398 inline bool fuzzyEquals(const Matrix<N>& ma, const Matrix<N>& mb, double tolerance = 1E-5) {
399 for (size_t i = 0; i < N; ++i) {
400 for (size_t j = 0; j < N; ++j) {
401 const double a = ma.get(i, j);
402 const double b = mb.get(i, j);
403 if (!Rivet::fuzzyEquals(a, b, tolerance)) return false;
404 }
405 }
406 return true;
407 }
408
409
411 template <size_t N>
412 inline bool isZero(const Matrix<N>& m, double tolerance = 1E-5) {
413 return m.isZero(tolerance);
414 }
415
416
417}
418
419#endif
General -dimensional mathematical matrix object.
Definition MatrixN.hh:30
double trace() const
Calculate trace.
Definition MatrixN.hh:146
double det() const
Calculate determinant.
Definition MatrixN.hh:141
Matrix< N > operator-() const
Negate.
Definition MatrixN.hh:156
bool isZero(double tolerance=1E-5) const
Index-wise check for nullness, allowing for numerical precision.
Definition MatrixN.hh:168
constexpr 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
Matrix< N > inverse() const
Calculate inverse.
Definition MatrixN.hh:134
bool isSymm() const
Check for symmetry under transposition.
Definition MatrixN.hh:188
bool isEqual(Matrix< N > other) const
Check for index-wise equality, allowing for numerical precision.
Definition MatrixN.hh:178
A minimal base class for -dimensional vectors.
Definition VectorN.hh:23
Vector< N > & set(const size_t index, const double value)
Set indexed value.
Definition VectorN.hh:63
double E(const ParticleBase &p)
Unbound function access to E.
Definition ParticleBaseUtils.hh:829
Definition LHCbCommon.hh:9
double subtract(double a, double b, double tolerance=1e-5)
Subtract two numbers with FP fuzziness.
Definition MathUtils.hh:242
bool operator==(const Cut &a, const Cut &b)
Compare two cuts for equality, forwards to the cut-specific implementation.
Definition Cuts.hh:45
std::ostream & operator<<(std::ostream &os, const AnalysisInfo &ai)
Stream an AnalysisInfo as a text description.
Definition AnalysisInfo.hh:463
std::enable_if_t< std::is_floating_point_v< NUM >, bool > isZero(NUM val, double tolerance=1e-8)
Compare a number to zero.
Definition MathUtils.hh:23
double add(double a, double b, double tolerance=1e-5)
Add two numbers with FP fuzziness.
Definition MathUtils.hh:248
std::string toString(const AnalysisInfo &ai)
String representation.
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&(std::is_floating_point_v< N1 >||std::is_floating_point_v< N2 >), bool > fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition MathUtils.hh:66