|
| 1 | +""" |
| 2 | +Lorenz transformation describes the transition from a reference frame P |
| 3 | +to another reference frame P', each of which is moving in a direction with |
| 4 | +respect to the other. The Lorenz transformation implemented in this code |
| 5 | +is the relativistic version using a four vector described by Minkowsky Space: |
| 6 | +x0 = ct, x1 = x, x2 = y, and x3 = z |
| 7 | +
|
| 8 | +NOTE: Please note that x0 is c (speed of light) times t (time). |
| 9 | +
|
| 10 | +So, the Lorenz transformation using a four vector is defined as: |
| 11 | +
|
| 12 | +|ct'| | γ -γβ 0 0| |ct| |
| 13 | +|x' | = |-γβ γ 0 0| *|x | |
| 14 | +|y' | | 0 0 1 0| |y | |
| 15 | +|z' | | 0 0 0 1| |z | |
| 16 | +
|
| 17 | +Where: |
| 18 | + 1 |
| 19 | +γ = --------------- |
| 20 | + ----------- |
| 21 | + / v^2 | |
| 22 | + /(1 - --- |
| 23 | + -/ c^2 |
| 24 | +
|
| 25 | + v |
| 26 | +β = ----- |
| 27 | + c |
| 28 | +
|
| 29 | +Reference: https://en.wikipedia.org/wiki/Lorentz_transformation |
| 30 | +""" |
| 31 | +from __future__ import annotations |
| 32 | + |
| 33 | +from math import sqrt |
| 34 | + |
| 35 | +import numpy as np # type: ignore |
| 36 | +from sympy import symbols # type: ignore |
| 37 | + |
| 38 | +# Coefficient |
| 39 | +# Speed of light (m/s) |
| 40 | +c = 299792458 |
| 41 | + |
| 42 | +# Symbols |
| 43 | +ct, x, y, z = symbols("ct x y z") |
| 44 | +ct_p, x_p, y_p, z_p = symbols("ct' x' y' z'") |
| 45 | + |
| 46 | + |
| 47 | +# Vehicle's speed divided by speed of light (no units) |
| 48 | +def beta(velocity: float) -> float: |
| 49 | + """ |
| 50 | + >>> beta(c) |
| 51 | + 1.0 |
| 52 | +
|
| 53 | + >>> beta(199792458) |
| 54 | + 0.666435904801848 |
| 55 | +
|
| 56 | + >>> beta(1e5) |
| 57 | + 0.00033356409519815205 |
| 58 | +
|
| 59 | + >>> beta(0.2) |
| 60 | + Traceback (most recent call last): |
| 61 | + ... |
| 62 | + ValueError: Speed must be greater than 1! |
| 63 | + """ |
| 64 | + if velocity > c: |
| 65 | + raise ValueError("Speed must not exceed Light Speed 299,792,458 [m/s]!") |
| 66 | + |
| 67 | + # Usually the speed u should be much higher than 1 (c order of magnitude) |
| 68 | + elif velocity < 1: |
| 69 | + raise ValueError("Speed must be greater than 1!") |
| 70 | + return velocity / c |
| 71 | + |
| 72 | + |
| 73 | +def gamma(velocity: float) -> float: |
| 74 | + """ |
| 75 | + >>> gamma(4) |
| 76 | + 1.0000000000000002 |
| 77 | +
|
| 78 | + >>> gamma(1e5) |
| 79 | + 1.0000000556325075 |
| 80 | +
|
| 81 | + >>> gamma(3e7) |
| 82 | + 1.005044845777813 |
| 83 | +
|
| 84 | + >>> gamma(2.8e8) |
| 85 | + 2.7985595722318277 |
| 86 | +
|
| 87 | + >>> gamma(299792451) |
| 88 | + 4627.49902669495 |
| 89 | +
|
| 90 | + >>> gamma(0.3) |
| 91 | + Traceback (most recent call last): |
| 92 | + ... |
| 93 | + ValueError: Speed must be greater than 1! |
| 94 | +
|
| 95 | + >>> gamma(2*c) |
| 96 | + Traceback (most recent call last): |
| 97 | + ... |
| 98 | + ValueError: Speed must not exceed Light Speed 299,792,458 [m/s]! |
| 99 | + """ |
| 100 | + return 1 / (sqrt(1 - beta(velocity) ** 2)) |
| 101 | + |
| 102 | + |
| 103 | +def transformation_matrix(velocity: float) -> np.array: |
| 104 | + """ |
| 105 | + >>> transformation_matrix(29979245) |
| 106 | + array([[ 1.00503781, -0.10050378, 0. , 0. ], |
| 107 | + [-0.10050378, 1.00503781, 0. , 0. ], |
| 108 | + [ 0. , 0. , 1. , 0. ], |
| 109 | + [ 0. , 0. , 0. , 1. ]]) |
| 110 | +
|
| 111 | + >>> transformation_matrix(19979245.2) |
| 112 | + array([[ 1.00222811, -0.06679208, 0. , 0. ], |
| 113 | + [-0.06679208, 1.00222811, 0. , 0. ], |
| 114 | + [ 0. , 0. , 1. , 0. ], |
| 115 | + [ 0. , 0. , 0. , 1. ]]) |
| 116 | +
|
| 117 | + >>> transformation_matrix(1) |
| 118 | + array([[ 1.00000000e+00, -3.33564095e-09, 0.00000000e+00, |
| 119 | + 0.00000000e+00], |
| 120 | + [-3.33564095e-09, 1.00000000e+00, 0.00000000e+00, |
| 121 | + 0.00000000e+00], |
| 122 | + [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00, |
| 123 | + 0.00000000e+00], |
| 124 | + [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, |
| 125 | + 1.00000000e+00]]) |
| 126 | +
|
| 127 | + >>> transformation_matrix(0) |
| 128 | + Traceback (most recent call last): |
| 129 | + ... |
| 130 | + ValueError: Speed must be greater than 1! |
| 131 | +
|
| 132 | + >>> transformation_matrix(c * 1.5) |
| 133 | + Traceback (most recent call last): |
| 134 | + ... |
| 135 | + ValueError: Speed must not exceed Light Speed 299,792,458 [m/s]! |
| 136 | + """ |
| 137 | + return np.array( |
| 138 | + [ |
| 139 | + [gamma(velocity), -gamma(velocity) * beta(velocity), 0, 0], |
| 140 | + [-gamma(velocity) * beta(velocity), gamma(velocity), 0, 0], |
| 141 | + [0, 0, 1, 0], |
| 142 | + [0, 0, 0, 1], |
| 143 | + ] |
| 144 | + ) |
| 145 | + |
| 146 | + |
| 147 | +def transform( |
| 148 | + velocity: float, event: np.array = np.zeros(4), symbolic: bool = True |
| 149 | +) -> np.array: |
| 150 | + """ |
| 151 | + >>> transform(29979245,np.array([1,2,3,4]), False) |
| 152 | + array([ 3.01302757e+08, -3.01302729e+07, 3.00000000e+00, 4.00000000e+00]) |
| 153 | +
|
| 154 | + >>> transform(29979245) |
| 155 | + array([1.00503781498831*ct - 0.100503778816875*x, |
| 156 | + -0.100503778816875*ct + 1.00503781498831*x, 1.0*y, 1.0*z], |
| 157 | + dtype=object) |
| 158 | +
|
| 159 | + >>> transform(19879210.2) |
| 160 | + array([1.0022057787097*ct - 0.066456172618675*x, |
| 161 | + -0.066456172618675*ct + 1.0022057787097*x, 1.0*y, 1.0*z], |
| 162 | + dtype=object) |
| 163 | +
|
| 164 | + >>> transform(299792459, np.array([1,1,1,1])) |
| 165 | + Traceback (most recent call last): |
| 166 | + ... |
| 167 | + ValueError: Speed must not exceed Light Speed 299,792,458 [m/s]! |
| 168 | +
|
| 169 | + >>> transform(-1, np.array([1,1,1,1])) |
| 170 | + Traceback (most recent call last): |
| 171 | + ... |
| 172 | + ValueError: Speed must be greater than 1! |
| 173 | + """ |
| 174 | + # Ensure event is not a vector of zeros |
| 175 | + if not symbolic: |
| 176 | + |
| 177 | + # x0 is ct (speed of ligt * time) |
| 178 | + event[0] = event[0] * c |
| 179 | + else: |
| 180 | + |
| 181 | + # Symbolic four vector |
| 182 | + event = np.array([ct, x, y, z]) |
| 183 | + |
| 184 | + return transformation_matrix(velocity).dot(event) |
| 185 | + |
| 186 | + |
| 187 | +if __name__ == "__main__": |
| 188 | + import doctest |
| 189 | + |
| 190 | + doctest.testmod() |
| 191 | + |
| 192 | + # Example of symbolic vector: |
| 193 | + four_vector = transform(29979245) |
| 194 | + print("Example of four vector: ") |
| 195 | + print(f"ct' = {four_vector[0]}") |
| 196 | + print(f"x' = {four_vector[1]}") |
| 197 | + print(f"y' = {four_vector[2]}") |
| 198 | + print(f"z' = {four_vector[3]}") |
| 199 | + |
| 200 | + # Substitute symbols with numerical values: |
| 201 | + values = np.array([1, 1, 1, 1]) |
| 202 | + sub_dict = {ct: c * values[0], x: values[1], y: values[2], z: values[3]} |
| 203 | + numerical_vector = [four_vector[i].subs(sub_dict) for i in range(0, 4)] |
| 204 | + |
| 205 | + print(f"\n{numerical_vector}") |
0 commit comments