[][src]Trait nalgebra_spacetime::LorentzianN

pub trait LorentzianN<N, R, C> where
    N: Scalar,
    R: DimName,
    C: DimName
{ fn metric() -> Self
    where
        ShapeConstraint: SameDimension<R, C>
;
fn dual(&self) -> Self;
fn r_dual(&self) -> Self;
fn c_dual(&self) -> Self;
fn dual_mut(&mut self);
fn r_dual_mut(&mut self);
fn c_dual_mut(&mut self);
fn contr<R2, C2, SB>(
        &self,
        rhs: &Matrix<N, R2, C2, SB>
    ) -> MatrixMN<N, R, C2>
    where
        R2: Dim,
        C2: Dim,
        SB: Storage<N, R2, C2>,
        ShapeConstraint: AreMultipliable<R, C, R2, C2>,
        DefaultAllocator: Allocator<N, R, C2>
;
fn tr_contr<R2, C2, SB>(
        &self,
        rhs: &Matrix<N, R2, C2, SB>
    ) -> MatrixMN<N, C, C2>
    where
        R2: Dim,
        C2: Dim,
        SB: Storage<N, R2, C2>,
        ShapeConstraint: SameNumberOfRows<R, R2>,
        DefaultAllocator: Allocator<N, C, C2>
;
fn scalar<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
    where
        R2: Dim,
        C2: Dim,
        SB: Storage<N, R2, C2>,
        ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>
;
fn tr_scalar<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
    where
        R2: Dim,
        C2: Dim,
        SB: Storage<N, R2, C2>,
        ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>
;
fn timelike_norm(&self) -> N;
fn spacelike_norm(&self) -> N;
fn interval(&self, rhs: &Self) -> (N, LightCone)
    where
        N: AbsDiffEq,
        ShapeConstraint: DimEq<U1, C>
;
fn interval_fn<P, L>(
        &self,
        rhs: &Self,
        is_present: P,
        is_lightlike: L
    ) -> (N, LightCone)
    where
        ShapeConstraint: DimEq<U1, C>,
        P: Fn(N) -> bool,
        L: Fn(N) -> bool
;
fn new_boost<D>(frame: &FrameN<N, D>) -> Self
    where
        D: DimNameSub<U1>,
        ShapeConstraint: AreMultipliable<R, C, R, C> + DimEq<R, D>,
        DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>
;
fn boost<D>(&self, frame: &FrameN<N, D>) -> Self
    where
        D: DimNameSub<U1>,
        ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
        DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>
;
fn boost_mut<D>(&mut self, frame: &FrameN<N, D>)
    where
        D: DimNameSub<U1>,
        ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
        DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>
;
fn new_velocity<D>(frame: &FrameN<N, D>) -> VectorN<N, D>
    where
        D: DimNameSub<U1>,
        ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
        DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>
;
fn frame(&self) -> FrameN<N, R>
    where
        R: DimNameSub<U1>,
        ShapeConstraint: SameNumberOfColumns<C, U1>,
        DefaultAllocator: Allocator<N, DimNameDiff<R, U1>>
;
fn from_split<D>(
        temporal: &N,
        spatial: &VectorN<N, DimNameDiff<D, U1>>
    ) -> VectorN<N, D>
    where
        D: DimNameSub<U1>,
        ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
        DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
        <DefaultAllocator as Allocator<N, D, U1>>::Buffer: StorageMut<N, D, U1, RStride = U1, CStride = D>
;
fn split(&self) -> (&N, MatrixSliceMN<'_, N, DimNameDiff<R, U1>, C, U1, R>)
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>,
        DefaultAllocator: Allocator<N, R, C>,
        <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>
;
fn split_mut(
        &mut self
    ) -> (&mut N, MatrixSliceMutMN<'_, N, DimNameDiff<R, U1>, C>)
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>,
        DefaultAllocator: Allocator<N, R, C>,
        <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>
;
fn temporal(&self) -> &N
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>
;
fn temporal_mut(&mut self) -> &mut N
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>
;
fn spatial(&self) -> MatrixSliceMN<'_, N, DimNameDiff<R, U1>, C, U1, R>
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>,
        DefaultAllocator: Allocator<N, R, C>,
        <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>
;
fn spatial_mut(
        &mut self
    ) -> MatrixSliceMutMN<'_, N, DimNameDiff<R, U1>, C, U1, R>
    where
        R: DimNameSub<U1>,
        ShapeConstraint: DimEq<U1, C>,
        DefaultAllocator: Allocator<N, R, C>,
        <DefaultAllocator as Allocator<N, R, C>>::Buffer: StorageMut<N, R, C, RStride = U1, CStride = R>
; }

Extension for $n$-dimensional Lorentzian space $\R^{-,+} = \R^{1,n-1}$ with metric signature in spacelike sign convention.

In four dimensions also known as Minkowski space $\R^{-,+} = \R^{1,3}$.

A statically sized column-major matrix whose R rows and C columns coincide with degree-1/degree-2 tensor indices.

Required methods

fn metric() -> Self where
    ShapeConstraint: SameDimension<R, C>, 
[src]

Lorentzian metric tensor $\eta_{\mu \nu}$:

$$ \eta_{\mu \nu} = \begin{pmatrix} -1 & 0 & \dots & 0 \\ 0 & 1 & \ddots & \vdots \\ \vdots & \ddots & \ddots & 0 \\ 0 & \dots & 0 & 1 \end{pmatrix} $$

Avoid matrix multiplication by preferring:

The spacelike sign convention $\R^{-,+} = \R^{1,n-1}$ requires less negations than its timelike alternative $\R^{+,-} = \R^{1,n-1}$. In four dimensions or Minkowski space $\R^{-,+} = \R^{1,3}$ it requires:

  • $n - 2 = 2$ less for degree-1 tensors, and
  • $n (n - 2) = 8$ less for one index of degree-2 tensors, but
  • $0$ less for two indices of degree-2 tensors.

Choosing the component order of $\R^{-,+} = \R^{1,n-1}$ over $\R^{+,-} = \R^{n-1,1}$ identifies the time component of $x^\mu$ as $x^0$ in compliance with the convention of identifying spatial components $x^i$ with Latin alphabet indices starting from $i=1$.

use nalgebra::{Vector4, Matrix4};
use nalgebra_spacetime::LorentzianN;
use approx::assert_ulps_eq;

let eta = Matrix4::<f64>::metric();
let sc = Vector4::new(-1.0, 1.0, 1.0, 1.0);
assert_ulps_eq!(eta, Matrix4::from_diagonal(&sc));

let x = Vector4::<f64>::new_random();
assert_ulps_eq!(x.dual(), eta * x);

let f = Matrix4::<f64>::new_random();
assert_ulps_eq!(f.dual(), eta * f * eta);
assert_ulps_eq!(f.dual(), f.r_dual().c_dual());
assert_ulps_eq!(f.dual(), f.c_dual().r_dual());
assert_ulps_eq!(f.r_dual(), eta * f);
assert_ulps_eq!(f.c_dual(), f * eta);

fn dual(&self) -> Self[src]

Raises/Lowers all of its degree-1/degree-2 tensor indices.

Negates the appropriate components avoiding matrix multiplication.

fn r_dual(&self) -> Self[src]

Raises/Lowers its degree-1/degree-2 row tensor index.

Prefer Self::dual over self.r_dual().c_dual() to half negations.

fn c_dual(&self) -> Self[src]

Raises/Lowers its degree-1/degree-2 column tensor index.

Prefer Self::dual over self.r_dual().c_dual() to half negations.

fn dual_mut(&mut self)[src]

Raises/Lowers all of its degree-1/degree-2 tensor indices in-place.

Negates the appropriate components avoiding matrix multiplication.

fn r_dual_mut(&mut self)[src]

Raises/Lowers its degree-1/degree-2 row tensor index in-place.

Prefer Self::dual over self.r_dual_mut().c_dual_mut() to half negations.

fn c_dual_mut(&mut self)[src]

Raises/Lowers its degree-1/degree-2 column tensor index in-place.

Prefer Self::dual over self.r_dual_mut().c_dual_mut() to half negations.

fn contr<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixMN<N, R, C2> where
    R2: Dim,
    C2: Dim,
    SB: Storage<N, R2, C2>,
    ShapeConstraint: AreMultipliable<R, C, R2, C2>,
    DefaultAllocator: Allocator<N, R, C2>, 
[src]

Lorentzian matrix multiplication of degree-1/degree-2 tensors.

Equals self.c_dual() * rhs, the metric contraction of its column index with rhs's row index.

fn tr_contr<R2, C2, SB>(
    &self,
    rhs: &Matrix<N, R2, C2, SB>
) -> MatrixMN<N, C, C2> where
    R2: Dim,
    C2: Dim,
    SB: Storage<N, R2, C2>,
    ShapeConstraint: SameNumberOfRows<R, R2>,
    DefaultAllocator: Allocator<N, C, C2>, 
[src]

Same as Self::contr but with transposed tensor indices.

Equals self.r_dual().tr_mul(rhs), the metric contraction of its transposed row index with rhs's row index.

fn scalar<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N where
    R2: Dim,
    C2: Dim,
    SB: Storage<N, R2, C2>,
    ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>, 
[src]

Lorentzian inner product of degree-1/degree-2 tensors.

Equals self.dual().dot(rhs), the metric contraction of:

  • one index for degree-1 tensors, and
  • two indices for degree-2 tensors.

Also known as:

  • Minkowski inner product,
  • relativistic dot product,
  • Lorentz scalar, invariant under Lorentz transformations, or
  • spacetime interval between two events, see Self::interval.

fn tr_scalar<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N where
    R2: Dim,
    C2: Dim,
    SB: Storage<N, R2, C2>,
    ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>, 
[src]

Same as Self::scalar but with transposed tensor indices.

Equals self.dual().tr_dot(rhs).

fn timelike_norm(&self) -> N[src]

Lorentzian norm of timelike degree-1/degree-2 tensors.

Equals self.scalar(self).neg().sqrt().

If spacelike, returns NaN or panics if N doesn't support it.

fn spacelike_norm(&self) -> N[src]

Lorentzian norm of spacelike degree-1/degree-2 tensors.

Equals self.scalar(self).sqrt().

If timelike, returns NaN or panics if N doesn't support it.

fn interval(&self, rhs: &Self) -> (N, LightCone) where
    N: AbsDiffEq,
    ShapeConstraint: DimEq<U1, C>, 
[src]

Spacetime interval between two events and region of self's light cone.

Same as Self::interval_fn but with AbsDiffEq::default_epsilon as in:

  • is_present = |time| abs_diff_eq!(time, N::zero()), and
  • is_lightlike = |interval| abs_diff_eq!(interval, N::zero()).

fn interval_fn<P, L>(
    &self,
    rhs: &Self,
    is_present: P,
    is_lightlike: L
) -> (N, LightCone) where
    ShapeConstraint: DimEq<U1, C>,
    P: Fn(N) -> bool,
    L: Fn(N) -> bool
[src]

Spacetime interval between two events and region of self's light cone.

Equals (rhs - self).scalar(&(rhs - self)) where self is subtracted from rhs to depict rhs in self's light cone.

Requires you to approximate when N equals N::zero() via:

  • is_present for the time component of rhs - self, and
  • is_lightlike for the interval.

Their signs are only evaluated in the false branches of is_present and is_lightlike.

See Self::interval for using defaults and approx for further details.

fn new_boost<D>(frame: &FrameN<N, D>) -> Self where
    D: DimNameSub<U1>,
    ShapeConstraint: AreMultipliable<R, C, R, C> + DimEq<R, D>,
    DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>, 
[src]

$ \gdef \uk {\hat u \cdot \vec K} \gdef \Lmu {\Lambda^{\mu'}_{\phantom {\mu'} \mu}} \gdef \Lnu {(\Lambda^T)_\nu^{\phantom \nu \nu'}} $ Lorentz transformation $\Lmu(\hat u, \zeta)$ boosting degree-1/degree-2 tensors to inertial frame of reference.

$$ \Lmu(\hat u, \zeta) = I - \sinh \zeta (\uk) + (\cosh \zeta - 1) (\uk)^2 $$

Where $\uk$ is the generator of the boost along $\hat{u}$ with its spatial components $(u^1, \dots, u^{n-1})$:

$$ \uk = \begin{pmatrix} 0 & u^1 & \dots & u^{n-1} \\ u^1 & 0 & \dots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ u^{n-1} & 0 & \dots & 0 \end{pmatrix} $$

Boosts degree-1 tensors by multiplying it from the left:

$$ x^{\mu'} = \Lmu x^\mu $$

Boosts degree-2 tensors by multiplying it from the left and its transpose (symmetric for pure boosts) from the right:

$$ F^{\mu' \nu'} = \Lmu F^{\mu \nu} \Lnu $$

use nalgebra::{Vector3, Vector4, Matrix4};
use nalgebra_spacetime::{LorentzianN, Frame4};
use approx::assert_ulps_eq;

let event = Vector4::new_random();
let frame = Frame4::from_beta(Vector3::new(0.3, -0.4, 0.6));
let boost = Matrix4::new_boost(&frame);
assert_ulps_eq!(boost * event, event.boost(&frame), epsilon = 1e-14);

fn boost<D>(&self, frame: &FrameN<N, D>) -> Self where
    D: DimNameSub<U1>,
    ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
    DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>, 
[src]

Boosts this degree-1 tensor $x^\mu$ to inertial frame of reference along $\hat u$ with $\zeta$.

use nalgebra::{Vector3, Vector4};
use nalgebra_spacetime::{LorentzianN, Frame4};
use approx::assert_ulps_eq;

let muon_lifetime_at_rest = Vector4::new(2.2e-6, 0.0, 0.0, 0.0);
let muon_frame = Frame4::from_axis_beta(Vector3::z_axis(), 0.9952);
let muon_lifetime = muon_lifetime_at_rest.boost(&muon_frame);
let time_dilation_factor = muon_lifetime[0] / muon_lifetime_at_rest[0];
assert_ulps_eq!(time_dilation_factor, 10.218, epsilon = 1e-3);

See boost_mut() for further details.

fn boost_mut<D>(&mut self, frame: &FrameN<N, D>) where
    D: DimNameSub<U1>,
    ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
    DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>, 
[src]

$ \gdef \xu {(\vec x \cdot \hat u)} $ Boosts this degree-1 tensor $x^\mu$ to inertial frame of reference along $\hat u$ with $\zeta$ in-place.

$$ \begin{pmatrix} x^0 \\ \vec x \end{pmatrix}' = \begin{pmatrix} x^0 \cosh \zeta - \xu \sinh \zeta \\ \vec x + (\xu (\cosh \zeta - 1) - x^0 \sinh \zeta) \hat u \end{pmatrix} $$

use nalgebra::Vector4;
use nalgebra_spacetime::LorentzianN;
use approx::assert_ulps_eq;

// Arbitrary timelike four-momentum.
let mut momentum = Vector4::new(24.3, 5.22, 16.8, 9.35);

// Rest mass.
let mass = momentum.timelike_norm();
// Four-momentum in center-of-momentum frame.
let mass_at_rest = Vector4::new(mass, 0.0, 0.0, 0.0);

// Rest mass is ratio of four-momentum to four-velocity.
let velocity = momentum / mass;
// Four-momentum boosted to center-of-momentum frame.
momentum.boost_mut(&velocity.frame());

// Verify boosting four-momentum to center-of-momentum frame.
assert_ulps_eq!(momentum, mass_at_rest, epsilon = 1e-14);

fn new_velocity<D>(frame: &FrameN<N, D>) -> VectorN<N, D> where
    D: DimNameSub<U1>,
    ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
    DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>, 
[src]

Velocity $u^\mu$ of inertial frame of reference.

fn frame(&self) -> FrameN<N, R> where
    R: DimNameSub<U1>,
    ShapeConstraint: SameNumberOfColumns<C, U1>,
    DefaultAllocator: Allocator<N, DimNameDiff<R, U1>>, 
[src]

Inertial frame of reference of this velocity $u^\mu$.

fn from_split<D>(
    temporal: &N,
    spatial: &VectorN<N, DimNameDiff<D, U1>>
) -> VectorN<N, D> where
    D: DimNameSub<U1>,
    ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
    DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
    <DefaultAllocator as Allocator<N, D, U1>>::Buffer: StorageMut<N, D, U1, RStride = U1, CStride = D>, 
[src]

From temporal and spatial spacetime split.

fn split(&self) -> (&N, MatrixSliceMN<'_, N, DimNameDiff<R, U1>, C, U1, R>) where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>,
    DefaultAllocator: Allocator<N, R, C>,
    <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>, 
[src]

Spacetime split into Self::temporal and Self::spatial.

fn split_mut(
    &mut self
) -> (&mut N, MatrixSliceMutMN<'_, N, DimNameDiff<R, U1>, C>) where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>,
    DefaultAllocator: Allocator<N, R, C>,
    <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>, 
[src]

Mutable spacetime split into Self::temporal_mut and Self::spatial_mut.

use nalgebra::Vector4;
use nalgebra_spacetime::LorentzianN;
use approx::assert_ulps_eq;

let mut spacetime = Vector4::new(1.0, 2.0, 3.0, 4.0);
let (temporal, mut spatial) = spacetime.split_mut();
*temporal += 1.0;
spatial[0] += 2.0;
spatial[1] += 3.0;
spatial[2] += 4.0;
assert_ulps_eq!(spacetime, Vector4::new(2.0, 4.0, 6.0, 8.0));

fn temporal(&self) -> &N where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>, 
[src]

Temporal component.

fn temporal_mut(&mut self) -> &mut N where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>, 
[src]

Mutable temporal component.

fn spatial(&self) -> MatrixSliceMN<'_, N, DimNameDiff<R, U1>, C, U1, R> where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>,
    DefaultAllocator: Allocator<N, R, C>,
    <DefaultAllocator as Allocator<N, R, C>>::Buffer: Storage<N, R, C, RStride = U1, CStride = R>, 
[src]

Spatial components.

fn spatial_mut(
    &mut self
) -> MatrixSliceMutMN<'_, N, DimNameDiff<R, U1>, C, U1, R> where
    R: DimNameSub<U1>,
    ShapeConstraint: DimEq<U1, C>,
    DefaultAllocator: Allocator<N, R, C>,
    <DefaultAllocator as Allocator<N, R, C>>::Buffer: StorageMut<N, R, C, RStride = U1, CStride = R>, 
[src]

Mutable spatial components.

Loading content...

Implementations on Foreign Types

impl<N, R, C> LorentzianN<N, R, C> for MatrixMN<N, R, C> where
    N: SimdRealField + Signed + Real,
    R: DimName,
    C: DimName,
    DefaultAllocator: Allocator<N, R, C>, 
[src]

Loading content...

Implementors

Loading content...