1#ifndef RIVET_MATH_MATRIXN
2#define RIVET_MATH_MATRIXN
4#include "Rivet/Math/MathConstants.hh"
5#include "Rivet/Math/MathUtils.hh"
6#include "Rivet/Math/Vectors.hh"
8#include "Rivet/Math/eigen3/Dense"
15 typedef Matrix<4> Matrix4;
18 Matrix<N> multiply(
const Matrix<N>& a,
const Matrix<N>& b);
20 Matrix<N> divide(
const Matrix<N>&,
const double);
22 Matrix<N> operator*(
const Matrix<N>& a,
const Matrix<N>& b);
50 for (
size_t i = 0; i < N; ++i) {
51 rtn.set(i, i, diag[i]);
58 for (
size_t i = 0; i < N; ++i) {
67 Matrix() : _matrix(EMatrix::Zero()) {}
71 Matrix& set(
const size_t i,
const size_t j,
const double value) {
73 _matrix(i, j) = value;
75 throw std::runtime_error(
"Attempted set access outside matrix bounds.");
80 double get(
const size_t i,
const size_t j)
const {
84 throw std::runtime_error(
"Attempted get access outside matrix bounds.");
88 Vector<N> getRow(
const size_t row)
const {
90 for (
size_t i = 0; i < N; ++i) {
91 rtn.
set(i, _matrix(row,i));
97 for (
size_t i = 0; i < N; ++i) {
98 _matrix(row,i) = r.get(i);
103 Vector<N> getColumn(
const size_t col)
const {
105 for (
size_t i = 0; i < N; ++i) {
106 rtn.
set(i, _matrix(i,col));
112 for (
size_t i = 0; i < N; ++i) {
113 _matrix(i,col) = c.get(i);
120 tmp._matrix = _matrix.transpose();
132 tmp._matrix = _matrix.
inverse();
138 return _matrix.determinant();
144 for (
size_t i = 0; i < N; ++i) {
154 rtn._matrix = -_matrix;
159 constexpr size_t size()
const {
164 bool isZero(
double tolerance=1E-5)
const {
165 for (
size_t i=0; i < N; ++i) {
166 for (
size_t j=0; j < N; ++j) {
175 for (
size_t i=0; i < N; ++i) {
176 for (
size_t j=i; j < N; ++j) {
177 if (!
Rivet::isZero(_matrix(i,j) - other._matrix(i,j)) )
return false;
185 return isEqual(this->transpose());
190 for (
size_t i=0; i < N; ++i) {
191 for (
size_t j=0; j < N; ++j) {
192 if (i == j)
continue;
199 bool operator == (
const Matrix<N>& a)
const {
200 return _matrix == a._matrix;
203 bool operator != (
const Matrix<N>& a)
const {
204 return _matrix != a._matrix;
223 Matrix<N>& operator *= (
const Matrix<N>& m) {
224 _matrix *= m._matrix;
228 Matrix<N>& operator *= (
const double a) {
233 Matrix<N>& operator /= (
const double a) {
238 Matrix<N>& operator += (
const Matrix<N>& m) {
239 _matrix += m._matrix;
243 Matrix<N>& operator -= (
const Matrix<N>& m) {
244 _matrix -= m._matrix;
250 using EMatrix = RivetEigen::Matrix<double,N,N>;
260 inline Matrix<N> add(
const Matrix<N>& a,
const Matrix<N>& b) {
262 result._matrix = a._matrix + b._matrix;
267 inline Matrix<N> subtract(
const Matrix<N>& a,
const Matrix<N>& b) {
272 inline Matrix<N> operator + (
const Matrix<N> a,
const Matrix<N>& b) {
277 inline Matrix<N> operator - (
const Matrix<N> a,
const Matrix<N>& b) {
278 return subtract(a, b);
282 inline Matrix<N> multiply(
const double a,
const Matrix<N>& m) {
284 rtn._matrix = a * m._matrix;
289 inline Matrix<N> multiply(
const Matrix<N>& m,
const double a) {
290 return multiply(a, m);
294 inline Matrix<N> divide(
const Matrix<N>& m,
const double a) {
295 return multiply(1/a, m);
299 inline Matrix<N> operator * (
const double a,
const Matrix<N>& m) {
300 return multiply(a, m);
304 inline Matrix<N> operator * (
const Matrix<N>& m,
const double a) {
305 return multiply(a, m);
309 inline Matrix<N> multiply(
const Matrix<N>& a,
const Matrix<N>& b) {
311 tmp._matrix = a._matrix * b._matrix;
316 inline Matrix<N> operator * (
const Matrix<N>& a,
const Matrix<N>& b) {
317 return multiply(a, b);
322 inline Vector<N> multiply(
const Matrix<N>& a,
const Vector<N>& b) {
324 tmp._vec = a._matrix * b._vec;
329 inline Vector<N> operator * (
const Matrix<N>& a,
const Vector<N>& b) {
330 return multiply(a, b);
334 inline Matrix<N> transpose(
const Matrix<N>& m) {
342 return m.transpose();
346 inline Matrix<N> inverse(
const Matrix<N>& m) {
351 inline double det(
const Matrix<N>& m) {
352 return m.determinant();
356 inline double trace(
const Matrix<N>& m) {
367 std::ostringstream ss;
369 for (
size_t i = 0; i < m.size(); ++i) {
371 for (
size_t j = 0; j < m.size(); ++j) {
372 const double e = m.get(i, j);
396 for (
size_t i = 0; i < N; ++i) {
397 for (
size_t j = 0; j < N; ++j) {
398 const double a = ma.get(i, j);
399 const double b = mb.get(i, j);
410 return m.isZero(tolerance);
General -dimensional mathematical matrix object.
Definition MatrixN.hh:30
double trace() const
Calculate trace.
Definition MatrixN.hh:142
double det() const
Calculate determinant.
Definition MatrixN.hh:137
Matrix< N > operator-() const
Negate.
Definition MatrixN.hh:152
bool isZero(double tolerance=1E-5) const
Index-wise check for nullness, allowing for numerical precision.
Definition MatrixN.hh:164
constexpr size_t size() const
Get dimensionality.
Definition MatrixN.hh:159
bool isDiag() const
Check that all off-diagonal elements are zero, allowing for numerical precision.
Definition MatrixN.hh:189
Matrix< N > inverse() const
Calculate inverse.
Definition MatrixN.hh:130
bool isSymm() const
Check for symmetry under transposition.
Definition MatrixN.hh:184
bool isEqual(Matrix< N > other) const
Check for index-wise equality, allowing for numerical precision.
Definition MatrixN.hh:174
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:60
Definition MC_Cent_pPb.hh:10
std::ostream & operator<<(std::ostream &os, const AnalysisInfo &ai)
Stream an AnalysisInfo as a text description.
Definition AnalysisInfo.hh:368
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:57
std::string toString(const AnalysisInfo &ai)
String representation.
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:24