From 0b8f90db6f06a3ee69e12475df688afa4c5f73c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Mon, 25 Feb 2019 18:11:22 +0200 Subject: [PATCH] Move typedefs from wigner.h to qpms_types.h; new qpms_vswf_irot_elem_from_irot3 fun. Former-commit-id: 0db6bbaade3993108c7227bfae67f5c22ab9df3e --- qpms/qpms_cdefs.pxd | 22 +++++++++++----------- qpms/qpms_types.h | 26 ++++++++++++++++++++++++++ qpms/wigner.c | 14 +++++++++++++- qpms/wigner.h | 32 ++++++++++++-------------------- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/qpms/qpms_cdefs.pxd b/qpms/qpms_cdefs.pxd index bc203ca..1606e26 100644 --- a/qpms/qpms_cdefs.pxd +++ b/qpms/qpms_cdefs.pxd @@ -37,6 +37,17 @@ cdef extern from "qpms_types.h": ctypedef int qpms_lm_t ctypedef int qpms_l_t ctypedef int qpms_m_t + struct qpms_quat_t: + cdouble a + cdouble b + struct qpms_quat4d_t: + double c1 + double ci + double cj + double ck + struct qpms_irot3_t: + qpms_quat_t rot + short det # maybe more if needed # Point generators from lattices.h @@ -75,14 +86,6 @@ cdef extern from "lattices.h": ctypedef double complex cdouble cdef extern from "wigner.h": - struct qpms_quat_t: - cdouble a - cdouble b - struct qpms_quat4d_t: - double c1 - double ci - double cj - double ck qpms_quat_t qpms_quat_2c_from_4d(qpms_quat4d_t q) qpms_quat4d_t qpms_quat_4d_from_2c(qpms_quat_t q) qpms_quat_t qpms_quat_mult(qpms_quat_t p, qpms_quat_t q) @@ -97,9 +100,6 @@ cdef extern from "wigner.h": qpms_quat_t qpms_quat_pow(qpms_quat_t q, double exponent) cdouble qpms_wignerD_elem(qpms_quat_t q, qpms_l_t l, qpms_m_t mp, qpms_m_t m) - struct qpms_irot3_t: - qpms_quat_t rot - short det qpms_irot3_t qpms_irot3_mult(qpms_irot3_t p, qpms_irot3_t q) qpms_irot3_t qpms_irot3_pow(qpms_irot3_t p, int n) diff --git a/qpms/qpms_types.h b/qpms/qpms_types.h index 34e34f7..6d34e46 100644 --- a/qpms/qpms_types.h +++ b/qpms/qpms_types.h @@ -254,6 +254,32 @@ typedef enum { QPMS_COORDS_CART3 = 1024, ///< 3D cartesian. } qpms_coord_system_t; +/// Quaternion type. +/** + * Internaly represented as a pair of complex numbers, + * \f$ Q_a = Q_1 + iQ_z, Q_b = Q_y + i Q_x\f$. + * + * Check wigner.h for "methods". + */ +typedef struct qpms_quat_t { + complex double a, b; +} qpms_quat_t; + +/// Quaternion type as four doubles. +/** Check wigner.h for "methods". + */ +typedef struct qpms_quat4d_t { + double c1, ci, cj, ck; +} qpms_quat4d_t; + +/// 3D improper rotations represented as a quaternion and a sign of the determinant. +/** Check wigner.h for "methods". + */ +typedef struct qpms_irot3_t { + qpms_quat_t rot; ///< Quaternion representing the rotation part. + short det; ///< Determinant of the transformation (valid values are 1 (rotation) or -1 (improper rotation) +} qpms_irot3_t; + #define lmcheck(l,m) assert((l) >= 1 && abs(m) <= (l)) #endif // QPMS_TYPES diff --git a/qpms/wigner.c b/qpms/wigner.c index 779e405..80cf86b 100644 --- a/qpms/wigner.c +++ b/qpms/wigner.c @@ -54,4 +54,16 @@ complex double qpms_wignerD_elem(const qpms_quat_t R, } } - +complex double qpms_vswf_irot_elem_from_irot3(const_qpms_irot3_t q, + qpms_l_t l, qpms_m_t mp, qpms_m_t m, bool pseudo) { +#ifndef NDEBUG + qpms_irot3_checkdet(q); +#endif + complex double res = qpms_wignerD_elem(q.rot, l, mp); + if (q.det == -1) { + res *= min1pow(l); + if (pseudo) + res *= -1; + } + return res; +} diff --git a/qpms/wigner.h b/qpms/wigner.h index b575e68..f7e89e3 100644 --- a/qpms/wigner.h +++ b/qpms/wigner.h @@ -8,25 +8,6 @@ #include "tiny_inlines.h" -/// Quaternion type. -/** - * Internaly represented as a pair of complex numbers, - * \f$ Q_a = Q_1 + iQ_z, Q_b = Q_y + i Q_x\f$. - */ -typedef struct qpms_quat_t { - complex double a, b; -} qpms_quat_t; - -/// Quaternion type as four doubles. -typedef struct qpms_quat4d_t { - double c1, ci, cj, ck; -} qpms_quat4d_t; - -/// 3D improper rotations represented as a quaternion and a sign of the determinant. -typedef struct qpms_irot3_t { - qpms_quat_t rot; ///< Quaternion representing the rotation part. - short det; ///< Determinant of the transformation (valid values are 1 (rotation) or -1 (improper rotation) -} qpms_irot3_t; /// Conversion from the 4*double to the 2*complex quaternion. // TODO is this really correct? @@ -134,7 +115,7 @@ static inline qpms_quat_t qpms_quat_pow(const qpms_quat_t q, const double expone return qpms_quat_exp(qe); } -/// Wigner D matrix element from a rotator quaternion for integer l. +/// Wigner D matrix element from a rotator quaternion for integer \a l. /** * The D matrix are calculated using formulae (3), (4), (6), (7) from * http://moble.github.io/spherical_functions/WignerDMatrices.html @@ -142,6 +123,17 @@ static inline qpms_quat_t qpms_quat_pow(const qpms_quat_t q, const double expone complex double qpms_wignerD_elem(qpms_quat_t q, qpms_l_t l, qpms_m_t mp, qpms_m_t m); +/// A VSWF representation element of the O(3) group. +/** + * TODO more doc. + */ +complex double qpms_vswf_irot_elem_from_irot3( + const qpms_irot3_t q, ///< The O(3) element in the quaternion representation. + qpms_l_t l, qpms_m_t mp, qpms_m_t m, + bool pseudo ///< Determines the sign of improper rotations. True for magnetic waves, false otherwise. + ); + + static inline int qpms_irot3_checkdet(const qpms_irot3_t p) { if (p.det != 1 && p.det != -1) abort(); return 0;