API
Scalar API
Types
UnitfulTensors.FastQuantities.AbstractUnitfulScalar
— TypeAbstractUnitfulScalar{TV, TD<:AbstractDimensions} <: Number
Abstract type representing a scalar physical quantity with a numerical value of type TV
and physical dimensions of type TD
.
UnitfulTensors.FastQuantities.UnitfulScalar
— TypeUnitfulScalar{TV, TD<:AbstractDimensions} <: AbstractUnitfulScalar{TV, TD}
Concrete type representing a scalar physical quantity with a numerical value of type TV
and physical dimensions of type TD
.
UnitfulTensors.FastQuantities.AbstractDimensions
— TypeAbstractDimensions
Abstract type representing the dimensions of a physical quantity.
UnitfulTensors.FastQuantities.SIDimensions
— TypeSIDimensions
Concrete type storing the dimensions of a physical quantity as 7 Float32
exponents of SI base units.
Constants
UnitfulTensors.FastQuantities.NoDims
— ConstantNoDims
Physical dimensions of a dimensionless quantity.
Functions
UnitfulTensors.FastQuantities.value
— Functionvalue(x::AbstractUnitfulScalar)
Get the numerical values of an AbstractUnitfulScalar
in the default unit system (SI).
See also: values
, dimensions
.
Base.values
— Methodvalues(x::AbstractUnitfulScalar)
Same as value
, for consistency with AbstractUnitfulTensor
.
See also: dimensions
.
UnitfulTensors.FastQuantities.dimensions
— Methoddimensions(x::AbstractUnitfulScalar)
Get the physical dimensions of an AbstractUnitfulScalar
.
See also: value
.
UnitfulTensors.FastQuantities.dimexps
— Functiondimexps(x::AbstractDimensions)
Represent x
as a product of base dimensions raised to some powers and return a tuple of these powers.
For SIDimensions
, the base dimensions are time, length, mass, current, temperature, amount, luminous intensity.
Tensor API
Basic types
UnitfulTensors.AbstractUnitfulTensor
— TypeAbstractUnitfulTensor{T<:AbstractUnitfulScalar, N} <: AbstractArray{T, N}
An N
-dimensional array of unitful quantities of type T
that can be used in linear or multilinear algebra.
This requirement forces its physical dimensions, represented by AbstractAxesDimensions
, to factorize into a tensor product of dimensions along each axis, represented by AbstractAxisDimensions
. For example, the physical dimensions of an AbstractUnitfulMatrix
are the product of its row and column dimensions.
UnitfulTensors.UnitfulTensor
— TypeUnitfulTensor{N, TV, TD<:AbstractDimensions,
V <: Union{AbstractArray{TV, N}, AbstractQ{TV}},
D <: AbstractAxesDimensions{N, TD}} <:
AbstractUnitfulTensor{UnitfulScalar{TV, TD}, N}
An N
-dimensional array of unitful quantities that can be used in linear or multilinear algebra.
This requirement forces its physical dimensions, represented by AxesDimensions
, to factorize into a tensor product of dimensions along each axis, represented by AxisDimensions
. For example, the physical dimensions of a UnitfulMatrix
are the product of its row and column dimensions.
UnitfulTensor
stores its numerical values as an array of type V
and its dimensions as an AbstractAxesDimensions
of type D
. They can be obtained using values
and dimensions
.
UnitfulTensors.AbstractAxesDimensions
— TypeAbstractAxesDimensions{N, T<:AbstractDimensions} <: AbstractArray{T, N}
Represents the physical dimensions of an N
-dimensional AbstractUnitfulTensor
.
UnitfulTensors.AxesDimensions
— TypeAxesDimensions{N, T<:AbstractDimensions} <: AbstractAxesDimensions{N, T}
Represents the physical dimensions of an N
-dimensional UnitfulTensor
.
UnitfulTensors.AbstractAxisDimensions
— TypeAbstractAxisDimensions{T<:AbstractDimensions} <: AbstractVector{T}
Represents the physical dimensions of an AbstractUnitfulTensor
along some axis.
Used as a building block of AbstractAxesDimensions
.
UnitfulTensors.AxisDimensions
— TypeAxisDimensions{T<:AbstractDimensions} <: AbstractAxisDimensions{T}
Represents the physical dimensions of a UnitfulTensor
along some axis.
Used as a building block of AxesDimensions
.
Extra types
UnitfulTensors.AdjointAxesDimensions
— TypeAdjointAxesDimensions{T<:AbstractDimensions, P<:AbstractVecOrMatDimensions{T}} <:
AbstractMatrixDimensions{T}
Like LinearAlgebra.Adjoint
and LinearAlgebra.Transpose
, but for AbstractAxesDimensions
.
UnitfulTensors.AbstractUnitfulFactorization
— TypeAbstractUnitfulFactorization{T}
Unitful version of LinearAlgebra.Factorization{T}
.
UnitfulTensors.UnitfulFactorization
— TypeUnitfulFactorization{TV, TD, F<:Factorization{TV}, D<:AbstractMatrixDimensions{TD}} <:
AbstractUnitfulFactorization{UnitfulScalar{TV, TD}}
Factorization of an AbstractUnitfulMatrix
.
UnitfulTensors.UnitfulGeneralizedFactorization
— TypeUnitfulGeneralizedFactorization{TV, TD,
F<:Factorization{TV},
D<:Tuple{Vararg{AbstractMatrixDimensions{TD}}}
} <:
AbstractUnitfulFactorization{UnitfulScalar{TV, TD}}
Generalized factorization of two AbstractUnitfulMatrices
.
Type aliases
UnitfulTensors.AbstractUnitfulVector
— TypeAbstractUnitfulVector{T<:AbstractUnitfulScalar}
Alias for AbstractUnitfulTensor{T, 1}
.
UnitfulTensors.UnitfulVector
— TypeUnitfulVector{TV, TD<:AbstractDimensions}
Alias for UnitfulTensor{1, TV, TD}
.
UnitfulTensors.AbstractUnitfulMatrix
— TypeAbstractUnitfulMatrix{T<:AbstractUnitfulScalar}
Alias for AbstractUnitfulTensor{T, 2}
.
UnitfulTensors.UnitfulMatrix
— TypeUnitfulMatrix{TV, TD<:AbstractDimensions}
Alias for UnitfulTensor{2, TV, TD}
.
UnitfulTensors.AbstractVectorDimensions
— TypeAbstractVectorDimensions{T<:AbstractDimensions}
Alias for AbstractAxesDimensions{1, T}
.
UnitfulTensors.AbstractMatrixDimensions
— TypeAbstractMatrixDimensions{T<:AbstractDimensions}
Alias for AbstractAxesDimensions{2, T}
.
UnitfulTensors.AdjointVectorDimensions
— TypeAdjointVectorDimensions{T<:AbstractDimensions}
Alias for AdjointAxesDimensions{T, P} where P <: AbstractVectorDimensions{T}
.
UnitfulTensors.AdjointMatrixDimensions
— TypeAdjointMatrixDimensions{T<:AbstractDimensions}
Alias for AdjointAxesDimensions{T, P} where P <: AbstractMatrixDimensions{T}
.
Constructors
UnitfulTensors.UnitfulTensor
— MethodUnitfulTensor(A::AbstractArray)
Convert an AbstractArray
of UnitfulScalar
s or Number
s to a UnitfulTensor
, which enables efficient operations on the physical dimensions.
The physical dimensions of A
must factorize into a tensor product of dimensions along each axis (e. g., row and column dimensions of a matrix). Other arrays cannot be used in linear or multilinear algebra and will throw an error when attempting to convert them to a UnitfulTensor
.
Examples:
julia> A = UnitfulTensor([1.0 2.0u"s^-1"
3.0u"J" 4.0u"W" ])
2×2 UnitfulMatrix{Float64, SIDimensions, Matrix{Float64}, AxesDimensions{2, SIDimensions}}:
1.0 2.0 s^-1
3.0 kg m^2 s^-2 4.0 kg m^2 s^-3
julia> V = values(A)
2×2 Matrix{Float64}:
1.0 2.0
3.0 4.0
julia> D = dimensions(A)
2×2 AxesDimensions{2, SIDimensions}:
NoDims 𝐓^-1
𝐋^2 𝐌 𝐓^-2 𝐋^2 𝐌 𝐓^-3
julia> A == UnitfulTensor(V, D)
true
julia> inv(A)
2×2 UnitfulMatrix{Float64, SIDimensions, Matrix{Float64}, AxesDimensions{2, SIDimensions}}:
-2.0 1.0 s^2 kg^-1 m^-2
1.5 s -0.5 s^3 kg^-1 m^-2
julia> inv(V)
2×2 Matrix{Float64}:
-2.0 1.0
1.5 -0.5
UnitfulTensors.AxesDimensions
— MethodAxesDimensions(A::AbstractArray{<:AbstractDimensions})
Convert an AbstractArray
of physical dimensions to AxesDimensions
, which enables efficient operations on the dimensions of unitful arrays.
UnitfulTensors.AxesDimensions
— MethodAxesDimensions(dims, scale; normalize = true)
AxesDimensions(dims; normalize = true)
Assemble AxesDimensions
from the physical dimensions along each axis (dims
) and an overall scalar factor (scale
).
The inverse operation of factorizing AxesDimensions
into dims
and scale
can be performed via normdims
and dimscale
.
dims
can be a tuple of AxisDimensions
or a tuple of Vector
s of AbstractDimensions
. If scale == NoDims
, it can be omitted.
By default, dims
are scaled by a scalar factor so that their first element is NoDims
. If you are absolutely sure that dims already satisfy this condition, you may set normalize = false
for performance.
UnitfulTensors.AxisDimensions
— MethodAxisDimensions(dims::AbstractVector; normalize = true)
AxisDimensions(dims::AbstractVector{<:AbstractDimensions}; normalize = true)
Convert an AbstractVector
of AbstractDimensions
to AxisDimensions
.
By default, the dimensions are scaled by a scalar factor so that the first element of AxisDimensions
is NoDims
. If you are absolutely sure that dims already satisfy this condition, you may set normalize = false
for performance.
Functions
Base.values
— Methodvalues(A::AbstractUnitfulTensor)
Get the numerical values of an AbstractUnitfulTensor
in the default unit system (SI).
See also: dimensions
.
UnitfulTensors.FastQuantities.dimensions
— Methoddimensions(A::AbstractUnitfulTensor)
Get the physical dimensions of an AbstractUnitfulTensor
.
See also: values
.
UnitfulTensors.normdims
— Functionnormdims(x::AbstractAxesDimensions)
normdims(x::AbstractAxisDimensions)
normdims(x::AbstractDimensions)
normdims(x::AbstractUnitfulTensor)
Get a tuple of AbstractAxisDimensions
representing the physical dimensions of x
along each axis.
AbstractAxisDimensions
are normalized so that their first element is NoDims
. The scalar normalization factor can be retrieved via dimscale(x)
.
For example, if x
isa
AbstractMatrixDimensions
, normdims
returns its row and column dimensions, and the elements of x
satisfy x[i, j] == dimscale(x) * normdims(x)[1][i] * normdims(x)[2][j]
.
AbstractAxisDimensions
and AbstractDimensions
are treated as 1- and 0-dimensional AbstractAxesDimensions
, respectively.
UnitfulTensors.dimscale
— Functiondimscale(x::AbstractAxesDimensions)
dimscale(x::AbstractAxisDimensions)
dimscale(x::AbstractDimensions)
dimscale(x::AbstractUnitfulTensor)
Get the first element of x
.
AbstractAxesDimensions
are factorized into an overall scalar factor, retrieved by dimscale
, and zero or more AbstractAxisDimensions
, which represent the physical dimensions along each axis. AbstractAxisDimensions
are normalized so that their first element is NoDims
and can be retrieved via normdims(x)
. Normalization ensures that the factorization is unique.
For example, if x
isa
AbstractMatrixDimensions
, the elements of x
satisfy x[i, j] == dimscale(x) * normdims(x)[1][i] * normdims(x)[2][j]
.
AbstractAxisDimensions
and AbstractDimensions
are treated as 1- and 0-dimensional AbstractAxesDimensions
, respectively.
UnitfulTensors.dimsplat
— Functiondimsplat(x)
Return dimscale(x)
and all normdims(x)
as a single tuple.
UnitfulTensors.dimsvec
— Functiondimsvec(a::AbstractAxisDimensions)
Convert AbstractAxisDimensions
to a Vector
of AbstractDimensions
.
For AxisDimensions
, dimsvec
returns the normdims
field.
Don't mutate it, or it will affect any UnitfulTensor
that references this AxisDimensions
internally. Instead, create a copy if necessary.
UnitfulTensors.nodims
— Functionnodims(size...)
Create AxesDimensions
representing the physical dimensions of a dimensionless array of size size
.
Examples
julia> nodims(2, 3)
2×3 AxesDimensions{2, SIDimensions}:
NoDims NoDims NoDims
NoDims NoDims NoDims
julia> UnitfulTensor([1 2 3; 4 5 6], 𝐍 * nodims(2, 3))
2×3 UnitfulMatrix{Int64, SIDimensions, Matrix{Int64}, AxesDimensions{2, SIDimensions}}:
1 mol 2 mol 3 mol
4 mol 5 mol 6 mol
UnitfulTensors.tensor_product
— Functiontensor_product(xs::AbstractAxesDimensionsLike...; init = NoDims)
Compute the tensor product of AbstractAxesDimensions
, AbstractAxisDimensions
, or AbstractDimensions
.
If the argument list may be empty, the init keyword must be supplied (NoDims
if one works with SIDimensions
). ⊗
can be used as a shorthand.
Examples:
julia> 𝐋 ⊗ AxisDimensions([NoDims, 𝐌]) ⊗ AxisDimensions([NoDims, 𝐓])
2×2 AxesDimensions{2, SIDimensions}:
𝐋 𝐋 𝐓
𝐋 𝐌 𝐋 𝐌 𝐓
UnitfulTensors.tensor_factorize
— Functiontensor_factorize(A::AbstractAxesDimensions, factor_ndims::Tuple{Vararg{Int}})
Represent A
as dimscale(A) ⊗ factors[1] ⊗ factors[2] ⊗ ...
, where dimscale(factors[i]) == NoDims
and ndims.(factors) == factor_ndims
.
Returns (factors, dimscale(A))
.
UnitfulTensors.ishomogeneous
— Functionishomogeneous(A::AbstractUnitfulTensor[, d::Integer]) -> Bool
ishomogeneous(A::AbstractAxesDimensions[, d::Integer]) -> Bool
ishomogeneous(A::AbstractArray{<:Number}[, d::Integer]) -> Bool
ishomogeneous(A::AbstractAxisDimensions) -> Bool
Test whether an array is dimensionally homogeneous (all of its elements have the same physical dimensions).
d
can be provided to test homogeneity along a specific (mathematical) dimension.
Most of linear algebra can be applied to dimensionally homogeneous matrices. Notable functions that require homogeneity include svd
and norm
. Least-squares solution of an overdetermined system with \
or pinv
requires homogeneity along the first dimension; otherwise the sum of squares is undefined.
UnitfulTensors.issquareable
— Functionissquareable(A::AbstractUnitfulMatrix) -> Bool
issquareable(A::AbstractMatrixDimensions) -> Bool
issquareable(A::AbstractMatrix{<:Number}) -> Bool
Test whether a matrix can be squared.
Certain functions, such as eigen
and tr
, are defined only for squareable matrices.
UnitfulTensors.isendomorphic
— Functionisendomorphic(A::AbstractUnitfulMatrix) -> Bool
isendomorphic(A::AbstractMatrixDimensions) -> Bool
isendomorphic(A::AbstractMatrix{<:Number}) -> Bool
Test whether a matrix is endomorphic (can represent a linear map from a vector space to itself).
Transcendental functions, such as exp
and log
, are defined only for endomorphic matrices.
Base.match
— Methodmatch(a::AbstractAxisDimensions, b::AbstractAxisDimensions)
Check if two AbstractAxisDimensions
can be multiplied.
This function is used for dimensions checking in AbstractUnitfulMatrix
multiplication.
UnitfulTensors.units_off
— Functionunits_off()
Switch from UnitfulScalar
s and UnitfulTensor
s to plain numbers and arrays of numbers, as if this package was not loaded.
If you are concerned with the overhead of using unitful quantities:
- Run your code on a small-scale problem to check the units
- Call
units_off()
immediately afterusing UnitfulTensors
- Run your code on the actual large-scale problem
If you used UnitfulScalar(...)
, UnitfulTensor(...)
, and the number * u"unit"
syntax for constructing unitful quantities, units_off()
should eliminate all runtime overhead. Quantities are still converted to the default units (SI) upon construction, but then the units are stripped and the rest of the execution proceeds with plain numbers.
However, inner constructors like UnitfulScalar{Float64, SIDimensions}(1., 𝐓)
will still produce unitful quantities, so don't use them.
There is no units_on
switch at present. You will have to restart Julia if you need units again.
Examples
using UnitfulTensors, BenchmarkTools
13u"cm" |> println
typeof(13u"cm") |> println
u = UnitfulTensor([1u"eV", 2u"ns", 3u"μF"])
v = [1.602176634e-19, 1e-9, 3e-6]
@btime $v * $v'
@btime $u * $u'
units_off()
println()
13u"cm" |> println
typeof(13u"cm") |> println
u = UnitfulTensor([1u"eV", 2u"ns", 3u"μF"])
v = [1.602176634e-19, 1e-9, 3e-6]
@btime $v * $v'
@btime $u * $u'
# output
0.13 m
UnitfulScalar{Float64, SIDimensions}
73.610 ns (1 allocation: 128 bytes)
80.519 ns (1 allocation: 128 bytes)
0.13
Float64
73.561 ns (1 allocation: 128 bytes)
73.077 ns (1 allocation: 128 bytes)
3×3 Matrix{Float64}:
2.56697e-38 3.20435e-28 4.80653e-25
3.20435e-28 4.0e-18 6.0e-15
4.80653e-25 6.0e-15 9.0e-12
UnitfulTensors.tensorize_literals
— Functiontensorize_literals()
Make array literals involving AbstractUnitfulScalar
s return UnitfulTensor
s instead of Array
s, so that you don't have to write UnitfulTensor([...])
all the time.
This feature is experimental. It might break something and may be removed in the future.