Bases
How to build a basis and read what it stores. The mathematics — dual basis, metric, variance, and why the type hierarchy exists — is on Bases and variance.
Constructors
Basis always returns the most specific type that applies, so the cost of every later component conversion is decided here.
| Call | Returns | Meaning |
|---|---|---|
Basis{dim,T}() | CanonicalBasis | the reference frame |
Basis(θ) | RotatedBasis | 2-D rotation by one angle |
Basis(θ, ϕ, ψ = 0) | RotatedBasis | 3-D rotation, Z–Y–Z Euler angles |
Basis(ℬ, χᵢ) | OrthogonalBasis | ℬ scaled by one factor per direction |
Basis(v::AbstractMatrix, var) | most specific | from a matrix of :cov or :cont vectors |
Basis(eᵢ, eⁱ, gᵢⱼ, gⁱʲ) | Basis | all four matrices given explicitly |
The matrix constructors take the basis vectors as columns, expressed in the canonical basis.
using TensND, SymPy, LinearAlgebra
ℬ = Basis(Sym[1 0 0; 0 1 0; 0 1 1])typeof(ℬ), isorthogonal(ℬ), isorthonormal(ℬ)(Basis{3, Sym}, false, false)An orthonormal basis is detected automatically and gets the cheaper type:
θ, ϕ, ψ = symbols("θ ϕ ψ", real = true)
typeof(Basis(θ, ϕ, ψ))RotatedBasis{3, Sym{PyCall.PyObject}}Accessors
| Function | Returns |
|---|---|
vecbasis(ℬ, :cov) | matrix of the |
vecbasis(ℬ, :cont) | matrix of the dual |
metric(ℬ, :cov) | |
metric(ℬ, :cont) | |
angles(ℬ) | Euler angles of a rotated basis |
get_dim(ℬ) | the dimension |
isorthogonal, isorthonormal | predicates |
metric(ℬ, :cov)tsimplify(metric(ℬ, :cont) * metric(ℬ, :cov))The product of the two metrics is the identity, by construction — the cheapest check that a basis is consistent.
Normalization
LinearAlgebra.normalize``(ℬ) divides each vector by its norm. It removes the scaling but not the obliquity: the metric acquires a unit diagonal while the off-diagonal terms, which measure the angles between the vectors, survive.
metric(normalize(ℬ), :cov)Predefined coordinates and basis vectors
The init_* helpers return a triple (coordinates, vectors, basis):
| Function | Coordinates |
|---|---|
init_cartesian(dim) | |
init_polar | |
init_cylindrical | |
init_spherical | |
init_rotated |
using TensND, SymPy
(r, θ, z), (𝐞ʳ, 𝐞ᶿ, 𝐞ᶻ), ℬᶜ = init_cylindrical()
ℬᶜThe spherical ordering is (\theta,\varphi,r)
Not RotatedBasis. The same applies to coorsys_spherical — see Curvilinear differential calculus.
The canonical keyword
Each init_* takes canonical::Bool. It decides whether the returned vectors carry their components in the canonical basis (true) or in the local rotated basis (false, the default):
(θs, ϕs, rs), (𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ), ℬˢ = init_spherical()
components_canon(𝐞ʳ)The default is usually what you want: further calculations then stay in the rotated frame, where components are the physical ones.