Index

Data structure for elements projective space as well as in in products of projective spaces.

Type

PVector{T, N} <: AbstractProjectiveVector{T, N}

A PVector represents a projective vector z which lives in a product of N projective spaces $P(T)^{dᵢ}$. The underlying data structure is a Vector{T}.

PVector(v::AbstractVector, dims::NTuple{N,Int}) where N

Create a projective vector v living in a product of projective spaces with (projective) dimensions dims.

PVector(v, w, ...)

Create the product of projective vectors.

Example

julia> PVector([1,2,3], [4, 5])
[1 : 2 : 3] × [4 : 5]

julia> PVector([1, 2, 3, 4, 5], (2, 1))
[1 : 2 : 3] × [4 : 5]

julia> PVector([1,2,3], [4, 5], [6, 7, 8])
[1 : 2 : 3] × [4 : 5] × [6 : 7 : 8]

Informations and manipulations

dims(z::PVector)

Dimensions of the projective spaces in which z lives.

homvars(z::PVector{T,N})

Return the indices of the homogenization variables.

Example

julia> v = PVector([4, 5, 6], [2, 3], [1, 2])
PVector{Int64, 3}:
 [4, 5, 6] × [2, 3] × [1, 2]

 julia> homvars(v)
 (3, 5, 7)
dimension_indices(z::PVector{T, N})
dimension_indices(dims::NTuple{N, Int})

Return a tuple of N UnitRanges indexing the underlying data.

Example

julia> v = PVector([4, 5, 6], [2, 3], [1, 2])
PVector{Int64, 3}:
 [4, 5, 6] × [2, 3] × [1, 2]

julia> dimension_indices(v)
(1:3, 4:5, 6:7)
dimension_indices_homvars(z::PVector{T, N})
dimension_indices_homvars(dims::NTuple{N, Int})

Return a tuple of N (UnitRange, Int) tuples indexing the underlying data per vector where the last coordinate in each vector is treated separetely.

Example

julia> v = PVector([4, 5, 6], [2, 3], [1, 2])
PVector{Int64, 3}:
 [4, 5, 6] × [2, 3] × [1, 2]

 julia> dimension_indices_homvars(v)
 ((1:2, 3), (4:4, 5), (6:6, 7))
components(v::PVector{T,N})::NTuple{N, PVector{T, 1}}

Decompose the element $v ∈ P(ℂ^n₁) × ... × P(ℂ^nⱼ)$ into $(v₁, …, vⱼ) = v$

Example

julia> v = PVector([1, 2, 3]);
julia> w = PVector([4, 5]);
julia> v × w
[1 : 2 : 3] × [4 : 5]
julia> components(v × w) == (v, w)
true
component(v::PVector{T,N}, i)::PVector{T,1}

Obtain the i-th component of $v ∈ P(ℂ^n₁) × ... × P(ℂ^nⱼ)$.

Example

julia> v = PVector([1, 2, 3]);
julia> w = PVector([4, 5]);
julia> v × w
[1 : 2 : 3] × [4 : 5]
julia> component(v × w, 1)
[1 : 2 : 3]
# alternative you can also indexing
julia> (v × w)[1,:]
[1 : 2 : 3]
combine(v::PVector, w::PVector...)

Combine the projective vectors v and wᵢ to the flattened product. There is also an operator version, × (written imes<tab>).

Example

julia> v = PVector([1, 2, 3]);
julia> w = PVector([4, 5]);
julia> combine(v, w)
[1 : 2 : 3] × [4 : 5]
LinearAlgebra.:×Method.
×(v::PVector, w::PVector...)

Operator version of combine.

Example

julia> v = PVector([1, 2, 3]);
julia> w = PVector([4, 5]);
julia> v × w
[1 : 2 : 3] × [4 : 5]

Conversion between affine and projective space

affine_chart(z::PVector)

Return the affine chart corresponding to the projective vector. This can be seen as the inverse of embed.

Example

julia> v = embed([2.0, 3, 4, 5, 6, 7], (2, 3, 1))
PVector{Float64, 3}:
 [2.0, 3.0, 1.0] × [4.0, 5.0, 6.0, 1.0] × [7.0, 1.0]

julia> affine_chart(v)
6-element Array{Float64,1}:
 2.0
 3.0
 4.0
 5.0
 6.0
 7.0
affine_chart!(x, z::PVector)

Inplace variant of affine_chart.

embed(xs::AbstractVector...; normalize=false)
embed(x::AbstractVector{T}, dims::NTuple{N, Int}; normalize=false)::PVector{T, N}

Embed an affine vector x in a product of affine spaces by the map πᵢ: xᵢ -> [xᵢ; 1] for each subset xᵢ of x according to dims. If normalize is true the vector is normalized.

Examples

julia> embed([2, 3])
PVector{Int64, 1}:
 [2, 3, 1]

julia> embed([2, 3], [4, 5, 6])
PVector{Int64, 2}:
 [2, 3, 1] × [4, 5, 6, 1]

julia> embed([2.0, 3, 4, 5, 6, 7], (2, 3, 1))
PVector{Float64, 3}:
 [2.0, 3.0, 1.0] × [4.0, 5.0, 6.0, 1.0] × [7.0, 1.0]

 julia> embed([2.0, 3, 4, 5, 6, 7], (2, 3, 1), normalize=true)
 PVector{Float64, 3}:
  [0.5345224838248488, 0.8017837257372732, 0.2672612419124244] × [0.45291081365783825, 0.5661385170722978, 0.6793662204867574, 0.11322770341445956] × [0.9899494936611666, 0.1414213562373095]

Other methods

data(z::AbstractProjectiveVector)

Access the underlying vector of z. This is useful to pass the vector into some function which does not know the projective structure.

data(z::AbstractVector)

For general AbstractVectors this is just the identity.

 norm_affine_chart(z::PVector, p::Real=2) where {T, N}

Compute the p-norm of z on it's affine_chart.

LinearAlgebra.normMethod.
norm(z::PVector{T,N}, p::Real=2)::NTuple{N, real(T)}

Compute the p-norm of z per vector space. This always returns a Tuple.

Example

julia> norm(embed([1, 2, 3, 4, 5], (2, 3)))
(2.449489742783178, 7.14142842854285)

julia> norm(embed([1, 2, 3, 4, 5]))
(7.483314773547883,)
LinearAlgebra.normalize!(z::PVector, p::Real=2)

Normalize each component of z separetly.

LinearAlgebra.normalize(z::PVector{T, N}, p::Real=2)::PVector{T,N}

Normalize each component of z separetly.

LinearAlgebra.dotMethod.
LinearAlgebra.dot(v::PVector{T, N}, w::PVector{T2, N}) where {T, T2, N}

Compute the component wise dot product. If decorated with @inbounds the check of the dims of v and w is skipped.

LinearAlgebra.rmul!(z::PVector{T, N}, λ::NTuple{N, <:Number}) where {T, N}
LinearAlgebra.rmul!(z::PVector{T, 1}, λ::Number) where {T}

Multiply each component of zᵢ of z by λ[i].

fubini_study(v::PVector{<:Number,N}, w::PVector{<:Number, N})

Compute the Fubini-Study distance between v and w for each component vᵢ and wᵢ. This is defined as $\arccos|⟨vᵢ,wᵢ⟩|$.

Base.isrealMethod.
isreal(v::PVector{T}, tol::Real)

Check whether there exists a fully real representative of v. For this v is first normalized, and then the largest entry in each component is made real. If after this the imaginary part of every coordinate is less than tol the vector is considered real.

Example

julia> a, b = rand(ComplexF64, 2);
julia> v = PVector(a .* [1,2,3]) × PVector(b .* [4, 5]);
julia> isreal(v, 1e-6)
true