Lorentz transformations
boost.RdLorentz transformations: boosts and rotations
Usage
boost(u=0)
rot(u,v,space=TRUE)
is.consistent.boost(L, give=FALSE, TOL=1e-10)
is.consistent.boost.galilean(L, give=FALSE, TOL=1e-10)
pureboost(L,include_sol=TRUE)
orthog(L)
pureboost.galilean(L, tidy=TRUE)
orthog.galilean(L)Arguments
- u,v
Three-velocities, coerced to class
3vel. In functionboost(), ifutakes the special default value0, this is interpreted as zero three velocity- L
Lorentz transformation expressed as a \(4\times 4\) matrix
- TOL
Numerical tolerance
- give
Boolean with
TRUEmeaning to return the transformed metric tensor (which should be the flat-spaceeta(); qv) and defaultFALSEmeaning to return whether the matrix is a consistent boost or not- space
Boolean, with default
TRUEmeaning to return just the spatial component of the rotation matrix andFALSEmeaning to return the full \(4\times 4\) matrix transformation- tidy
In
pureboost.galilean(), Boolean with defaultTRUEmeaning to return a “tidy” boost matrix with spatial components forced to be a \(3\times 3\) identity matrix- include_sol
In function
pureboost(), Boolean with defaultTRUEmeaning to correctly account for the speed of light, andFALSEmeaning to assume \(c=1\). See details
Details
Arguments u,v are coerced to three-velocities.
A rotation-free Lorentz transformation is known as a boost
(sometimes a pure boost), here expressed in matrix form. Pure
boost matrices are symmetric if \(c=1\). Function boost(u)
returns a \(4\times 4\) matrix giving the Lorentz transformation of
an arbitrary three-velocity u.
Boosts can be successively applied with regular matrix multiplication. However, composing two successive pure boosts does not in general return a pure boost matrix: the product is not symmetric in general. Also note that boost matrices do not commute. The resulting matrix product represents a Lorentz transformation.
It is possible to decompose a Lorentz transformation \(L\) into a pure
boost and a spatial rotation. Thus \(L=OP\) where \(O\) is an
orthogonal matrix and \(P\) a pure boost matrix; these are returned by
functions orthog() and pureboost() respectively. If the
speed of light is not equal to 1, the functions still work but can be
confusing.
Functions pureboost.galilean() and orthog.galilean() are
the Newtonian equivalents of pureboost() and orthog(),
intended to be used when the speed of light is infinite (which causes
problems for the relativistic functions).
As noted above, the composition of two pure Lorentz boosts is not
necessarily pure. If we have two successive boosts corresponding to
\(u\) and \(v\), then the composed boost may be decomposed into a
pure boost of boost(u+v) and a rotation of rot(u,v).
The reason argument include_sol exists is that function
orthog() needs to call pureboost() in an environment
where we pretend that \(c=1\).
References
Ungar 2006. “Thomas precession: a kinematic effect...”. European Journal of Physics, 27:L17-L20
Sbitneva 2001. “Nonassociative geometry of special relativity”. International Journal of Theoretical Physics, volume 40, number 1, pages 359–362
Wikipedia contributors 2018. “Wigner rotation”, Wikipedia, The Free Encyclopedia. https://en.wikipedia.org/w/index.php?title=Wigner_rotation&oldid=838661305. Online; accessed 23 August 2018
Note
Function rot() uses crossprod() for efficiency reasons
but is algebraically equivalent to
boost(-u-v) %*% boost(u) %*% boost(v).
Examples
boost(as.3vel(c(0.4,-0.2,0.1)))
#> t x y z
#> t 1.1250879 -0.45003516 0.22501758 -0.11250879
#> x -0.4500352 1.09530507 -0.04765253 0.02382627
#> y 0.2250176 -0.04765253 1.02382627 -0.01191313
#> z -0.1125088 0.02382627 -0.01191313 1.00595657
u <- r3vel(1)
v <- r3vel(1)
w <- r3vel(1)
boost(u) - solve(boost(-u)) # should be zero
#> t x y z
#> t 2.220446e-16 5.551115e-17 -2.775558e-17 1.110223e-16
#> x -5.551115e-17 -2.220446e-16 3.469447e-18 -5.551115e-17
#> y -2.775558e-17 0.000000e+00 0.000000e+00 1.387779e-17
#> z 5.551115e-17 0.000000e+00 6.938894e-18 0.000000e+00
boost(u) %*% boost(v) # not a pure boost (not symmetrical)
#> t x y z
#> t 3.7313117 2.5117035 -2.4494656 -0.7836778
#> x 1.7480214 1.8695281 -0.6044470 -0.4416866
#> y -3.1104905 -1.8972002 2.5323180 0.8143389
#> z 0.4381295 0.4627642 -0.4710528 0.8694343
boost(u+v) # not the same!
#> t x y z
#> t 3.7313117 1.7480214 -3.110490 0.4381295
#> x 1.7480214 1.6458206 -1.149196 0.1618705
#> y -3.1104905 -1.1491958 3.044919 -0.2880380
#> z 0.4381295 0.1618705 -0.288038 1.0405717
boost(v+u) # also not the same!
#> t x y z
#> t 3.7313117 2.5117035 -2.4494656 -0.7836778
#> x 2.5117035 2.3333838 -1.3003437 -0.4160297
#> y -2.4494656 -1.3003437 2.2681222 0.4057209
#> z -0.7836778 -0.4160297 0.4057209 1.1298056
u+v # returns a three-velocity
#> A vector of three-velocities (speed of light = 1)
#> x y z
#> [1,] -0.4684737 0.8336185 -0.1174197
boost(u) %*% boost(v) %*% boost(w) # associative, no brackets needed
#> t x y z
#> t 6.2256740 5.2788979 2.8115207 -1.4098248
#> x 4.4305081 3.5866333 2.6601111 -0.8302246
#> y -4.2404687 -3.9401410 -1.3517184 1.2766054
#> z 0.3847593 0.6914573 -0.0362619 0.8176868
boost(u+(v+w)) # not the same!
#> t x y z
#> t 6.2256740 4.4305081 -4.2404687 0.3847593
#> x 4.4305081 3.7166189 -2.6000939 0.2359198
#> y -4.2404687 -2.6000939 3.4885671 -0.2258004
#> z 0.3847593 0.2359198 -0.2258004 1.0204880
boost((u+v)+w) # also not the same!
#> t x y z
#> t 4.2297189 3.2174487 -2.5268328 0.3919976
#> x 3.2174487 2.9794517 -1.5545682 0.2411664
#> y -2.5268328 -1.5545682 2.2208848 -0.1894007
#> z 0.3919976 0.2411664 -0.1894007 1.0293825
rot(u,v)
#> x y z
#> x 0.9415590 0.3005278 -0.1521505
#> y -0.2459393 0.9219741 0.2991283
#> z 0.2301751 -0.2442271 0.9420045
rot(v,u) # transpose (=inverse) of rot(u,v)
#> x y z
#> x 0.9415590 -0.2459393 0.2301751
#> y 0.3005278 0.9219741 -0.2442271
#> z -0.1521505 0.2991283 0.9420045
rot(u,v,FALSE) %*% boost(v) %*% boost(u)
#> t x y z
#> t 3.7313117 1.7480214 -3.110490 0.4381295
#> x 1.7480214 1.6458206 -1.149196 0.1618705
#> y -3.1104905 -1.1491958 3.044919 -0.2880380
#> z 0.4381295 0.1618705 -0.288038 1.0405717
boost(u+v) # should be the same.
#> t x y z
#> t 3.7313117 1.7480214 -3.110490 0.4381295
#> x 1.7480214 1.6458206 -1.149196 0.1618705
#> y -3.1104905 -1.1491958 3.044919 -0.2880380
#> z 0.4381295 0.1618705 -0.288038 1.0405717
orthog(boost(u) %*% boost(v)) - rot(u,v,FALSE) # zero to numerical precision
#> t x y z
#> t -3.356204e-13 2.384869e-13 -2.329841e-13 -7.413563e-14
#> x 1.646747e-13 -1.103562e-13 1.112999e-13 3.477774e-14
#> y -2.913561e-13 1.967038e-13 -1.935119e-13 -6.239453e-14
#> z 3.785482e-14 -2.717271e-14 2.622902e-14 8.659740e-15
pureboost(boost(v) %*% boost(u)) - boost(u+v) # ditto
#> t x y z
#> t 5.950795e-14 -2.775558e-14 4.884981e-14 -6.938894e-15
#> x -2.797762e-14 1.154632e-14 -2.842171e-14 2.775558e-15
#> y 4.929390e-14 -2.864375e-14 4.574119e-14 -7.160939e-15
#> z -6.994405e-15 2.831069e-15 -7.160939e-15 4.440892e-16
## Define a random-ish Lorentz transformation
L <- boost(r3vel(1)) %*% boost(r3vel(1)) %*% boost(r3vel(1))
## check it:
if (FALSE) # needs emulator package
quad.form(eta(),L) # should be eta()
# \dontrun{}
## More concisely:
is.consistent.boost(L) # should be TRUE
#> [1] TRUE
## Decompose L into a rotation and a pure boost:
U <- orthog(L)
P <- pureboost(L)
L - U %*% P # should be zero (L = UP)
#> t x y z
#> t 2.025047e-13 1.376677e-14 -1.243450e-13 1.634248e-13
#> x 4.440892e-16 1.110223e-16 -2.220446e-15 -1.776357e-15
#> y 1.053380e-12 7.971401e-14 -6.714629e-13 8.046896e-13
#> z -1.030287e-13 -9.325873e-15 6.483702e-14 -7.815970e-14
crossprod(U) # should be identity (U is orthogonal)
#> t x y z
#> t 1.000000e+00 2.308912e-11 -1.987552e-10 2.358591e-10
#> x 2.308912e-11 1.000000e+00 1.483563e-11 -1.758904e-11
#> y -1.987552e-10 1.483563e-11 1.000000e+00 1.515277e-10
#> z 2.358591e-10 -1.758904e-11 1.515277e-10 1.000000e+00
P - t(P) # should be zero (P is symmetric)
#> t x y z
#> t 0 0 0 0
#> x 0 0 0 0
#> y 0 0 0 0
#> z 0 0 0 0
## First row of P should be a consistent 4-velocity:
is.consistent.4vel(P[1,,drop=FALSE],give=TRUE)
#> t
#> -3.093095e-10