Skip to content

Bases ​

Basis types and their accessors. Theory: Bases and variance; usage: Bases.

TensND.Basis Type
julia
Basis(v::AbstractMatrix{T}, ::Val{:cov})
Basis{dim, T<:Number}()
Basis(θ::T<:Number, ϕ::T<:Number, ψ::T<:Number)

Basis built from a square matrix v where columns correspond either to

  • primal vectors ie eᵢ=v[:,i] if var=:cov as by default

  • dual vectors ie eⁱ=v[:,i] if var=:cont.

Basis without any argument refers to the canonical basis (CanonicalBasis) in Rᵈⁱᵐ (by default dim=3 and T=Sym)

Basis can also be built from Euler angles (RotatedBasis) θ in 2D and (θ, ϕ, ψ) in 3D

The attributes of this object can be obtained by

  • vecbasis(ℬ, :cov): square matrix defining the primal basis eᵢ=e[:,i]

  • vecbasis(ℬ, :cont): square matrix defining the dual basis eⁱ=E[:,i]

  • metric(ℬ, :cov): square matrix defining the covariant components of the metric tensor gᵢⱼ=eᵢ⋅eⱼ=g[i,j]

  • metric(ℬ, :cont): square matrix defining the contravariant components of the metric tensor gⁱʲ=eⁱ⋅eʲ=gⁱʲ[i,j]

Examples

julia
julia> v = Sym[1 0 0; 0 1 0; 0 1 1] ; ℬ = Basis(v)
Basis{3, Sym}
# basis: 3×3 Tensor{2, 3, Sym, 9}:
 1  0  0
 0  1  0
 0  1  1
# dual basis: 3×3 Tensor{2, 3, Sym, 9}:
 1  0   0
 0  1  -1
 0  0   1
# covariant metric tensor: 3×3 SymmetricTensor{2, 3, Sym, 6}:
 1  0  0
 0  2  1
 0  1  1
# contravariant metric tensor: 3×3 SymmetricTensor{2, 3, Sym, 6}:
 1   0   0
 0   1  -1
 0  -1   2

julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = Basis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
 -sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ)  -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ)  sin(θ)⋅cos(ϕ)
  sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ)  -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ)  sin(θ)⋅sin(ϕ)
                        -sin(θ)⋅cos(ψ)                          sin(θ)⋅sin(ψ)         cos(θ)
TensND.CanonicalBasis Type
julia
CanonicalBasis{dim, T}

Canonical basis of dimension dim (default: 3) and type T (default: Sym)

The attributes of this object can be obtained by

  • vecbasis(ℬ, :cov): square matrix defining the primal basis eᵢ=e[:,i]=δᵢⱼ

  • vecbasis(ℬ, :cont): square matrix defining the dual basis eⁱ=E[:,i]=δᵢⱼ

  • metric(ℬ, :cov): square matrix defining the covariant components of the metric tensor gᵢⱼ=eᵢ⋅eⱼ=g[i,j]=δᵢⱼ

  • metric(ℬ, :cont): square matrix defining the contravariant components of the metric tensor gⁱʲ=eⁱ⋅eʲ=gⁱʲ[i,j]=δᵢⱼ

Examples

julia
julia> ℬ = CanonicalBasis()
CanonicalBasis{3, Sym}
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
 1  0  0
 0  1  0
 0  0  1
# dual basis: 3×3 TensND.LazyIdentity{3, Sym}:
 1  0  0
 0  1  0
 0  0  1
# covariant metric tensor: 3×3 TensND.LazyIdentity{3, Sym}:
 1  0  0
 0  1  0
 0  0  1
# contravariant metric tensor: 3×3 TensND.LazyIdentity{3, Sym}:
 1  0  0
 0  1  0
 0  0  1

julia> ℬ₂ = CanonicalBasis{2, Float64}()
CanonicalBasis{2, Float64}
# basis: 2×2 TensND.LazyIdentity{2, Float64}:
 1.0  0.0
 0.0  1.0
# dual basis: 2×2 TensND.LazyIdentity{2, Float64}:
 1.0  0.0
 0.0  1.0
# covariant metric tensor: 2×2 TensND.LazyIdentity{2, Float64}:
 1.0  0.0
 0.0  1.0
# contravariant metric tensor: 2×2 TensND.LazyIdentity{2, Float64}:
 1.0  0.0
 0.0  1.0
TensND.RotatedBasis Type
julia
RotatedBasis(θ::T<:Number, ϕ::T<:Number, ψ::T<:Number)
RotatedBasis(θ::T<:Number)

Orthonormal basis of dimension dim (default: 3) and type T (default: Sym) built from Euler angles θ in 2D and (θ, ϕ, ψ) in 3D

Examples

julia
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = RotatedBasis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
 -sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ)  -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ)  sin(θ)⋅cos(ϕ)
  sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ)  -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ)  sin(θ)⋅sin(ϕ)
                        -sin(θ)⋅cos(ψ)                          sin(θ)⋅sin(ψ)         cos(θ)
TensND.frame_from_axis Function
julia
frame_from_axis(n; in_plane = nothing, T = nothing) -> RotatedBasis{3}

The right-handed orthonormal basis whose third vector is n normalized, n given by its canonical components (a 3-vector, a tuple or a first-order tensor). is the Gram–Schmidt projection of in_plane on the plane normal to , and   . Without in_plane, the reference is the canonical axis least aligned with n for comparable numbers, which never degenerates; for symbolic ones, the first canonical axis whose projection does not vanish identically. A frame equal to the canonical one is returned as the CanonicalBasis (see RotatedBasis), of the element type that euler_basis gives the data type T when T is given: a symbolic T keeps a symbolic canonical frame, whose exact 0 and 1 add no float to an exact result.

Symbolic components are simplified once here (tsimplify), rather than in every component of every tensor later written in the frame.

TensND.permute_basis Function
julia
permute_basis(ℬ, σ; negate = dim) -> RotatedBasis

The orthonormal basis whose k-th vector is the σ[k]-th vector of ℬ, with the orientation of ℬ: an odd permutation reverses the orientation, so the vector of index negate (the last one by default) is reversed as well. A shape invariant under the reflections of its own axes (an ellipsoid, a crack) is the same shape in the permuted basis, its semi-axes permuted by σ. A basis that is not orthonormal is refused, as by RotatedBasis.

julia
julia> permute_basis(RotatedBasis(0.3, 0.2, 0.1), (2, 1, 3)) ;   # e₂, e₁, -e₃
TensND.euler_basis Function
julia
euler_basis(angles::Tuple; T = Float64) -> AbstractBasis{3}

The orthonormal basis of the ZYZ Euler angles angles, zero to three of them: missing trailing angles are zero, and the angles are promoted to one type — Int or Irrational to a float, a dual staying a dual, a symbolic angle keeping its type. When every angle is zero the basis is the canonical one, of element type Float64 for real numbers (duals included: its entries are exact zeros and ones) and of the symbolic type otherwise, promoted with T — the element type of the data the basis will carry.

julia
julia> euler_basis(()) isa CanonicalBasis{3, Float64}
true

julia> euler_basis((π / 2,)) == RotatedBasis(π / 2, 0.0, 0.0)
true
TensND.canonical_eltype Function
julia
canonical_eltype(T) -> Type

The element type of the canonical basis that carries data of type T, the rule euler_basis follows: Float64 for any real number (duals included: the entries of the canonical basis are exact zeros and ones), T itself for a symbolic or complex type, whose exact 0 and 1 add no float to an exact result.

julia
julia> canonical_eltype(Int)
Float64
TensND.OrthogonalBasis Type
julia
OrthogonalBasis{dim,T}

Orthogonal but not normalized basis: an orthonormal basis scaled by one factor χᵢ per direction.

Its metric is diagonal, gᵢⱼ = diag(χᵢ²), and its dual vectors are 𝐞ⁱ = 𝐞ᵢ/χᵢ², so variance still matters but only diagonally. This is exactly the situation of the natural basis of a curvilinear coordinate system, where the χᵢ are the Lamé coefficients — see Curvilinear differential calculus.

Built by Basis(ℬ, χᵢ) from an orthonormal basis and a tuple of scaling factors. Normalizing it returns the orthonormal basis it came from.

TensND.CylindricalBasis Function
julia
CylindricalBasis(θ)

Local orthonormal basis (𝐞ʳ, 𝐞ᶿ, 𝐞ᶻ) of the cylindrical system at azimuth θ, i.e. RotatedBasis(0, θ, 0).

Convenience constructor for a one-off local frame; for differential calculus use coorsys_cylindrical, which also carries the Lamé coefficients and the Christoffel symbols.

TensND.SphericalBasis Function
julia
SphericalBasis(θ, ϕ)

Local orthonormal basis (𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ) of the spherical system at polar angle θ and azimuth ϕ, i.e. RotatedBasis(θ, ϕ, 0).

Note the ordering: the radial vector comes last, so that θ = ϕ = 0 returns the canonical basis in the canonical order. See Rotations and Euler angles.

Convenience constructor for a one-off local frame; for differential calculus use coorsys_spherical.

TensND.AllOrthogonalBasis Type
julia
AllOrthogonalBasis{dim,T}

Union of every basis whose metric is diagonal: the orthonormal ones (CanonicalBasis, RotatedBasis) and the merely orthogonal OrthogonalBasis.

Used to dispatch the component conversions that need no dense metric.

TensND.vecbasis Function
julia
vecbasis(ℬ::AbstractBasis, var = :cov)

Return the primal (if var = :cov) or dual (if var = :cont) basis

TensND.metric Function
julia
metric(ℬ::AbstractBasis, var = :cov)

Return the covariant (if var = :cov) or contravariant (if var = :cont) metric matrix

TensND.angles Function
julia
angles(M::AbstractMatrix{T})

Determine the Euler angles corresponding to the input matrix supposed to be a rotation matrix or at least a similarity

Examples

julia
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = RotatedBasis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
 -sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ)  -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ)  sin(θ)⋅cos(ϕ)
  sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ)  -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ)  sin(θ)⋅sin(ϕ)
                        -sin(θ)⋅cos(ψ)                          sin(θ)⋅sin(ψ)         cos(θ)

julia> angles(ℬʳ)
(θ = θ, ϕ = ϕ, ψ = ψ)
TensND.isorthogonal Function
julia
isorthogonal(ℬ::AbstractBasis)

Check whether the basis ℬ is orthogonal

TensND.isorthonormal Function
julia
isorthonormal(ℬ::AbstractBasis)

Check whether the basis ℬ is orthonormal

TensND.get_dim Function
julia
get_dim(t::AbstractTens) → Int
get_dim(ℬ::AbstractBasis) → Int

Dimension of the underlying space.

TensND.init_cartesian Function
julia
init_cartesian(coords = symbols("x y z", real = true))

Returns the coordinates, unit vectors and basis of the cartesian basis

Examples

julia
julia> coords, vectors, ℬ = init_cartesian() ; x, y, z = coords ; 𝐞₁, 𝐞₂, 𝐞₃ = vectors ;
TensND.init_polar Function
julia
init_polar(coords = (symbols("r θ", real = true)); canonical = false)

Returns the coordinates, base vectors and basis of the polar basis

Examples

julia
julia> coords, vectors, ℬᵖ = init_polar() ; r, θ = coords ; 𝐞ʳ, 𝐞ᶿ = vectors ;
TensND.init_cylindrical Function
julia
init_cylindrical(coords = (symbols("r", positive = true), symbols("θ z", real = true)...); canonical = false)

Returns the coordinates, base vectors and basis of the cylindrical basis

Examples

julia
julia> coords, vectors, ℬᶜ = init_cylindrical() ; r, θ, z = coords ; 𝐞ʳ, 𝐞ᶿ, 𝐞ᶻ = vectors ;
TensND.init_spherical Function
julia
init_spherical(coords = (symbols("θ ϕ", real = true)..., symbols("r", positive = true)); canonical = false)

Return the coordinates, base vectors and basis of the spherical basis. Take care that the order of the 3 vectors is 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ so that the basis coincides with the canonical one when the angles are null and in consistency the coordinates are ordered as θ, ϕ, r.

Examples

julia
julia> coords, vectors, ℬˢ = init_spherical() ; θ, ϕ, r = coords ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ  = vectors ;
TensND.init_rotated Function
julia
init_rotated(coords = symbols("θ ϕ ψ", real = true); canonical = false)

Return the angles, base vectors and basis of the rotated basis. Note that here the coordinates are angles and do not represent a valid parametrization of ℝ³

Examples

julia
julia> angles, vectors, ℬʳ = init_rotated() ; θ, ϕ, ψ = angles ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = vectors ;