PVector
All of the sub-types of Number and Quantity are supported. In general it works as we expected whereas there are too many possibilities to foresee. Mathematically vector operations, linear algebra, array conversions, neighbor searching, etc. are well documented in corresponding sections.
The vector types are immutable out of performance reason.
PVector and PVector2D
Constructor
It is assumed that 3D vectors are used more often, so we choose PVector to represent 3D vectors and provide user-friendly functions to avoid errors in case you missed suffix 2D:
julia> using PhysicalParticlesjulia> PVector(1.0, 2.0)PVector2D{Float64}(1.0, 2.0)julia> PVector(2.0, 3.0, u"m")PVector2D(2.0 m, 3.0 m)
The default constructors of PVector are still 3d-version:
julia> PVector()PVector{Float64}(0.0, 0.0, 0.0)julia> PVector(u"m")PVector(0.0 m, 0.0 m, 0.0 m)
Basic Operators
Basic maths are well support by overriding Base: +, -, *, /, and array operations are supported by overriding Base: length, iterate
julia> a = pconvert(ones(3))PVector{Float64}(1.0, 1.0, 1.0)julia> b = pconvert(ones(3)) * 2PVector{Float64}(2.0, 2.0, 2.0)julia> a + bPVector{Float64}(3.0, 3.0, 3.0)julia> a * b6.0julia> norm(a)1.7320508075688772julia> norm(a) == sqrt(3)truejulia> normalize(a)PVector{Float64}(0.5773502691896258, 0.5773502691896258, 0.5773502691896258)julia> normalize(a) == a / sqrt(3)truejulia> cross(a, b)PVector{Float64}(0.0, 0.0, 0.0)julia> dot(a,b) == *(a,b)truejulia> c = pconvert(ones(3)) * 1.0u"m"PVector(1.0 m, 1.0 m, 1.0 m)julia> c * a3.0 m
More types, more possibilities
T<:Number gives us a whole world to try out new vector operations. As we mentioned above, the build-in type operation and promotion schemes have guaranteed most of operations would be correct:
julia> a = PVector(1.0, 1.0, 1.0) * imPVector{ComplexF64}(0.0 + 1.0im, 0.0 + 1.0im, 0.0 + 1.0im)julia> a * PVector(1, 2, 3)0.0 + 6.0imjulia> norm(a)0.0 + 1.7320508075688772imjulia> b = PVector(1.0f0, 2.0f0)PVector2D{Float32}(1.0f0, 2.0f0)julia> b * 2PVector2D{Float32}(2.0f0, 4.0f0)julia> b * 2.0PVector2D{Float64}(2.0, 4.0)julia> PVector(BigFloat)PVector{BigFloat}(0.0, 0.0, 0.0)julia> PVector2D(BigInt, u"m")PVector2D(0 m, 0 m)
LinearAlgebra
norm, normalize, dot, cross from LinearAlgebra module are overloaded.
However, when it comes to Quantity, some wierd things would happen:
julia> using Unitfuljulia> sqrt(1.0u"km" * 1000.0u"m")31.622776601683793 m^1/2 km^1/2julia> sqrt(upreferred(1.0u"km" * 1000.0u"m"))1000.0 mjulia> 1.0u"km" / sqrt(upreferred(1.0u"km" * 1.0u"km"))0.001 km m^-1
To avoid this, we have to use upreferred in both norm and normalize:
@inline norm(p::PVector2D) = sqrt(upreferred(p * p))
@inline normalize(p::PVector2D) = (n = ustrip(norm(p)); return PVector2D(upreferred(p.x/n), upreferred(p.y/n)))
@inline norm(p::PVector) = sqrt(upreferred(p * p))
@inline normalize(p::PVector) = (n = ustrip(norm(p)); return PVector(upreferred(p.x/n), upreferred(p.y/n), upreferred(p.z/n)))uconvert, ustrip, zero, one
These would be useful when you cannot predict the type of input.
julia> p = PVector(2.0, 2.0, 2.0, u"km")PVector(2.0 km, 2.0 km, 2.0 km)julia> uconvert(u"m", p)PVector(2000.0 m, 2000.0 m, 2000.0 m)julia> ustrip(u"m", p)PVector{Float64}(2000.0, 2000.0, 2000.0)julia> ustrip(p)PVector{Float64}(2.0, 2.0, 2.0)julia> one(u"m", p)PVector(1.0 m, 1.0 m, 1.0 m)julia> one(p)PVector{Float64}(1.0, 1.0, 1.0)julia> zero(u"m", p)PVector(0.0 m, 0.0 m, 0.0 m)julia> zero(p)PVector(0.0 km, 0.0 km, 0.0 km)
parse from string
julia> parse(PVector2D, "PVector2D{Float64}(1.0, 2.0)")PVector2D{Float64}(1.0, 2.0)julia> parse(PVector, "PVector{Float32}(1.0f0, 2.0f0, 3.0f0)")PVector{Float32}(1.0f0, 2.0f0, 3.0f0)julia> parse(PVector, "PVector(1.0f0 m s^-1, 2.0f0 m s^-1, 3.0f0 m s^-1)")PVector(1.0f0 m s^-1, 2.0f0 m s^-1, 3.0f0 m s^-1)julia> parse(PVector2D, "PVector2D{ComplexF64}(1.0im, 2.0im)")PVector2D{ComplexF64}(0.0 + 1.0im, 0.0 + 2.0im)
numeric type conversion
julia> convert(PVector{Float32}, PVector(1.1,2.2,3.3))PVector{Float32}(1.1f0, 2.2f0, 3.3f0)julia> convert(PVector{Int32}, PVector(1.0,2.0,3.0))PVector{Int32}(1, 2, 3)