From b1d19316100032cd889b949b02897feab685fbd5 Mon Sep 17 00:00:00 2001 From: Matthias Frey <matthias.frey@psi.ch> Date: Wed, 15 Jul 2020 14:01:46 +0200 Subject: [PATCH] RealDiracMatrix: remove unused functions, change storage type of ublas vector and fix bug in function 'transform' --- src/Distribution/RealDiracMatrix.cpp | 124 ++++++--------------- src/Distribution/RealDiracMatrix.h | 50 ++++----- src/Distribution/matrix_vector_operation.h | 6 +- 3 files changed, 56 insertions(+), 124 deletions(-) diff --git a/src/Distribution/RealDiracMatrix.cpp b/src/Distribution/RealDiracMatrix.cpp index 681527b9f..8b1cdd7bc 100644 --- a/src/Distribution/RealDiracMatrix.cpp +++ b/src/Distribution/RealDiracMatrix.cpp @@ -29,7 +29,7 @@ #include <string> #include "matrix_vector_operation.h" -RealDiracMatrix::RealDiracMatrix() : NumOfRDMs(16), DimOfRDMs(4) {}; +RealDiracMatrix::RealDiracMatrix() {}; typename RealDiracMatrix::sparse_matrix_t RealDiracMatrix::getRDM(short i) { @@ -59,56 +59,6 @@ RealDiracMatrix::getRDM(short i) { } -typename RealDiracMatrix::vector_t -RealDiracMatrix::decompose(const matrix_t& M) { - /* - * Formula (11) from paper: - * Geometrical method of decoupling - */ - if (M.size1() != 4 && M.size1() != M.size2()) { - throw OpalException("RealDiracMatrix::decompose()", - "Wrong matrix dimensions."); - } - - vector_t coeffs(16); - - matrix_t left(4,4), right(4,4), rdm2(4,4); - - double inv32 = 1.0 / 32.0; - - // do it with iterators - for (short i = 0; i < 16; ++i) { - sparse_matrix_t rdm = getRDM(i); - left = boost::numeric::ublas::prod(M,rdm); - right = boost::numeric::ublas::prod(rdm,M); - rdm2 = boost::numeric::ublas::prod(rdm,rdm); - left *= inv32; - right *= inv32; - left += right; - coeffs(i) = matt_boost::trace(rdm2) * matt_boost::trace(left); - } - return coeffs; -} - - -typename RealDiracMatrix::matrix_t -RealDiracMatrix::combine(const vector_t& coeffs) { - if (coeffs.size() > 16) { - throw OpalException("RealDiracMatrix::combine()", - "Wrong size of coefficient vector."); - } - - // initialize a 4x4 zero matrix - matrix_t M = boost::numeric::ublas::zero_matrix<double>(4,4); - - // evaluate linear combination - for (short i = 0; i < 16; ++i) - M += coeffs(i)*getRDM(i); - - return M; -} - - void RealDiracMatrix::diagonalize(matrix_t& Ms, sparse_matrix_t& R, sparse_matrix_t& invR) { // R and invR store the total transformation @@ -129,39 +79,39 @@ void RealDiracMatrix::diagonalize(matrix_t& Ms, sparse_matrix_t& R, sparse_matri }; // 1. Transformation with \gamma_{0} - P(0) = mult(1); P(1) = mult(2); P(2) = mult(3); - E(0) = mult(4); E(1) = mult(5); E(2) = mult(6); - B(0) = -mult(7); B(1) = -mult(8); B(2) = -mult(9); - mr = boost::numeric::ublas::inner_prod(E,B); // formula (31), paper: Geometrical method of decoupling - mg = boost::numeric::ublas::inner_prod(B,P); // formula (31), paper: Geometrical method of decoupling + P = vector_t({ mult(1), mult(2), mult(3)}); + E = vector_t({ mult(4), mult(5), mult(6)}); + B = vector_t({-mult(7), -mult(8), -mult(9)}); + mr = boost::numeric::ublas::inner_prod(E, B); // formula (31), paper: Geometrical method of decoupling + mg = boost::numeric::ublas::inner_prod(B, P); // formula (31), paper: Geometrical method of decoupling transform(Ms, 0, 0.5 * std::atan2(mg,mr), R, invR); // 2. Transformation with \gamma_{7} - eps = -mult(0); - P(0) = mult(1); P(1) = mult(2); P(2) = mult(3); - E(0) = mult(4); E(1) = mult(5); E(2) = mult(6); - B(0) = -mult(7); B(1) = -mult(8); B(2) = -mult(9); - b = eps*B+matt_boost::cross_prod(E,P); // formula (32), paper: Geometrical method of decoupling + eps = -mult(0); + P = vector_t({ mult(1), mult(2), mult(3)}); + E = vector_t({ mult(4), mult(5), mult(6)}); + B = vector_t({-mult(7), -mult(8), -mult(9)}); + b = eps * B + matt_boost::cross_prod(E, P); // formula (32), paper: Geometrical method of decoupling transform(Ms, 7, 0.5 * std::atan2(b(2), b(1)), R, invR); // 3. Transformation with \gamma_{9} - eps = -mult(0); - P(0) = mult(1); P(1) = mult(2); P(2) = mult(3); - E(0) = mult(4); E(1) = mult(5); E(2) = mult(6); - B(0) = -mult(7); B(1) = -mult(8); B(2) = -mult(9); - b = eps*B+matt_boost::cross_prod(E,P); + eps = -mult(0); + P = vector_t({ mult(1), mult(2), mult(3)}); + E = vector_t({ mult(4), mult(5), mult(6)}); + B = vector_t({-mult(7), -mult(8), -mult(9)}); + b = eps * B + matt_boost::cross_prod(E, P); transform(Ms, 9, -0.5 * std::atan2(b(0), b(1)), R, invR); // 4. Transformation with \gamma_{2} - eps = -mult(0); - P(0) = mult(1); P(1) = mult(2); P(2) = mult(3); - E(0) = mult(4); E(1) = mult(5); E(2) = mult(6); - B(0) = -mult(7); B(1) = -mult(8); B(2) = -mult(9); - mr = boost::numeric::ublas::inner_prod(E,B); - b = eps*B+matt_boost::cross_prod(E,P); + eps = -mult(0); + P = vector_t({ mult(1), mult(2), mult(3)}); + E = vector_t({ mult(4), mult(5), mult(6)}); + B = vector_t({-mult(7), -mult(8), -mult(9)}); + mr = boost::numeric::ublas::inner_prod(E, B); + b = eps * B + matt_boost::cross_prod(E, P); // Transformation distinction made according to function "rdm_Decouple_F" // in rdm.c of Dr. Christian Baumgarten @@ -172,18 +122,18 @@ void RealDiracMatrix::diagonalize(matrix_t& Ms, sparse_matrix_t& R, sparse_matri transform(Ms, 2, 0.5 * std::atanh(b(1) / mr), R, invR); } - eps = -mult(0); - P(0) = mult(1); P(1) = mult(2); P(2) = mult(3); - E(0) = mult(4); E(1) = mult(5); E(2) = mult(6); - B(0) = -mult(7); B(1) = -mult(8); B(2) = -mult(9); + eps = -mult(0); + P = vector_t({ mult(1), mult(2), mult(3)}); + E = vector_t({ mult(4), mult(5), mult(6)}); + B = vector_t({-mult(7), -mult(8), -mult(9)}); // formula (31), paper: Geometrical method of decoupling - mr = boost::numeric::ublas::inner_prod(E,B); - mg = boost::numeric::ublas::inner_prod(B,P); - mb = boost::numeric::ublas::inner_prod(E,P); + mr = boost::numeric::ublas::inner_prod(E, B); + mg = boost::numeric::ublas::inner_prod(B, P); + mb = boost::numeric::ublas::inner_prod(E, P); - double P2 = boost::numeric::ublas::inner_prod(P,P); - double E2 = boost::numeric::ublas::inner_prod(E,E); + double P2 = boost::numeric::ublas::inner_prod(P, P); + double E2 = boost::numeric::ublas::inner_prod(E, E); // 5. Transform with \gamma_{0} transform(Ms, 0, 0.25 * std::atan2(mb,0.5 * (E2 - P2)), R, invR); @@ -225,16 +175,6 @@ RealDiracMatrix::symplex(const matrix_t& M) { } -typename RealDiracMatrix::matrix_t -RealDiracMatrix::cosymplex(const matrix_t& M) { - /* - * formula (16), p, 3 - */ - sparse_matrix_t rdm0 = getRDM(0); - return 0.5 * (M - matt_boost::gemmm<matrix_t>(rdm0,boost::numeric::ublas::trans(M),rdm0)); -} - - void RealDiracMatrix::transform(matrix_t& M, short i, double phi, sparse_matrix_t& Rtot, sparse_matrix_t& invRtot) { @@ -258,7 +198,7 @@ void RealDiracMatrix::transform(short i, double phi, if (phi) { // if phi == 0 --> nothing happens, since R and invR would be identity_matrix matrix sparse_matrix_t I = boost::numeric::ublas::identity_matrix<double>(4); - if (i < 7 && i != 0 && i > 10 && i != 14) { + if ((i < 7 && i != 0) || (i > 10 && i != 14)) { R = I * std::cosh(phi) + getRDM(i) * std::sinh(phi); invR = I * std::cosh(phi) - getRDM(i) * std::sinh(phi); } else { diff --git a/src/Distribution/RealDiracMatrix.h b/src/Distribution/RealDiracMatrix.h index 1c21a74de..ae6fa40ca 100644 --- a/src/Distribution/RealDiracMatrix.h +++ b/src/Distribution/RealDiracMatrix.h @@ -40,7 +40,10 @@ public: /// Dense matrix type definition typedef boost::numeric::ublas::matrix<double> matrix_t; /// Dense vector type definition - typedef boost::numeric::ublas::vector<double> vector_t; + typedef boost::numeric::ublas::vector< + double, + std::vector<double> + > vector_t; /// Default constructor (sets only NumOfRDMs and DimOfRDMs) RealDiracMatrix(); @@ -51,21 +54,6 @@ public: */ sparse_matrix_t getRDM(short); - /*! - * Decomposes a real-valued 4x4 matrix into a linear combination - * and returns a vector containing the coefficients - * @param M an arbitrary real-valued 4x4 matrix - */ - vector_t decompose(const matrix_t&); - - /*! - * Takes a vector of coefficients, evaluates the linear combination of - * RDMs with these coefficients and returns a 4x4 matrix - * - * @param coeffs is a vector of coefficients (at most length NumOfRDMs) - */ - matrix_t combine(const vector_t&); - /*! * Brings a 4x4 symplex matrix into Hamilton form and * computes the transformation matrix and its inverse @@ -91,22 +79,10 @@ public: */ matrix_t symplex(const matrix_t&); - /*! - * @param M 4x4 real-valued matrix - * @returns the cosymplex part of a 4x4 real-valued matrix - */ - matrix_t cosymplex(const matrix_t&); - - /// The number of real Dirac matrices - short NumOfRDMs; - /// The matrix dimension (4x4) - short DimOfRDMs; - - private: - /// /*! * Applies a rotation to the matrix M by a given angle + * * @param M is the matrix to be transformed * @param i is the i-th RDM used for transformation * @param phi is the angle of rotation @@ -115,8 +91,24 @@ private: */ void transform(matrix_t&, short, double, sparse_matrix_t&, sparse_matrix_t&); + /*! + * Obtain transformation matrices. + * + * @param i is the i-th RDM used for transformation + * @param phi is the angle of rotation + * @param R is a reference to the transformation matrix + * @param invR is a reference to the inverse of the transformation matrix + */ void transform(short, double, sparse_matrix_t&, sparse_matrix_t&); + /*! + * Update quantites to decouple the sigma-matrix + * + * @param sigma current state of sigma-matrix + * @param i is the i-th step + * @param R is a reference to the transformation matrix + * @param invR is a reference to the inverse of the transformation matrix + */ void update(matrix_t& sigma, short i, sparse_matrix_t& R, sparse_matrix_t& invR); }; diff --git a/src/Distribution/matrix_vector_operation.h b/src/Distribution/matrix_vector_operation.h index 12be15405..45f7aec46 100644 --- a/src/Distribution/matrix_vector_operation.h +++ b/src/Distribution/matrix_vector_operation.h @@ -55,10 +55,10 @@ namespace matt_boost { } /// Computes the cross product \f$ v_{1}\times v_{2}\f$ of two vectors in \f$ \mathbb{R}^{3} \f$ - template<class V> + template<class V, class A> BOOST_UBLAS_INLINE - ublas::vector<V> cross_prod(ublas::vector<V>& v1, ublas::vector<V>& v2) { - ublas::vector<V> v(v1.size()); + ublas::vector<V, A> cross_prod(ublas::vector<V, A>& v1, ublas::vector<V, A>& v2) { + ublas::vector<V, A> v(v1.size()); if (v1.size() == v2.size() && v1.size() == 3) { v(0) = v1(1) * v2(2) - v1(2) * v2(1); v(1) = v1(2) * v2(0) - v1(0) * v2(2); -- GitLab