Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
quaternion_utils.py
Go to the documentation of this file.
1import numpy as np
2
3#-----------------------------------------------------------------------------
4def multiply_quats(q1, q2):
5 """q1, q2 must be [scalar, x, y, z] but those may be arrays or scalars"""
6 return np.array([
7 q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3],
8 q1[2]*q2[3] - q2[2]*q1[3] + q1[0]*q2[1] + q2[0]*q1[1],
9 q1[3]*q2[1] - q2[3]*q1[1] + q1[0]*q2[2] + q2[0]*q1[2],
10 q1[1]*q2[2] - q2[1]*q1[2] + q1[0]*q2[3] + q2[0]*q1[3]])
11
12#-----------------------------------------------------------------------------
13def quat_inv(q):
14 """Returns QBar such that Q*QBar = 1"""
15 qConj = -q
16 qConj[0] = -qConj[0]
17 normSqr = multiply_quats(q, qConj)[0]
18 return qConj/normSqr
19
20#-----------------------------------------------------------------------------
21def align_vec_quat(vec):
22 """Returns a unit quaternion that will align vec with the z-axis"""
23 alpha = np.arctan2(vec[1], vec[0])
24 beta = np.arccos(vec[2])
25 gamma = -alpha*vec[2]
26 cb = np.cos(0.5*beta)
27 sb = np.sin(0.5*beta)
28 return np.array([cb*np.cos(0.5*(alpha + gamma)),
29 sb*np.sin(0.5*(gamma - alpha)),
30 sb*np.cos(0.5*(gamma - alpha)),
31 cb*np.sin(0.5*(alpha + gamma))])
32
33#-----------------------------------------------------------------------------
34def transform_time_dependent_vector(quat, vec, inverse=0):
35 """Given (for example) a minimal rotation frame quat, transforms
36 vec from the minimal rotation frame to the inertial frame.
37 With inverse=1, transforms from the inertial frame to the minimal
38 rotation frame."""
39 qInv = quat_inv(quat)
40 if inverse:
41 return transform_time_dependent_vector(qInv, vec, inverse=0)
42
43 return multiply_quats(quat, multiply_quats(np.append(np.array([
44 np.zeros(len(vec[0]))]), vec, 0), qInv))[1:]
45
46
47#-----------------------------------------------------------------------------
48def rotate_in_plane(chi, phase):
49 """ Rotates a given vector, chi, by a clockwise angle, phase, about the
50 z-axis. Can be used for transforming spins from the coprecessing frame to
51 the coorbital frame"""
52 v = chi.T
53 sp = np.sin(phase)
54 cp = np.cos(phase)
55 res = 1.*v
56 res[0] = v[0]*cp + v[1]*sp
57 res[1] = v[1]*cp - v[0]*sp
58 return res.T
59
60#-----------------------------------------------------------------------------
61def transform_vector_coorb_to_inertial(vec_coorb, orbPhase, quat_copr):
62 """Given a vector (of size 3) in coorbital frame, orbital phase in
63 coprecessing frame and a minimal rotation frame quat, transforms
64 the vector from the coorbital to the LAL inertial frame.
65 """
66
67 # Transform to coprecessing frame
68 vec_copr = rotate_in_plane(vec_coorb, -orbPhase)
69
70 # Transform to inertial frame (for the surrogate)
71 vec = transform_time_dependent_vector(np.array([quat_copr]).T,
72 np.array([vec_copr]).T).T[0]
73
74 return np.array(vec)
def align_vec_quat(vec)
Returns a unit quaternion that will align vec with the z-axis.
def rotate_in_plane(chi, phase)
Rotates a given vector, chi, by a clockwise angle, phase, about the z-axis.
def transform_vector_coorb_to_inertial(vec_coorb, orbPhase, quat_copr)
Given a vector (of size 3) in coorbital frame, orbital phase in coprecessing frame and a minimal rota...
def transform_time_dependent_vector(quat, vec, inverse=0)
Given (for example) a minimal rotation frame quat, transforms vec from the minimal rotation frame to ...
def multiply_quats(q1, q2)
q1, q2 must be [scalar, x, y, z] but those may be arrays or scalars
def quat_inv(q)
Returns QBar such that Q*QBar = 1.