diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 455fa51..a1bcf79 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.3","generation_timestamp":"2024-06-04T18:53:35","documenter_version":"1.4.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.3","generation_timestamp":"2024-06-04T19:38:35","documenter_version":"1.4.1"}} \ No newline at end of file diff --git a/dev/api/clifford.html b/dev/api/clifford.html index e57bafc..d36ee6e 100644 --- a/dev/api/clifford.html +++ b/dev/api/clifford.html @@ -1,20 +1,20 @@ -CliffordNumbers · CliffordNumbers.jl

Clifford numbers

Supertype and associated functions

CliffordNumbers.AbstractCliffordNumberType
AbstractCliffordNumber{Q,T} <: Number

An element of a Clifford algebra, often referred to as a multivector, with quadratic form Q and element type T. These are statically size and therefore should be able to be stored inline in arrays or other data structures.

Interface

Required implementation

All subtypes C of AbstractCliffordNumber{Q} must implement the following functions:

  • CliffordNumbers.similar_type(::Type{C}, ::Type{T}, ::Type{Q}) where {C,T,Q} should construct a

new type similar to C which subtypes AbstractCliffordNumber{Q,T} that may serve as a constructor.

  • Base.getindex(x::C, b::BitIndex{Q}) should allow one to recover the coefficients associated

with each basis blade represented by C.

  • nblades(::Type{C}) should be defined to return the number of basis blades represented by the

type. By default, nblades(x::AbstractCliffordNumber) = nblades(typeof(x)).

  • Base.Tuple(x::C) should return the tuple used to construct x. The fallback is

getfield(x, :data)::Tuple, so any type declared with a NTuple field named data should have this defined automatically.

source
CliffordNumbers.nbladesFunction
nblades(::Type{<:Number}) -> Int
-nblades(x::Number)

Returns the number of blades represented by a Number subtype or instance. For subtypes of Number that are not AbstractCliffordNumber, this is always 1.

This function is separate from Base.length since AbstractCliffordNumber is a scalar type for which collect() returns a zero-dimensional array. For consistency, length(x) should always equal length(collect(x)).

source
CliffordNumbers.scalar_typeFunction
scalar_type(::Type{<:AbstractCliffordNumber{Q,T}}) = T
+CliffordNumbers · CliffordNumbers.jl

Clifford numbers

Supertype and associated functions

CliffordNumbers.AbstractCliffordNumberType
AbstractCliffordNumber{Q,T} <: Number

An element of a Clifford algebra, often referred to as a multivector, with quadratic form Q and element type T. These are statically size and therefore should be able to be stored inline in arrays or other data structures.

Interface

Required implementation

All subtypes C of AbstractCliffordNumber{Q} must implement the following functions:

  • CliffordNumbers.similar_type(::Type{C}, ::Type{T}, ::Type{Q}) where {C,T,Q} should construct a

new type similar to C which subtypes AbstractCliffordNumber{Q,T} that may serve as a constructor.

  • Base.getindex(x::C, b::BitIndex{Q}) should allow one to recover the coefficients associated

with each basis blade represented by C.

  • nblades(::Type{C}) should be defined to return the number of basis blades represented by the

type. By default, nblades(x::AbstractCliffordNumber) = nblades(typeof(x)).

  • Base.Tuple(x::C) should return the tuple used to construct x. The fallback is

getfield(x, :data)::Tuple, so any type declared with a NTuple field named data should have this defined automatically.

source
CliffordNumbers.nbladesFunction
nblades(::Type{<:Number}) -> Int
+nblades(x::Number)

Returns the number of blades represented by a Number subtype or instance. For subtypes of Number that are not AbstractCliffordNumber, this is always 1.

This function is separate from Base.length since AbstractCliffordNumber is a scalar type for which collect() returns a zero-dimensional array. For consistency, length(x) should always equal length(collect(x)).

source
CliffordNumbers.scalar_typeFunction
scalar_type(::Type{<:AbstractCliffordNumber{Q,T}}) = T
 scalar_type(T::Type{<:Union{Real,Complex}}) = T
-scalar_type(x) = scalar_type(typeof(x))

Returns the numeric type associated with an AbstractCliffordNumber instance. For subtypes of Real and Complex, or their instances, this simply returns the input type or instance type.

Why not define eltype?

AbstractCliffordNumber instances behave like numbers, not arrays. If collect() is called on a Clifford number of type T, it should not construct a vector of coefficients; instead it should return an Array{T,0}. Similarly, a broadcasted multiplication should return the same result as normal multiplication, as is the case with complex numbers.

For subtypes T of Number, eltype(T) === T, and this is true for AbstractCliffordNumber.

source
CliffordNumbers.similar_typeFunction
CliffordNumbers.similar_type(
+scalar_type(x) = scalar_type(typeof(x))

Returns the numeric type associated with an AbstractCliffordNumber instance. For subtypes of Real and Complex, or their instances, this simply returns the input type or instance type.

Why not define eltype?

AbstractCliffordNumber instances behave like numbers, not arrays. If collect() is called on a Clifford number of type T, it should not construct a vector of coefficients; instead it should return an Array{T,0}. Similarly, a broadcasted multiplication should return the same result as normal multiplication, as is the case with complex numbers.

For subtypes T of Number, eltype(T) === T, and this is true for AbstractCliffordNumber.

source
CliffordNumbers.similar_typeFunction
CliffordNumbers.similar_type(
     C::Type{<:AbstractCliffordNumber},
     [N::Type{<:BaseNumber} = scalar_type(C)],
     [Q::Val = Val(signature(C))]
-) -> Type{<:AbstractCliffordNumber{Q,N}}

Constructs a type similar to T but with numeric type N and quadratic form Q. The quadratic form must be wrapped in a Val to preserve type stability.

This function must be defined with all its arguments for each concrete type subtyping AbstractCliffordNumber.

source

Concrete types

CliffordNumbers.CliffordNumberType
CliffordNumber{Q,T,L} <: AbstractCliffordNumber{Q,T}

A dense multivector (or Clifford number), with quadratic form Q, element type T, and length L (which depends entirely on Q).

The coefficients are ordered by taking advantage of the natural binary structure of the basis. The grade of an element is given by the Hamming weight of its index. For the algebra of physical space, the order is: 1, e₁, e₂, e₁₂, e₃, e₁₃, e₂₃, e₁₂₃ = i. This order allows for more aggressive SIMD optimization when calculating the geometric product.

source
CliffordNumbers.Z2CliffordNumberType
CliffordNumbers.Z2CliffordNumber{P,Q,T,L} <: AbstractCliffordNumber{Q,T}

A Clifford number whose only nonzero grades are even or odd. Clifford numbers of this form naturally arise as versors, the geometric product of 1-vectors.

The type parameter P is constrained to be a Bool: true for odd grade Clifford numbers, and false for even grade Clifford numbers, corresponding to the Boolean result of each grade modulo 2.

Type aliases

This type is not exported, and usually you will want to refer to the following aliases:

const EvenCliffordNumber{Q,T,L} = Z2CliffordNumber{false,Q,T,L}
-const OddCliffordNumber{Q,T,L} = Z2CliffordNumber{true,Q,T,L}
source
CliffordNumbers.EvenCliffordNumberType
EvenCliffordNumber{P,Q,T,L} (alias for CliffordNumbers.Z2CliffordNumber{false,Q,T,L})

A Clifford number whose only nonzero grades are even. These are the natural choice of representation for rotors and motors (Euclidean isometries preserving orientation, or "proper" isometries), as well as their composition with dilations.

source
CliffordNumbers.OddCliffordNumberType
OddCliffordNumber{P,Q,T,L} (alias for CliffordNumbers.Z2CliffordNumber{true,Q,T,L})

A Clifford number whose only nonzero grades are odd. These are the natural choice of representation for reflections, as well as their compositions with rotors and motors (Euclidean isometries preserving orientation, or "proper" isometries), as well as their composition with dilations.

source
CliffordNumbers.KVectorType
KVector{K,Q,T,L} <: AbstractCliffordNumber{Q,T}

A multivector consisting only linear combinations of basis blades of grade K - in other words, a k-vector.

k-vectors have binomial(dimension(Q), K) components.

source
CliffordNumbers.gradeMethod
grade(::Type{<:KVector{K}}) = K
-grade(x::KVector{K}) = k

Returns the grade represented by a KVector{K}, which is K.

source

Promotion and conversion

CliffordNumbers.scalar_convertFunction
scalar_convert(T::Type{<:Union{Real,Complex}}, x::AbstractCliffordNumber) -> T
+) -> Type{<:AbstractCliffordNumber{Q,N}}

Constructs a type similar to T but with numeric type N and quadratic form Q. The quadratic form must be wrapped in a Val to preserve type stability.

This function must be defined with all its arguments for each concrete type subtyping AbstractCliffordNumber.

source

Concrete types

CliffordNumbers.CliffordNumberType
CliffordNumber{Q,T,L} <: AbstractCliffordNumber{Q,T}

A dense multivector (or Clifford number), with quadratic form Q, element type T, and length L (which depends entirely on Q).

The coefficients are ordered by taking advantage of the natural binary structure of the basis. The grade of an element is given by the Hamming weight of its index. For the algebra of physical space, the order is: 1, e₁, e₂, e₁₂, e₃, e₁₃, e₂₃, e₁₂₃ = i. This order allows for more aggressive SIMD optimization when calculating the geometric product.

source
CliffordNumbers.Z2CliffordNumberType
CliffordNumbers.Z2CliffordNumber{P,Q,T,L} <: AbstractCliffordNumber{Q,T}

A Clifford number whose only nonzero grades are even or odd. Clifford numbers of this form naturally arise as versors, the geometric product of 1-vectors.

The type parameter P is constrained to be a Bool: true for odd grade Clifford numbers, and false for even grade Clifford numbers, corresponding to the Boolean result of each grade modulo 2.

Type aliases

This type is not exported, and usually you will want to refer to the following aliases:

const EvenCliffordNumber{Q,T,L} = Z2CliffordNumber{false,Q,T,L}
+const OddCliffordNumber{Q,T,L} = Z2CliffordNumber{true,Q,T,L}
source
CliffordNumbers.EvenCliffordNumberType
EvenCliffordNumber{P,Q,T,L} (alias for CliffordNumbers.Z2CliffordNumber{false,Q,T,L})

A Clifford number whose only nonzero grades are even. These are the natural choice of representation for rotors and motors (Euclidean isometries preserving orientation, or "proper" isometries), as well as their composition with dilations.

source
CliffordNumbers.OddCliffordNumberType
OddCliffordNumber{P,Q,T,L} (alias for CliffordNumbers.Z2CliffordNumber{true,Q,T,L})

A Clifford number whose only nonzero grades are odd. These are the natural choice of representation for reflections, as well as their compositions with rotors and motors (Euclidean isometries preserving orientation, or "proper" isometries), as well as their composition with dilations.

source
CliffordNumbers.KVectorType
KVector{K,Q,T,L} <: AbstractCliffordNumber{Q,T}

A multivector consisting only linear combinations of basis blades of grade K - in other words, a k-vector.

k-vectors have binomial(dimension(Q), K) components.

source
CliffordNumbers.gradeMethod
grade(::Type{<:KVector{K}}) = K
+grade(x::KVector{K}) = k

Returns the grade represented by a KVector{K}, which is K.

source

Promotion and conversion

CliffordNumbers.scalar_convertFunction
scalar_convert(T::Type{<:Union{Real,Complex}}, x::AbstractCliffordNumber) -> T
 scalar_convert(T::Type{<:Union{Real,Complex}}, x::Union{Real,Complex}) -> T

If x is an AbstractCliffordNumber, converts the scalars of x to type T.

If x is a Real or Complex, converts x to T.

Examples

julia> scalar_convert(Float32, KVector{1,APS}(1, 2, 3))
 3-element KVector{1, VGA(3), Float32}:
 1.0σ₁ + 2.0σ₂ + 3.0σ
 
 julia> scalar_convert(Float32, 2)
-2.0f0
source
CliffordNumbers.scalar_promoteFunction
scalar_promote(x::AbstractCliffordNumber, y::AbstractCliffordNumber)

Promotes the scalar types of x and y to a common type. This does not increase the number of represented grades of either x or y.

source
Base.widenMethod
widen(C::Type{<:AbstractCliffordNumber})
-widen(x::AbstractCliffordNumber)

Construct a new type whose scalar type is widened. This behavior matches that of widen(C::Type{Complex{T}}), which results in widening of its scalar type T.

For obtaining a representation of a Clifford number with an increased number of nonzero grades, use widen_grade(T).

source
CliffordNumbers.widen_gradeFunction
widen_grade(C::Type{<:AbstractCliffordNumber})
-widen_grade(x::AbstractCliffordNumber)

For type arguments, construct the next largest type that can hold all of the grades of C. KVector{K,Q,T} widens to EvenCliffordNumber{Q,T} or OddCliffordNumber{Q,T}, and EvenCliffordNumber{Q,T} and OddCliffordNumber{Q,T} widen to CliffordNumber{Q,T}, which is the widest type.

For AbstractCliffordNumber arguments, the argument is converted to the result of widen_grade(typeof(x)).

For widening the scalar type of an AbstractCliffordNumber, use Base.widen(T).

source

Real and complex algebras

Base.realMethod
real(x::AbstractCliffordNumber{Q,T})

Gets the real portion of each coefficient of x. For T<:Real this operation does nothing; for T<:Complex{S} this an AbstractCliffordNumber{Q,S}.

Note that this does not return the scalar (grade 0) coefficient of x. Use scalar(x) to obtain this result in general, or real(scalar(x)) if only the real portion is desired.

source
Base.complexMethod
complex(x::AbstractCliffordNumber, [y::AbstractCliffordNumber = zero(typeof(x))])

For a single argument x, converts the type of each coefficient to a suitable complex type.

For two arguments x and y, which are both real Clifford numbers, performs the sum x + y*im, constructing a complex Clifford number.

Note that this operation does not isolate a scalar (grade 0) coefficient of x or y. Use complex(scalar(x), [scalar(y)]) to obtain this result.

source

Scalar and pseudoscalar components

CliffordNumbers.isscalarFunction
isscalar(x::AbstractCliffordNumber)

Determines whether the Clifford number x is a scalar, meaning that all of its blades of nonzero grade are zero.

source
CliffordNumbers.ispseudoscalarFunction
ispseudoscalar(m::AbstractCliffordNumber)

Determines whether the Clifford number x is a pseudoscalar, meaning that all of its blades with grades below the dimension of the space are zero.

source
CliffordNumbers.scalarFunction
scalar(x::AbstractCliffordNumber{Q,T}) -> T

Returns the scalar portion of x as its scalar type. This is equivalent to x[scalar_index(x)].

To retain Clifford number semantics, use the KVector{0} constructor.

source
CliffordNumbers.pseudoscalarFunction
pseudoscalar(C::Type{<:AbstractCliffordNumber{Q,T}}) -> KVector{dimension(Q),Q,T}
-pseudoscalar(x::AbstractCliffordNumber{Q})

Returns the pseudoscalar associated with the signature Q of the argument. The result will have the same scalar type as the input if such information is given; otherwise it will use Bool as the scalar type so as to promote to any other numeric type.

source
+2.0f0
source
CliffordNumbers.scalar_promoteFunction
scalar_promote(x::AbstractCliffordNumber, y::AbstractCliffordNumber)

Promotes the scalar types of x and y to a common type. This does not increase the number of represented grades of either x or y.

source
Base.widenMethod
widen(C::Type{<:AbstractCliffordNumber})
+widen(x::AbstractCliffordNumber)

Construct a new type whose scalar type is widened. This behavior matches that of widen(C::Type{Complex{T}}), which results in widening of its scalar type T.

For obtaining a representation of a Clifford number with an increased number of nonzero grades, use widen_grade(T).

source
CliffordNumbers.widen_gradeFunction
widen_grade(C::Type{<:AbstractCliffordNumber})
+widen_grade(x::AbstractCliffordNumber)

For type arguments, construct the next largest type that can hold all of the grades of C. KVector{K,Q,T} widens to EvenCliffordNumber{Q,T} or OddCliffordNumber{Q,T}, and EvenCliffordNumber{Q,T} and OddCliffordNumber{Q,T} widen to CliffordNumber{Q,T}, which is the widest type.

For AbstractCliffordNumber arguments, the argument is converted to the result of widen_grade(typeof(x)).

For widening the scalar type of an AbstractCliffordNumber, use Base.widen(T).

source

Real and complex algebras

Base.realMethod
real(x::AbstractCliffordNumber{Q,T})

Gets the real portion of each coefficient of x. For T<:Real this operation does nothing; for T<:Complex{S} this an AbstractCliffordNumber{Q,S}.

Note that this does not return the scalar (grade 0) coefficient of x. Use scalar(x) to obtain this result in general, or real(scalar(x)) if only the real portion is desired.

source
Base.complexMethod
complex(x::AbstractCliffordNumber, [y::AbstractCliffordNumber = zero(typeof(x))])

For a single argument x, converts the type of each coefficient to a suitable complex type.

For two arguments x and y, which are both real Clifford numbers, performs the sum x + y*im, constructing a complex Clifford number.

Note that this operation does not isolate a scalar (grade 0) coefficient of x or y. Use complex(scalar(x), [scalar(y)]) to obtain this result.

source

Scalar and pseudoscalar components

CliffordNumbers.isscalarFunction
isscalar(x::AbstractCliffordNumber)

Determines whether the Clifford number x is a scalar, meaning that all of its blades of nonzero grade are zero.

source
CliffordNumbers.ispseudoscalarFunction
ispseudoscalar(m::AbstractCliffordNumber)

Determines whether the Clifford number x is a pseudoscalar, meaning that all of its blades with grades below the dimension of the space are zero.

source
CliffordNumbers.scalarFunction
scalar(x::AbstractCliffordNumber{Q,T}) -> T

Returns the scalar portion of x as its scalar type. This is equivalent to x[scalar_index(x)].

To retain Clifford number semantics, use the KVector{0} constructor.

source
CliffordNumbers.pseudoscalarFunction
pseudoscalar(C::Type{<:AbstractCliffordNumber{Q,T}}) -> KVector{dimension(Q),Q,T}
+pseudoscalar(x::AbstractCliffordNumber{Q})

Returns the pseudoscalar associated with the signature Q of the argument. The result will have the same scalar type as the input if such information is given; otherwise it will use Bool as the scalar type so as to promote to any other numeric type.

source
diff --git a/dev/api/indexing.html b/dev/api/indexing.html index 63668c9..9cf3b8f 100644 --- a/dev/api/indexing.html +++ b/dev/api/indexing.html @@ -4,9 +4,9 @@ 0:3 julia> CliffordNumbers.nonzero_grades(KVector{2,APS}) -2:2source
CliffordNumbers.has_grades_ofFunction
has_grades_of(S::Type{<:AbstractCliffordNumber}, T::Type{<:AbstractCliffordNumber}) -> Bool
-has_grades_of(x::AbstractCliffordNumber, y::AbstractCliffordNumber) -> Bool

Returns true if the grades represented in S are also represented in T; false otherwise.

source

BitIndex

CliffordNumbers.BitIndexType
BitIndex{Q}

A representation of an index corresponding to a basis blade of the geometric algebra with quadratic form Q.

source
CliffordNumbers.is_same_bladeFunction
CliffordNumbers.is_same_blade(a::BitIndex{Q}, b::BitIndex{Q})

Checks if a and b perform identical indexing up to sign.

source

Special indices

CliffordNumbers.scalar_indexFunction
scalar_index(x::AbstractCliffordNumber{Q}) -> BitIndex{Q}

Constructs the BitIndex used to obtain the scalar (grade zero) portion of x.

source
CliffordNumbers.pseudoscalar_indexFunction
pseudoscalar_index(x::AbstractCliffordNumber{Q}) -> BitIndex{Q}

Constructs the BitIndex used to obtain the pseudoscalar (highest grade) portion of x.

source

Tools for implementing mathematical operations

Base.reverseMethod
adjoint(i::BitIndex) = reverse(i::BitIndex) = i' -> BitIndex
-adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source
CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
-grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source
Base.conjMethod
conj(i::BitIndex) -> BitIndex
-conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source
CliffordNumbers.left_complementFunction
left_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the left complement of b, define so that left_complement(b) * b generates the pseudoscalar index of elements of the algebra Q.

When the left complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the left complement and [right complement](@ref right_complement) are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the left complement is an underbar.

source
CliffordNumbers.right_complementFunction
right_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the right complement of b, define so that b * right_complement(b) generates the pseudoscalar index of elements of the algebra Q.

When the right complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the [left complement](@ref left_complement) and right complement are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the right complement is an overbar.

source
CliffordNumbers.gradeMethod
grade(i::BitIndex) -> Int

Returns the grade of the basis blade represented by i, which ranges from 0 to the dimension of the space represented by i (equal to dimension(signature(i))).

source
CliffordNumbers.sign_of_squareFunction
CliffordNumbers.sign_of_square(b::BitIndex) -> Int8

Returns the sign associated with squaring the basis blade indexed by b using an Int8 as proxy: positive signs return Int8(1), negative signs return Int8(-1), and zeros from degenerate components return Int8(0).

source
CliffordNumbers.signbit_of_squareFunction
CliffordNumbers.signbit_of_square(b::BitIndex) -> Bool

Returns the signbit associated with squaring the basis blade indexed by b.

source
CliffordNumbers.nondegenerate_squareFunction
CliffordNumbers.nondegenerate_square(b::BitIndex) -> Bool

Returns false if squaring the basis blade b is zero due to a degenerate component, true otherwise. For a nondegenerate metric, this is always true.

source
CliffordNumbers.sign_of_multFunction
CliffordNumbers.sign_of_mult(a::T, b::T) where T<:BitIndex -> Int8

Returns an Int8 that carries the sign associated with the multiplication of two basis blades of Clifford/geometric algebras of the same quadratic form.

source
CliffordNumbers.signbit_of_multFunction
CliffordNumbers.signbit_of_mult(a::Integer, [b::Integer]) -> Bool
-CliffordNumbers.signbit_of_mult(a::BitIndex, [b::BitIndex]) -> Bool

Calculates the sign bit associated with multiplying basis elements indexed with bit indices supplied as either integers or BitIndex instances. The sign bit flips when the order of a and b are reversed, unless a === b.

As with Base.signbit(), true represents a negative sign and false a positive sign. However, in degenerate metrics (such as those of projective geometric algebras) the sign bit may be irrelevant as the multiplication of those basis blades would result in zero.

source
CliffordNumbers.nondegenerate_multFunction
CliffordNumbers.nondegenerate_mult(a::T, b::T) where T<:BitIndex -> Bool

Returns false if the product of a and b is zero due to the squaring of a degenerate component, true otherwise. This function always returns true if R === 0.

source
Base.:*Method
*(a::BitIndex{Q}, b::BitIndex{Q}) -> BitIndex{Q}

Returns the BitIndex corresponding to the basis blade resulting from the geometric product of the basis blades indexed by a and b.

source
CliffordNumbers.has_wedgeFunction
CliffordNumbers.has_wedge(a::BitIndex{Q}, b::BitIndex{Q}, [c::BitIndex{Q}...]) -> Bool

Returns true if the basis blades indexed by a, b, or any other blades c... have a nonzero wedge product; false otherwise. This is determined by comparing all bits of the arguments (except the sign bit) to identify any matching basis blades using bitwise AND.

source
CliffordNumbers.AbstractBitIndicesType
AbstractBitIndices{Q,C<:AbstractCliffordNumber{Q}} <: AbstractVector{BitIndex{Q}}

Supertype for vectors containing all valid BitIndex{Q} objects for the basis elements represented by C.

source
CliffordNumbers.BitIndicesType
BitIndices{Q,C<:AbstractCliffordNumber{Q,<:Any}} <: AbstractVector{BitIndex{Q}}

Represents a range of valid BitIndex objects for the nonzero components of a given multivector of algebra Q.

For a generic AbstractCliffordNumber{Q}, this returns BitIndices{Q,CliffordNumber{Q}}, which contains all possible indices for a multivector associated with the algebra parameter Q. For sparser representations, such as KVector{K,Q}, the object only contains the indices of the nonzero elements of the multivector.

Construction

BitIndices can be constructed by calling the type constructor with the Clifford number or its type. This will automatically strip some type parameters so that identical BitIndices objects are constructed regardless of the scalar type.

For this reason, you should not use BitIndices{Q,C}(); instead use BitIndices(C).

Indexing

BitIndices always uses one-based indexing like most Julia arrays. Although it is more natural in the dense case to use zero-based indexing, as the basis blades are naturally encoded in the indices for the dense representation of CliffordNumber, one-based indexing is used by the tuples which contain the data associated with this package's implementations of Clifford numbers.

Broadcasting

Because BitIndices(x) only lazily references the indices of x, we define a new type, TransformedBitIndices, which allows for a function f to be lazily associated with the BitIndices object, and this type is constructed when a f.(BitIndices(x)) is called.

Interfaces for new subtypes of AbstractCliffordNumber

When defining the behavior of BitIndices for new subtypes T of AbstractCliffordNumber, Base.getindex(::BitIndices{Q,T}, i::Integer) should be defined so that all indices of T that are not constrained to be zero are returned.

You should also define CliffordNumbers.bitindices_type(::Type{T}) so that type parameters that do not affect the construction of the BitIndices object are stripped.

source
CliffordNumbers.TransformedBitIndicesType
TransformedBitIndices{Q,C,F} <: AbstractBitIndices{Q,C}

Lazy representation of BitIndices{Q,C} with some function of type f applied to each element. These objects can be used to perform common operations which act on basis blades or grades, such as the reverse or grade involution.

source
+2:2source
CliffordNumbers.has_grades_ofFunction
has_grades_of(S::Type{<:AbstractCliffordNumber}, T::Type{<:AbstractCliffordNumber}) -> Bool
+has_grades_of(x::AbstractCliffordNumber, y::AbstractCliffordNumber) -> Bool

Returns true if the grades represented in S are also represented in T; false otherwise.

source

BitIndex

CliffordNumbers.BitIndexType
BitIndex{Q}

A representation of an index corresponding to a basis blade of the geometric algebra with quadratic form Q.

source
CliffordNumbers.is_same_bladeFunction
CliffordNumbers.is_same_blade(a::BitIndex{Q}, b::BitIndex{Q})

Checks if a and b perform identical indexing up to sign.

source

Special indices

CliffordNumbers.scalar_indexFunction
scalar_index(x::AbstractCliffordNumber{Q}) -> BitIndex{Q}

Constructs the BitIndex used to obtain the scalar (grade zero) portion of x.

source
CliffordNumbers.pseudoscalar_indexFunction
pseudoscalar_index(x::AbstractCliffordNumber{Q}) -> BitIndex{Q}

Constructs the BitIndex used to obtain the pseudoscalar (highest grade) portion of x.

source

Tools for implementing mathematical operations

Base.reverseMethod
adjoint(i::BitIndex) = reverse(i::BitIndex) = i' -> BitIndex
+adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source
CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
+grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source
Base.conjMethod
conj(i::BitIndex) -> BitIndex
+conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source
CliffordNumbers.left_complementFunction
left_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the left complement of b, define so that left_complement(b) * b generates the pseudoscalar index of elements of the algebra Q.

When the left complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the left complement and [right complement](@ref right_complement) are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the left complement is an underbar.

source
CliffordNumbers.right_complementFunction
right_complement(b::BitIndex{Q}) -> BitIndex{Q}

Returns the right complement of b, define so that b * right_complement(b) generates the pseudoscalar index of elements of the algebra Q.

When the right complement is applied twice, the original BitIndex object is returned up to a change of sign, given by (-1)^(grade(b) * (dimension(Q) - grade(b))). This implies that in algebras of odd dimension, the [left complement](@ref left_complement) and right complement are identical because eithergrade(b)ordimension(Q) - grade(b)must be even. The complement is independent of the signature ofQ`, depending only on the dimension.

Lengyel's convention for the right complement is an overbar.

source
CliffordNumbers.gradeMethod
grade(i::BitIndex) -> Int

Returns the grade of the basis blade represented by i, which ranges from 0 to the dimension of the space represented by i (equal to dimension(signature(i))).

source
CliffordNumbers.sign_of_squareFunction
CliffordNumbers.sign_of_square(b::BitIndex) -> Int8

Returns the sign associated with squaring the basis blade indexed by b using an Int8 as proxy: positive signs return Int8(1), negative signs return Int8(-1), and zeros from degenerate components return Int8(0).

source
CliffordNumbers.signbit_of_squareFunction
CliffordNumbers.signbit_of_square(b::BitIndex) -> Bool

Returns the signbit associated with squaring the basis blade indexed by b.

source
CliffordNumbers.nondegenerate_squareFunction
CliffordNumbers.nondegenerate_square(b::BitIndex) -> Bool

Returns false if squaring the basis blade b is zero due to a degenerate component, true otherwise. For a nondegenerate metric, this is always true.

source
CliffordNumbers.sign_of_multFunction
CliffordNumbers.sign_of_mult(a::T, b::T) where T<:BitIndex -> Int8

Returns an Int8 that carries the sign associated with the multiplication of two basis blades of Clifford/geometric algebras of the same quadratic form.

source
CliffordNumbers.signbit_of_multFunction
CliffordNumbers.signbit_of_mult(a::Integer, [b::Integer]) -> Bool
+CliffordNumbers.signbit_of_mult(a::BitIndex, [b::BitIndex]) -> Bool

Calculates the sign bit associated with multiplying basis elements indexed with bit indices supplied as either integers or BitIndex instances. The sign bit flips when the order of a and b are reversed, unless a === b.

As with Base.signbit(), true represents a negative sign and false a positive sign. However, in degenerate metrics (such as those of projective geometric algebras) the sign bit may be irrelevant as the multiplication of those basis blades would result in zero.

source
CliffordNumbers.nondegenerate_multFunction
CliffordNumbers.nondegenerate_mult(a::T, b::T) where T<:BitIndex -> Bool

Returns false if the product of a and b is zero due to the squaring of a degenerate component, true otherwise. This function always returns true if R === 0.

source
Base.:*Method
*(a::BitIndex{Q}, b::BitIndex{Q}) -> BitIndex{Q}

Returns the BitIndex corresponding to the basis blade resulting from the geometric product of the basis blades indexed by a and b.

source
CliffordNumbers.has_wedgeFunction
CliffordNumbers.has_wedge(a::BitIndex{Q}, b::BitIndex{Q}, [c::BitIndex{Q}...]) -> Bool

Returns true if the basis blades indexed by a, b, or any other blades c... have a nonzero wedge product; false otherwise. This is determined by comparing all bits of the arguments (except the sign bit) to identify any matching basis blades using bitwise AND.

source
CliffordNumbers.AbstractBitIndicesType
AbstractBitIndices{Q,C<:AbstractCliffordNumber{Q}} <: AbstractVector{BitIndex{Q}}

Supertype for vectors containing all valid BitIndex{Q} objects for the basis elements represented by C.

source
CliffordNumbers.BitIndicesType
BitIndices{Q,C<:AbstractCliffordNumber{Q,<:Any}} <: AbstractVector{BitIndex{Q}}

Represents a range of valid BitIndex objects for the nonzero components of a given multivector of algebra Q.

For a generic AbstractCliffordNumber{Q}, this returns BitIndices{Q,CliffordNumber{Q}}, which contains all possible indices for a multivector associated with the algebra parameter Q. For sparser representations, such as KVector{K,Q}, the object only contains the indices of the nonzero elements of the multivector.

Construction

BitIndices can be constructed by calling the type constructor with the Clifford number or its type. This will automatically strip some type parameters so that identical BitIndices objects are constructed regardless of the scalar type.

For this reason, you should not use BitIndices{Q,C}(); instead use BitIndices(C).

Indexing

BitIndices always uses one-based indexing like most Julia arrays. Although it is more natural in the dense case to use zero-based indexing, as the basis blades are naturally encoded in the indices for the dense representation of CliffordNumber, one-based indexing is used by the tuples which contain the data associated with this package's implementations of Clifford numbers.

Broadcasting

Because BitIndices(x) only lazily references the indices of x, we define a new type, TransformedBitIndices, which allows for a function f to be lazily associated with the BitIndices object, and this type is constructed when a f.(BitIndices(x)) is called.

Interfaces for new subtypes of AbstractCliffordNumber

When defining the behavior of BitIndices for new subtypes T of AbstractCliffordNumber, Base.getindex(::BitIndices{Q,T}, i::Integer) should be defined so that all indices of T that are not constrained to be zero are returned.

You should also define CliffordNumbers.bitindices_type(::Type{T}) so that type parameters that do not affect the construction of the BitIndices object are stripped.

source
CliffordNumbers.TransformedBitIndicesType
TransformedBitIndices{Q,C,F} <: AbstractBitIndices{Q,C}

Lazy representation of BitIndices{Q,C} with some function of type f applied to each element. These objects can be used to perform common operations which act on basis blades or grades, such as the reverse or grade involution.

source
diff --git a/dev/api/internal.html b/dev/api/internal.html index abc7b29..c107ebd 100644 --- a/dev/api/internal.html +++ b/dev/api/internal.html @@ -1,25 +1,25 @@ -Internals · CliffordNumbers.jl

Internal methods

CliffordNumbers.HammingModule
CliffordNumbers.Hamming

A submodule containing methods for working with the sum of binary digits contained in an integer. This is essential to representing the basis blades of a geometric algebra, as the presence or absence of each possible basis vector in a blade can be represented by a binary 1 or 0. Operations that require knowledge of the grade of a basis blade will need the operations in this submodule.

source
CliffordNumbers.Hamming.isevilFunction
CliffordNumbers.Hamming.isevil(i::Integer) -> Bool

Determines whether a number is evil, meaning that its Hamming weight (sum of its binary digits) is even.

source
CliffordNumbers.Hamming.isodiousFunction
CliffordNumbers.Hamming.isodious(i::Integer) -> Bool

Determines whether a number is odious, meaning that its Hamming weight (sum of its binary digits) is odd.

source
CliffordNumbers.Hamming.evil_numberFunction
CliffordNumbers.Hamming.evil_number(n::Integer)

Returns the nth evil number, with the first evil number (n == 1) defined to be 0.

Evil numbers are numbers which have an even Hamming weight (sum of its binary digits).

source
CliffordNumbers.Hamming.odious_numberFunction
CliffordNumbers.Hamming.odious_number(n::Integer)

Returns the nth odious number, with the first odious number (n == 1) defined to be 1.

Odious numbers are numbers which have an odd Hamming weight (sum of its binary digits).

source
CliffordNumbers.Hamming.hamming_numberFunction
CliffordNumbers.Hamming.hamming_number(w::Integer, n::Integer)

Gets the nth number with Hamming weight w. The first number with this Hamming weight (n = 1) is 2^w - 1.

Example

julia> CliffordNumbers.hamming_number(3, 2)
-11
source

Indexing

CliffordNumbers.signmaskFunction
CliffordNumbers.signmask([T::Type{<:Integer} = UInt], [signbit::Bool = true]) -> T

Generates a signmask, or a string of bits where the only 1 bit is the sign bit. If signbit is set to false, this returns zero (or whatever value is represented by all bits being 0).

source
CliffordNumbers._sort_with_parity!Function
CliffordNumbers._sort_with_parity!(v::AbstractVector{<:Real}) -> Tuple{typeof(v),Bool}

Performs a parity-tracking insertion sort of v, which modifies v in place. The function returns a tuple containing v and the parity, which is true for an odd permutation and false for an even permutation. This is implemented with a modified insertion sort algorithm.

source
CliffordNumbers.bitindices_typeFunction
CliffordNumbers.bitindices_type(C::Type{<:AbstractCliffordNumber{Q,T}})

Removes extraneous type parameters from C, converting it to the least parameterized type that can be used to parameterize an AbstractBitIndices{Q,C} object. This is to avoid issues with the proliferation of type parameters that would construct identical BitIndices objects otherwise: for instance, BitIndices{VGA(3),EvenCliffordNumber{VGA(3),Float32,4}}() and BitIndices{VGA(3),EvenCliffordNumber{VGA(3),Int}}() have identical elements, and are equal when compared with ==, but are not the same object.

For types defined in this package, this strips the scalar type parameter T and any length parameters present.

Examples

julia> CliffordNumbers.bitindices_type(CliffordNumber{VGA(3),Float32,8})
+Internals · CliffordNumbers.jl

Internal methods

CliffordNumbers.HammingModule
CliffordNumbers.Hamming

A submodule containing methods for working with the sum of binary digits contained in an integer. This is essential to representing the basis blades of a geometric algebra, as the presence or absence of each possible basis vector in a blade can be represented by a binary 1 or 0. Operations that require knowledge of the grade of a basis blade will need the operations in this submodule.

source
CliffordNumbers.Hamming.isevilFunction
CliffordNumbers.Hamming.isevil(i::Integer) -> Bool

Determines whether a number is evil, meaning that its Hamming weight (sum of its binary digits) is even.

source
CliffordNumbers.Hamming.isodiousFunction
CliffordNumbers.Hamming.isodious(i::Integer) -> Bool

Determines whether a number is odious, meaning that its Hamming weight (sum of its binary digits) is odd.

source
CliffordNumbers.Hamming.evil_numberFunction
CliffordNumbers.Hamming.evil_number(n::Integer)

Returns the nth evil number, with the first evil number (n == 1) defined to be 0.

Evil numbers are numbers which have an even Hamming weight (sum of its binary digits).

source
CliffordNumbers.Hamming.odious_numberFunction
CliffordNumbers.Hamming.odious_number(n::Integer)

Returns the nth odious number, with the first odious number (n == 1) defined to be 1.

Odious numbers are numbers which have an odd Hamming weight (sum of its binary digits).

source
CliffordNumbers.Hamming.hamming_numberFunction
CliffordNumbers.Hamming.hamming_number(w::Integer, n::Integer)

Gets the nth number with Hamming weight w. The first number with this Hamming weight (n = 1) is 2^w - 1.

Example

julia> CliffordNumbers.hamming_number(3, 2)
+11
source

Indexing

CliffordNumbers.signmaskFunction
CliffordNumbers.signmask([T::Type{<:Integer} = UInt], [signbit::Bool = true]) -> T

Generates a signmask, or a string of bits where the only 1 bit is the sign bit. If signbit is set to false, this returns zero (or whatever value is represented by all bits being 0).

source
CliffordNumbers._sort_with_parity!Function
CliffordNumbers._sort_with_parity!(v::AbstractVector{<:Real}) -> Tuple{typeof(v),Bool}

Performs a parity-tracking insertion sort of v, which modifies v in place. The function returns a tuple containing v and the parity, which is true for an odd permutation and false for an even permutation. This is implemented with a modified insertion sort algorithm.

source
CliffordNumbers.bitindices_typeFunction
CliffordNumbers.bitindices_type(C::Type{<:AbstractCliffordNumber{Q,T}})

Removes extraneous type parameters from C, converting it to the least parameterized type that can be used to parameterize an AbstractBitIndices{Q,C} object. This is to avoid issues with the proliferation of type parameters that would construct identical BitIndices objects otherwise: for instance, BitIndices{VGA(3),EvenCliffordNumber{VGA(3),Float32,4}}() and BitIndices{VGA(3),EvenCliffordNumber{VGA(3),Int}}() have identical elements, and are equal when compared with ==, but are not the same object.

For types defined in this package, this strips the scalar type parameter T and any length parameters present.

Examples

julia> CliffordNumbers.bitindices_type(CliffordNumber{VGA(3),Float32,8})
 CliffordNumber{VGA(3)}
 
 julia> CliffordNumbers.bitindices_type(KVector{2,STA,Bool})
-KVector{2,STA}
source

Construction

CliffordNumbers.zero_tupleFunction
CliffordNumbers.zero_tuple(::Type{T}, ::Val{L}) -> NTuple{L,T}

Generates a Tuple of length L with all elements being zero(T).

source
CliffordNumbers.zero_tuple(::Type{C<:AbstractCliffordNumber})
-    -> NTuple{nblades(C),scalar_type(C)}

Generates a Tuple that can be used to construct zero(C).

source
CliffordNumbers.check_element_countFunction
CliffordNumbers.check_element_count(sz, [L], data)

Ensures that the number of elements in data is the same as the result of f(Q), where f is a function that generates the expected number of elements for the type. This function is used in the inner constructors of subtypes of AbstractCliffordNumber{Q} to ensure that the input has the correct length.

If provided, the length type parameter L can be included as an argument, and it will be checked for type (must be an Int) and value (must be equal to sz).

This function returns nothing, but throws an AssertionError for failed checks.

source

Multiplication kernels

Construction

CliffordNumbers.zero_tupleFunction
CliffordNumbers.zero_tuple(::Type{T}, ::Val{L}) -> NTuple{L,T}

Generates a Tuple of length L with all elements being zero(T).

source
CliffordNumbers.zero_tuple(::Type{C<:AbstractCliffordNumber})
+    -> NTuple{nblades(C),scalar_type(C)}

Generates a Tuple that can be used to construct zero(C).

source
CliffordNumbers.check_element_countFunction
CliffordNumbers.check_element_count(sz, [L], data)

Ensures that the number of elements in data is the same as the result of f(Q), where f is a function that generates the expected number of elements for the type. This function is used in the inner constructors of subtypes of AbstractCliffordNumber{Q} to ensure that the input has the correct length.

If provided, the length type parameter L can be included as an argument, and it will be checked for type (must be an Int) and value (must be equal to sz).

This function returns nothing, but throws an AssertionError for failed checks.

source

Multiplication kernels

CliffordNumbers.mulFunction
CliffordNumbers.mul(
     x::AbstractCliffordNumber{Q},
     y::AbstractCliffordNumber{Q},
     [F::GradeFilter = GradeFilter{:*}()]
-)

A fast geometric product implementation using generated functions for specific cases, and generic methods which either convert the arguments or fall back to other methods.

The arguments to this function should all agree in scalar type T. The * function, which exposes the fast geometric product implementation, promotes the scalar types of the arguments before utilizing this kernel. The scalar multiplication operations are implemented using muladd, allowing for hardware fma operations to be used when available.

The GradeFilter F allows for some blade multiplications to be excluded if they meet certain criteria. This is useful for implementing products besides the geometric product, such as the wedge product, which excludes multiplications between blades with shared vectors. Without a filter, this kernel just returns the geometric product.

source
CliffordNumbers.GradeFilterType
CliffordNumbers.GradeFilter{S}

A type that can be used to filter certain products of blades in a geometric product multiplication. The type parameter S must be a Symbol. The single instance of GradeFilter{S} is a callable object which implements a function that takes two or more BitIndex{Q} objects a and b and returns false if the product of the blades indexed is zero.

To implement a grade filter for a product function f, define the following method: (::GradeFilter{:f})(::BitIndex{Q}, ::BitIndex{Q}) # Or if the definition allows for more arguments (::GradeFilter{:f})(::BitIndex{Q}...) where Q

source
CliffordNumbers.nondegenerate_maskFunction
CliffordNumbers.nondegenerate_mask(a::BitIndex{Q}, B::NTuple{L,BitIndex{Q}})

Constructs a Boolean mask which is false for any multiplication that squares a degenerate blade; true otherwise.

source
CliffordNumbers.mul_maskFunction
CliffordNumbers.mul_mask(F::GradeFilter, a::BitIndex{Q}, B::NTuple{L,BitIndices{Q}})
+)

A fast geometric product implementation using generated functions for specific cases, and generic methods which either convert the arguments or fall back to other methods.

The arguments to this function should all agree in scalar type T. The * function, which exposes the fast geometric product implementation, promotes the scalar types of the arguments before utilizing this kernel. The scalar multiplication operations are implemented using muladd, allowing for hardware fma operations to be used when available.

The GradeFilter F allows for some blade multiplications to be excluded if they meet certain criteria. This is useful for implementing products besides the geometric product, such as the wedge product, which excludes multiplications between blades with shared vectors. Without a filter, this kernel just returns the geometric product.

source
CliffordNumbers.GradeFilterType
CliffordNumbers.GradeFilter{S}

A type that can be used to filter certain products of blades in a geometric product multiplication. The type parameter S must be a Symbol. The single instance of GradeFilter{S} is a callable object which implements a function that takes two or more BitIndex{Q} objects a and b and returns false if the product of the blades indexed is zero.

To implement a grade filter for a product function f, define the following method: (::GradeFilter{:f})(::BitIndex{Q}, ::BitIndex{Q}) # Or if the definition allows for more arguments (::GradeFilter{:f})(::BitIndex{Q}...) where Q

source
CliffordNumbers.nondegenerate_maskFunction
CliffordNumbers.nondegenerate_mask(a::BitIndex{Q}, B::NTuple{L,BitIndex{Q}})

Constructs a Boolean mask which is false for any multiplication that squares a degenerate blade; true otherwise.

source
CliffordNumbers.mul_maskFunction
CliffordNumbers.mul_mask(F::GradeFilter, a::BitIndex{Q}, B::NTuple{L,BitIndices{Q}})
 CliffordNumbers.mul_mask(F::GradeFilter, B::NTuple{L,BitIndices{Q}}, a::BitIndex{Q})
 
 CliffordNumbers.mul_mask(F::GradeFilter, a::BitIndex{Q}, B::BitIndices{Q})
-CliffordNumbers.mul_mask(F::GradeFilter, B::BitIndices{Q}, a::BitIndex{Q})

Generates a NTuple{L,Bool} which is true whenever the multiplication of the blade indexed by a and blades indexed by B is nonzero. false is returned if the grades multiply to zero due to the squaring of a degenerate component, or if they are filtered by F.

source
CliffordNumbers.mul_signsFunction
CliffordNumbers.mul_signs(F::GradeFilter, a::BitIndex{Q}, B::NTuple{L,BitIndices{Q}})
+CliffordNumbers.mul_mask(F::GradeFilter, B::BitIndices{Q}, a::BitIndex{Q})

Generates a NTuple{L,Bool} which is true whenever the multiplication of the blade indexed by a and blades indexed by B is nonzero. false is returned if the grades multiply to zero due to the squaring of a degenerate component, or if they are filtered by F.

source
CliffordNumbers.mul_signsFunction
CliffordNumbers.mul_signs(F::GradeFilter, a::BitIndex{Q}, B::NTuple{L,BitIndices{Q}})
 CliffordNumbers.mul_signs(F::GradeFilter, B::NTuple{L,BitIndices{Q}}, a::BitIndex{Q})
 
 CliffordNumbers.mul_signs(F::GradeFilter, a::BitIndex{Q}, B::BitIndices{Q})
-CliffordNumbers.mul_signs(F::GradeFilter, B::BitIndices{Q}, a::BitIndex{Q})

Generates an NTuple{L,Int8} which represents the sign associated with the multiplication needed to calculate components of a multiplication result.

This is equivalent to sign.(B) unless F === CliffordNumbers.GradeFilter{:dot}().

source
CliffordNumbers.bitindex_shuffleFunction
CliffordNumbers.bitindex_shuffle(a::BitIndex{Q}, B::NTuple{L,BitIndex{Q}})
+CliffordNumbers.mul_signs(F::GradeFilter, B::BitIndices{Q}, a::BitIndex{Q})

Generates an NTuple{L,Int8} which represents the sign associated with the multiplication needed to calculate components of a multiplication result.

This is equivalent to sign.(B) unless F === CliffordNumbers.GradeFilter{:dot}().

source
CliffordNumbers.bitindex_shuffleFunction
CliffordNumbers.bitindex_shuffle(a::BitIndex{Q}, B::NTuple{L,BitIndex{Q}})
 CliffordNumbers.bitindex_shuffle(a::BitIndex{Q}, B::BitIndices{Q})
 
 CliffordNumbers.bitindex_shuffle(B::NTuple{L,BitIndex{Q}}, a::BitIndex{Q})
-CliffordNumbers.bitindex_shuffle(B::BitIndices{Q}, a::BitIndex{Q})

Performs the multiplication -a * b for each element of B for the above ordering, or -b * a for the below ordering, generating a reordered NTuple of BitIndex{Q} objects suitable for implementing a geometric product.

source

Taylor series exponential

CliffordNumbers.exp_taylorFunction
CliffordNumbers.exp_taylor(x::AbstractCliffordNumber, order = Val(16))

Calculates the exponential of x using a Taylor expansion up to the specified order. In most cases, 12 is as sufficient number.

Notes

16 iterations is currently used because the number of loop iterations is not currently a performance bottleneck.

source

Return types for operations

CliffordNumbers.product_return_typeFunction
CliffordNumbers.product_return_type(::Type{X}, ::Type{Y}, [::GradeFilter{S}])

Returns a suitable type for representing the product of Clifford numbers of types X and Y. The GradeFilter{S} argument allows for the return type to be changed depending on the type of product. Without specialization on S, a type suitable for the geometric product is returned.

source
CliffordNumbers.exponential_typeFunction
CliffordNumbers.exponential_type(::Type{<:AbstractCliffordNumber})
-CliffordNumbers.exponential_type(x::AbstractCliffordNumber)

Returns the type expected when exponentiating a Clifford number. This is an EvenCliffordNumber if the nonzero grades of the input are even, a CliffordNumber otherwise.

source
+CliffordNumbers.bitindex_shuffle(B::BitIndices{Q}, a::BitIndex{Q})

Performs the multiplication -a * b for each element of B for the above ordering, or -b * a for the below ordering, generating a reordered NTuple of BitIndex{Q} objects suitable for implementing a geometric product.

source

Taylor series exponential

CliffordNumbers.exp_taylorFunction
CliffordNumbers.exp_taylor(x::AbstractCliffordNumber, order = Val(16))

Calculates the exponential of x using a Taylor expansion up to the specified order. In most cases, 12 is as sufficient number.

Notes

16 iterations is currently used because the number of loop iterations is not currently a performance bottleneck.

source

Return types for operations

CliffordNumbers.product_return_typeFunction
CliffordNumbers.product_return_type(::Type{X}, ::Type{Y}, [::GradeFilter{S}])

Returns a suitable type for representing the product of Clifford numbers of types X and Y. The GradeFilter{S} argument allows for the return type to be changed depending on the type of product. Without specialization on S, a type suitable for the geometric product is returned.

source
CliffordNumbers.exponential_typeFunction
CliffordNumbers.exponential_type(::Type{<:AbstractCliffordNumber})
+CliffordNumbers.exponential_type(x::AbstractCliffordNumber)

Returns the type expected when exponentiating a Clifford number. This is an EvenCliffordNumber if the nonzero grades of the input are even, a CliffordNumber otherwise.

source
diff --git a/dev/api/math.html b/dev/api/math.html index 90f3af8..722215c 100644 --- a/dev/api/math.html +++ b/dev/api/math.html @@ -1,12 +1,12 @@ Math · CliffordNumbers.jl

Mathematical operations

Grade automorphisms

Base.reverseMethod
adjoint(i::BitIndex) = reverse(i::BitIndex) = i' -> BitIndex
-adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source
CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
-grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source
Base.conjMethod
conj(i::BitIndex) -> BitIndex
-conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source

Duals and inverses

CliffordNumbers.versor_inverseFunction
CliffordNumbers.versor_inverse(x::AbstractCliffordNumber)

Calculates the versor inverse of x, equal to x' / abs2(x).

The versor inverse is only guaranteed to be an inverse for versors. Not all Clifford numbers have a well-defined inverse, (for instance, in algebras with 2 or more positive-squaring, dimensions, 1 + e₁ has no inverse). To validate the result, use inv(x) instead.

source
Base.invMethod
inv(x::AbstractCliffordNumber) -> AbstractCliffordNumber

Calculates the inverse of x, if it exists, using the versor inverse formula x' / abs2(x). The result is tested to check if its left and right products with x are approximately 1, and a CliffordNumbers.InverseException is thrown if this test does not pass.

source

Addition and subtraction

Addition and subtraction integrate seamlessly with those of the Julia Base number types, and no special documentation is included here.

Products

Products with scalars

The standard multiplication and division operations (*, /, //) between Clifford numbers and scalars behave as expected. Base.muladd has been overloaded to take advantage of fma instructions available on some hardware platforms.

Base.muladdMethod
muladd(x::Union{Real,Complex}, y::AbstractCliffordNumber{Q}, z::AbstractCliffordNumber{Q})
-muladd(x::AbstractCliffordNumber{Q}, y::Union{Real,Complex}, z::AbstractCliffordNumber{Q})

Multiplies a scalar with a Clifford number and adds another Clifford number, utilizing optimizations made available with scalar muladd, such as fma if hardware support is available.

source

Geometric products

Base.:*Function
*(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-(x::AbstractCliffordNumber{Q})(y::AbstractCliffordNumber{Q})

Calculates the geometric product of x and y, returning the smallest type which is able to represent all nonzero basis blades of the result.

source
CliffordNumbers.:⨼Function
left_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-⨼(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the left contraction of x and y.

For basis blades A of grade m and B of grade n, the left contraction is zero if n < m, otherwise it is KVector{n-m,Q}(A*B).

source
CliffordNumbers.:⨽Function
right_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-⨽(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the right contraction of x and y.

For basis blades A of grade m and B of grade n, the right contraction is zero if m < n, otherwise it is KVector{m-n,Q}(A*B).

source
CliffordNumbers.dotFunction
CliffordNumbers.dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the dot product of x and y.

For basis blades A of grade m and B of grade n, the dot product is equal to the left contraction when m >= n and is equal to the right contraction (up to sign) when n >= m.

Why is this function not exported?

The LinearAlgebra package also defines a dot function, and if both packages are used together, this will cause a name conflict if CliffordNumbers.dot is exported. In the future, we will try to resolve this without requiring a LinearAlgebra dependency.

Additionally, there is reason to prefer the use of the left and right contractions over the dot product because the contractions require fewer exceptions in their definitions and properties.

source
CliffordNumbers.hestenes_dotFunction
CliffordNumbers.hestenes_dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Returns the Hestenes product: this is equal to the dot product given by dot(x, y) but is equal to to zero when either x or y is a scalar.

Why is this function not exported?

In almost every case, left and right contractions are preferable - the dot product and the Hestenes product are less regular in algebraic sense, and the conditionals present in its implementation slow it down relative to contractions. It is provided for the sake of exact reproducibility of results which use it.

source
CliffordNumbers.:∧Function
∧(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-wedge(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the wedge (outer) product of two Clifford numbers x and y with quadratic form Q.

Note that the wedge product, in general, is not equal to the commutator product (or antisymmetric product), which may be invoked with the commutator function or the × operator.

source
CliffordNumbers.:×Function
×(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-commutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the commutator (or antisymmetric) product, equal to 1//2 * (x*y - y*x).

Note that the commutator product, in general, is not equal to the wedge product, which may be invoked with the wedge function or the operator.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source
CliffordNumbers.:⨰Function
⨰(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
-anticommutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the anticommutator (or symmetric) product, equal to 1//2 * (x*y + y*x).

Note that the dot product, in general, is not equal to the anticommutator product, which may be invoked with dot. In some cases, the preferred operators might be the left and right contractions, which use infix operators and respectively.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source

Scalar products and normalization

CliffordNumbers.scalar_productFunction
scalar_product(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the scalar product of two Clifford numbers with quadratic form Q. The result is a Real or Complex number. This can be converted back to an AbstractCliffordNumber.

source
Base.abs2Method
abs2(x::AbstractCliffordNumber{Q,T}) -> T

Calculates the squared norm of x, equal to scalar_product(x, x').

source
Base.absMethod
abs2(x::AbstractCliffordNumber{Q,T}) -> Union{Real,Complex}

Calculates the norm of x, equal to sqrt(scalar_product(x, x')).

source
CliffordNumbers.normalizeFunction
normalize(x::AbstractCliffordNumber{Q}) -> AbstractCliffordNumber{Q}

Normalizes x so that its magnitude (as calculated by abs2(x)) is 1.

source

Exponentiation

Base.expMethod
exp(x::AbstractCliffordNumber{Q})

Returns the natural exponential of a Clifford number.

For special cases where m squares to a scalar, the following shortcuts can be used to calculate exp(x):

  • When x^2 < 0: exp(x) === cos(abs(x)) + x * sin(abs(x)) / abs(x)
  • When x^2 > 0: exp(x) === cosh(abs(x)) + x * sinh(abs(x)) / abs(x)
  • When x^2 == 0: exp(x) == 1 + x

See also: exppi, exptau.

source
CliffordNumbers.exppiFunction
exppi(x::AbstractCliffordNumber)

Returns the natural exponential of π * x with greater accuracy than exp(π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exptau.

source
CliffordNumbers.exptauFunction
exptau(x::AbstractCliffordNumber)

Returns the natural exponential of 2π * x with greater accuracy than exp(2π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exppi.

source
+adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source
CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
+grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source
Base.conjMethod
conj(i::BitIndex) -> BitIndex
+conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source

Duals and inverses

CliffordNumbers.versor_inverseFunction
CliffordNumbers.versor_inverse(x::AbstractCliffordNumber)

Calculates the versor inverse of x, equal to x' / abs2(x).

The versor inverse is only guaranteed to be an inverse for versors. Not all Clifford numbers have a well-defined inverse, (for instance, in algebras with 2 or more positive-squaring, dimensions, 1 + e₁ has no inverse). To validate the result, use inv(x) instead.

source
Base.invMethod
inv(x::AbstractCliffordNumber) -> AbstractCliffordNumber

Calculates the inverse of x, if it exists, using the versor inverse formula x' / abs2(x). The result is tested to check if its left and right products with x are approximately 1, and a CliffordNumbers.InverseException is thrown if this test does not pass.

source

Addition and subtraction

Addition and subtraction integrate seamlessly with those of the Julia Base number types, and no special documentation is included here.

Products

Products with scalars

The standard multiplication and division operations (*, /, //) between Clifford numbers and scalars behave as expected. Base.muladd has been overloaded to take advantage of fma instructions available on some hardware platforms.

Base.muladdMethod
muladd(x::Union{Real,Complex}, y::AbstractCliffordNumber{Q}, z::AbstractCliffordNumber{Q})
+muladd(x::AbstractCliffordNumber{Q}, y::Union{Real,Complex}, z::AbstractCliffordNumber{Q})

Multiplies a scalar with a Clifford number and adds another Clifford number, utilizing optimizations made available with scalar muladd, such as fma if hardware support is available.

source

Geometric products

Base.:*Function
*(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+(x::AbstractCliffordNumber{Q})(y::AbstractCliffordNumber{Q})

Calculates the geometric product of x and y, returning the smallest type which is able to represent all nonzero basis blades of the result.

source
CliffordNumbers.:⨼Function
left_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+⨼(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the left contraction of x and y.

For basis blades A of grade m and B of grade n, the left contraction is zero if n < m, otherwise it is KVector{n-m,Q}(A*B).

source
CliffordNumbers.:⨽Function
right_contraction(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+⨽(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the right contraction of x and y.

For basis blades A of grade m and B of grade n, the right contraction is zero if m < n, otherwise it is KVector{m-n,Q}(A*B).

source
CliffordNumbers.dotFunction
CliffordNumbers.dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the dot product of x and y.

For basis blades A of grade m and B of grade n, the dot product is equal to the left contraction when m >= n and is equal to the right contraction (up to sign) when n >= m.

Why is this function not exported?

The LinearAlgebra package also defines a dot function, and if both packages are used together, this will cause a name conflict if CliffordNumbers.dot is exported. In the future, we will try to resolve this without requiring a LinearAlgebra dependency.

Additionally, there is reason to prefer the use of the left and right contractions over the dot product because the contractions require fewer exceptions in their definitions and properties.

source
CliffordNumbers.hestenes_dotFunction
CliffordNumbers.hestenes_dot(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Returns the Hestenes product: this is equal to the dot product given by dot(x, y) but is equal to to zero when either x or y is a scalar.

Why is this function not exported?

In almost every case, left and right contractions are preferable - the dot product and the Hestenes product are less regular in algebraic sense, and the conditionals present in its implementation slow it down relative to contractions. It is provided for the sake of exact reproducibility of results which use it.

source
CliffordNumbers.:∧Function
∧(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+wedge(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the wedge (outer) product of two Clifford numbers x and y with quadratic form Q.

Note that the wedge product, in general, is not equal to the commutator product (or antisymmetric product), which may be invoked with the commutator function or the × operator.

source
CliffordNumbers.:×Function
×(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+commutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the commutator (or antisymmetric) product, equal to 1//2 * (x*y - y*x).

Note that the commutator product, in general, is not equal to the wedge product, which may be invoked with the wedge function or the operator.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source
CliffordNumbers.:⨰Function
⨰(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})
+anticommutator(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the anticommutator (or symmetric) product, equal to 1//2 * (x*y + y*x).

Note that the dot product, in general, is not equal to the anticommutator product, which may be invoked with dot. In some cases, the preferred operators might be the left and right contractions, which use infix operators and respectively.

Type promotion

Because of the rational 1//2 factor in the product, inputs with scalar types subtyping Integer will be promoted to Rational subtypes.

source

Scalar products and normalization

CliffordNumbers.scalar_productFunction
scalar_product(x::AbstractCliffordNumber{Q}, y::AbstractCliffordNumber{Q})

Calculates the scalar product of two Clifford numbers with quadratic form Q. The result is a Real or Complex number. This can be converted back to an AbstractCliffordNumber.

source
Base.abs2Method
abs2(x::AbstractCliffordNumber{Q,T}) -> T

Calculates the squared norm of x, equal to scalar_product(x, x').

source
Base.absMethod
abs2(x::AbstractCliffordNumber{Q,T}) -> Union{Real,Complex}

Calculates the norm of x, equal to sqrt(scalar_product(x, x')).

source
CliffordNumbers.normalizeFunction
normalize(x::AbstractCliffordNumber{Q}) -> AbstractCliffordNumber{Q}

Normalizes x so that its magnitude (as calculated by abs2(x)) is 1.

source

Exponentiation

Base.expMethod
exp(x::AbstractCliffordNumber{Q})

Returns the natural exponential of a Clifford number.

For special cases where m squares to a scalar, the following shortcuts can be used to calculate exp(x):

  • When x^2 < 0: exp(x) === cos(abs(x)) + x * sin(abs(x)) / abs(x)
  • When x^2 > 0: exp(x) === cosh(abs(x)) + x * sinh(abs(x)) / abs(x)
  • When x^2 == 0: exp(x) == 1 + x

See also: exppi, exptau.

source
CliffordNumbers.exppiFunction
exppi(x::AbstractCliffordNumber)

Returns the natural exponential of π * x with greater accuracy than exp(π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exptau.

source
CliffordNumbers.exptauFunction
exptau(x::AbstractCliffordNumber)

Returns the natural exponential of 2π * x with greater accuracy than exp(2π * x) in the case where x^2 is a negative scalar, especially for large values of abs(x).

See also: exp, exppi.

source
diff --git a/dev/api/metrics.html b/dev/api/metrics.html index 48ba0a5..c8b3442 100644 --- a/dev/api/metrics.html +++ b/dev/api/metrics.html @@ -1,17 +1,17 @@ -Metric signatures · CliffordNumbers.jl

Metric signatures

Signature types

CliffordNumbers.Metrics.AbstractSignatureType
Metrics.AbstractSignature <: AbstractVector{Int8}

Supertype for all data types that represent metric signatures. This includes the generic Signature type as well as other specialized types.

Metric signatures can be interpreted as the signs of the diagonal elements of the metric tensor. All elements are either -1, 0, or 1. All nondegenerate Clifford algebras admit an orthonormal basis corresponding to the metric.

Aside from the generic Metrics.Signature subtype, types for commonly used algebras are available, including Metrics.VGA, Metrics.PGA, and Metrics.CGA. Custom signatures with firmer bounds on their behavior can be implemented by subtyping this type.

source
CliffordNumbers.Metrics.SignatureType
Metrics.Signature <: Metrics.AbstractSignature
+Metric signatures · CliffordNumbers.jl

Metric signatures

Signature types

CliffordNumbers.Metrics.AbstractSignatureType
Metrics.AbstractSignature <: AbstractVector{Int8}

Supertype for all data types that represent metric signatures. This includes the generic Signature type as well as other specialized types.

Metric signatures can be interpreted as the signs of the diagonal elements of the metric tensor. All elements are either -1, 0, or 1. All nondegenerate Clifford algebras admit an orthonormal basis corresponding to the metric.

Aside from the generic Metrics.Signature subtype, types for commonly used algebras are available, including Metrics.VGA, Metrics.PGA, and Metrics.CGA. Custom signatures with firmer bounds on their behavior can be implemented by subtyping this type.

source
CliffordNumbers.Metrics.SignatureType
Metrics.Signature <: Metrics.AbstractSignature
 Metrics.Signature(
     dimensions::Integer,
     negative::UInt,
     degenerate::UInt,
     [first_index::Integer = 1]
-)

Contains information about the metric associated with a Clifford algebra or Clifford number. This type is constructed to be as generic as possible; other subtypes of Metrics.AbstractSignature may provide firmer guarantees on behavior, such as VGA.

The number which the dimensions square to is stored in a pair of UInt fields. The negative field consists of 1 bits for dimensions that square to a negative number, and 0 bits for those squaring to a positive number, matching the convention of sign bits in signed numbers.

The degenerate field consists of 1 bits for degenerate dimensions (dimensions that square to zero) and 0 bits for nondegenerate dimensions.

The numerical index of the first basis vector is first_index, which defaults to 1. Some algebras conventionally use 0 as the first index, such as projective geometric algebras and Lorentzian geometric algebras, and in some cases it may be useful to start with a negative index if there are a larger number of modeling dimensions.

source
CliffordNumbers.Metrics.VGAType
VGA <: Metrics.AbstractSignature

Represents the signature associated with a vanilla geometric algebra (VGA), a positive-definite geometric algebra which models space without any projective dimensions.

source
CliffordNumbers.Metrics.PGAType
PGA <: Metrics.AbstractSignature

Represents the signature associated with a PGA (projective geometric algebra) with the given number of modeled dimensions. The constructed algebra will contain the number of modeled dimensions plus one degenerate (zero-squaring) dimension represented by e₀. This degenerate dimension corresponds with the n∞ null vector in CGA (conformal geometric algebra).

source
CliffordNumbers.Metrics.CGAType
CGA <: Metrics.AbstractSignature

Represents the signature of a CGA (conformal geometric algebra) with the given number of modeled dimensions. The constructed algebra will contain the number of modeled dimensions plus one positive-squaring dimension and one negative-squaring dimension.

There are two common choices of vector basis for the extra dimensions added when working with CGA. The most straightforward one is e₊ and e₋, which square to +1 and -1, respectively, and this is what is used internally, with the negative-squaring dimension being the first one.

However, there is another commonly used basis: define null vectors n₀ = (e₋ - e₊)/2 and n∞ = e₋ - e₊, which represent the origin point and the point at infinity, respectively. n∞ corresponds to e₀ in PGA (projective geometric algebra).

source
CliffordNumbers.Metrics.LGAType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
-const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.LGAEastType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
-const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.LGAWestType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
-const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.ExteriorType
Exterior <: Metrics.AbstractSignature

Represents a signature corresponding to an exterior algebra. In an exterior algebra, all 1-blades square to 0, and the geometric product is equivalent ot the wedge product.

Unlike VGA, PGA, CGA, and LGA, the first index is not assumed when constructing this object, and can be manually specified. If it is not specified, it defaults to 1.

source

Aliases for common signatures

CliffordNumbers.Metrics.VGA2DConstant
VGA2D (alias for VGA(2))

The algebra of 2D space. The even subalgebra of this algebra is isomorphic to ℂ, the complex numbers.

source
CliffordNumbers.Metrics.VGA3DConstant
VGA3D (alias for VGA(3))
-const APS = VGA3D

The algebra of physical space, a 3D VGA which is commonly used (explicitly and implicitly) to model non-relativistic physics. It also serves as the subalgebra of both signature conventions of the spacetime algebra (available as STAEast and STAWest).

The even subalgebra of this algebra is isomorphic to ℍ, the quaternions.

source
CliffordNumbers.Metrics.PGA3DConstant
PGA3D (alias for PGA(3))

The projective geometric algebra of 3D space, which represents points, lines, and planes in a 3D space.

source
CliffordNumbers.Metrics.CGA2DConstant
CGA2D (alias for CGA(2))

The conformal geometric algebra of 2D space, which represents points, lines, and circles on the plane. This algebra constitutes a framework for compass and straightedge constructions.

This algebra is isomorphic to STAEast, and this isomorphism is the reason why the default convention for spacetime algebras in this package is the West Coast (mostly negative) convention.

source
CliffordNumbers.Metrics.CGA3DConstant
CGA3D (alias for CGA(3))

The conformal geometric algebra of 3D space, which represents points, lines, and planes, as well as circles and spheres. This algebra constitutes a framework for extending compass and straightedge constructions to 3 dimensions.

source
CliffordNumbers.Metrics.STAEastConstant
STAEast (alias for LGAEast(3))

The spacetime algebra using the East Coast sign convention (spatial dimensions square positive, temporal dimensions square negative), with the temporal dimension at index 0.

This convention is not the default STA convention, since this signature is identical to that of the 2D conformal geometric algebra.

source
CliffordNumbers.Metrics.STAPEastConstant
STAPEast (alias for Signature(5, 0b00010, 0b00001, -1))

The projective spacetime algebra using the East Coast sign convention (spatial dimensions square positive, temporal dimensions square negative). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source
CliffordNumbers.Metrics.STAPWestConstant
STAPWest (alias for Signature(5, 0b11100, 0b00001, -1))
-const STAP = STAPWest

The projective spacetime algebra using the West Coast sign convention (spatial dimensions square negative, temporal dimensions square positive). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source
CliffordNumbers.Metrics.STAPConstant
STAPWest (alias for Signature(5, 0b11100, 0b00001, -1))
-const STAP = STAPWest

The projective spacetime algebra using the West Coast sign convention (spatial dimensions square negative, temporal dimensions square positive). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source

Associated methods

CliffordNumbers.Metrics.dimensionFunction
dimension(s::AbstractSignature) -> Int8

Returns the total number of dimensions associated with s. The default implementation returns signed(s.dimensions).

The total number of basis blades is equal to to the size of the power set of all basis vectors, and is equal to 2^dimension(s).

source
CliffordNumbers.signatureFunction
signature(T::Type{<:AbstractCliffordNumber{Q}}) = Q
-signature(x::AbstractCliffordNumber{Q}) = Q

Returns the metric signature object associated with an AbstractCliffordNumber x or its type T.

source
CliffordNumbers.Metrics.gradesFunction
grades(s::AbstractSignature) -> UnitRange{Int8}

Returns the total number of grades associated with s, which is equal to 0:dimension(s).

source
CliffordNumbers.Metrics.is_degenerateFunction
is_degenerate(s::AbstractSignature)

Returns true if any basis elements of s square to 0.

This does not imply that no elements of the associated Clifford algebra square to 0.

source
+)

Contains information about the metric associated with a Clifford algebra or Clifford number. This type is constructed to be as generic as possible; other subtypes of Metrics.AbstractSignature may provide firmer guarantees on behavior, such as VGA.

The number which the dimensions square to is stored in a pair of UInt fields. The negative field consists of 1 bits for dimensions that square to a negative number, and 0 bits for those squaring to a positive number, matching the convention of sign bits in signed numbers.

The degenerate field consists of 1 bits for degenerate dimensions (dimensions that square to zero) and 0 bits for nondegenerate dimensions.

The numerical index of the first basis vector is first_index, which defaults to 1. Some algebras conventionally use 0 as the first index, such as projective geometric algebras and Lorentzian geometric algebras, and in some cases it may be useful to start with a negative index if there are a larger number of modeling dimensions.

source
CliffordNumbers.Metrics.VGAType
VGA <: Metrics.AbstractSignature

Represents the signature associated with a vanilla geometric algebra (VGA), a positive-definite geometric algebra which models space without any projective dimensions.

source
CliffordNumbers.Metrics.PGAType
PGA <: Metrics.AbstractSignature

Represents the signature associated with a PGA (projective geometric algebra) with the given number of modeled dimensions. The constructed algebra will contain the number of modeled dimensions plus one degenerate (zero-squaring) dimension represented by e₀. This degenerate dimension corresponds with the n∞ null vector in CGA (conformal geometric algebra).

source
CliffordNumbers.Metrics.CGAType
CGA <: Metrics.AbstractSignature

Represents the signature of a CGA (conformal geometric algebra) with the given number of modeled dimensions. The constructed algebra will contain the number of modeled dimensions plus one positive-squaring dimension and one negative-squaring dimension.

There are two common choices of vector basis for the extra dimensions added when working with CGA. The most straightforward one is e₊ and e₋, which square to +1 and -1, respectively, and this is what is used internally, with the negative-squaring dimension being the first one.

However, there is another commonly used basis: define null vectors n₀ = (e₋ - e₊)/2 and n∞ = e₋ - e₊, which represent the origin point and the point at infinity, respectively. n∞ corresponds to e₀ in PGA (projective geometric algebra).

source
CliffordNumbers.Metrics.LGAType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
+const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.LGAEastType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
+const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.LGAWestType
LGA{C} <: Metrics.AbstractSignature

Represents the signature of a Lorentzian geometric algebra (LGA), an algebra which models a given number of spatial dimensions associated with a single time dimension at index 0.

The type parameter C corresponds to the sign bit associated with the square of the spatial 1-blades. For convenience, the following aliases are defined:

const LGAEast = LGA{false}
+const LGAWest = LGA{true}

The names correspond to the "East Coast" and "West Coast" conventions for the metric signature of spacetime, with the East Coast convention having positive squares for spatial 1-blades and the West Coast convention having negative squares for spatial 1-blades.

source
CliffordNumbers.Metrics.ExteriorType
Exterior <: Metrics.AbstractSignature

Represents a signature corresponding to an exterior algebra. In an exterior algebra, all 1-blades square to 0, and the geometric product is equivalent ot the wedge product.

Unlike VGA, PGA, CGA, and LGA, the first index is not assumed when constructing this object, and can be manually specified. If it is not specified, it defaults to 1.

source

Aliases for common signatures

CliffordNumbers.Metrics.VGA2DConstant
VGA2D (alias for VGA(2))

The algebra of 2D space. The even subalgebra of this algebra is isomorphic to ℂ, the complex numbers.

source
CliffordNumbers.Metrics.VGA3DConstant
VGA3D (alias for VGA(3))
+const APS = VGA3D

The algebra of physical space, a 3D VGA which is commonly used (explicitly and implicitly) to model non-relativistic physics. It also serves as the subalgebra of both signature conventions of the spacetime algebra (available as STAEast and STAWest).

The even subalgebra of this algebra is isomorphic to ℍ, the quaternions.

source
CliffordNumbers.Metrics.PGA3DConstant
PGA3D (alias for PGA(3))

The projective geometric algebra of 3D space, which represents points, lines, and planes in a 3D space.

source
CliffordNumbers.Metrics.CGA2DConstant
CGA2D (alias for CGA(2))

The conformal geometric algebra of 2D space, which represents points, lines, and circles on the plane. This algebra constitutes a framework for compass and straightedge constructions.

This algebra is isomorphic to STAEast, and this isomorphism is the reason why the default convention for spacetime algebras in this package is the West Coast (mostly negative) convention.

source
CliffordNumbers.Metrics.CGA3DConstant
CGA3D (alias for CGA(3))

The conformal geometric algebra of 3D space, which represents points, lines, and planes, as well as circles and spheres. This algebra constitutes a framework for extending compass and straightedge constructions to 3 dimensions.

source
CliffordNumbers.Metrics.STAEastConstant
STAEast (alias for LGAEast(3))

The spacetime algebra using the East Coast sign convention (spatial dimensions square positive, temporal dimensions square negative), with the temporal dimension at index 0.

This convention is not the default STA convention, since this signature is identical to that of the 2D conformal geometric algebra.

source
CliffordNumbers.Metrics.STAPEastConstant
STAPEast (alias for Signature(5, 0b00010, 0b00001, -1))

The projective spacetime algebra using the East Coast sign convention (spatial dimensions square positive, temporal dimensions square negative). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source
CliffordNumbers.Metrics.STAPWestConstant
STAPWest (alias for Signature(5, 0b11100, 0b00001, -1))
+const STAP = STAPWest

The projective spacetime algebra using the West Coast sign convention (spatial dimensions square negative, temporal dimensions square positive). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source
CliffordNumbers.Metrics.STAPConstant
STAPWest (alias for Signature(5, 0b11100, 0b00001, -1))
+const STAP = STAPWest

The projective spacetime algebra using the West Coast sign convention (spatial dimensions square negative, temporal dimensions square positive). The degenerate dimension is at index -1.

As with STA, the default convention for STAP is the West Coast metric. For an explanation, see STA.

source

Associated methods

CliffordNumbers.Metrics.dimensionFunction
dimension(s::AbstractSignature) -> Int8

Returns the total number of dimensions associated with s. The default implementation returns signed(s.dimensions).

The total number of basis blades is equal to to the size of the power set of all basis vectors, and is equal to 2^dimension(s).

source
CliffordNumbers.signatureFunction
signature(T::Type{<:AbstractCliffordNumber{Q}}) = Q
+signature(x::AbstractCliffordNumber{Q}) = Q

Returns the metric signature object associated with an AbstractCliffordNumber x or its type T.

source
CliffordNumbers.Metrics.gradesFunction
grades(s::AbstractSignature) -> UnitRange{Int8}

Returns the total number of grades associated with s, which is equal to 0:dimension(s).

source
CliffordNumbers.Metrics.is_degenerateFunction
is_degenerate(s::AbstractSignature)

Returns true if any basis elements of s square to 0.

This does not imply that no elements of the associated Clifford algebra square to 0.

source
diff --git a/dev/index.html b/dev/index.html index f5b4010..fd615cb 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · CliffordNumbers.jl

CliffordNumbers

CliffordNumbers.jl is a package that provides fully static multivectors (Clifford numbers) in arbitrary dimensions and metrics. While in many cases, sparse representations of multivectors are more efficient, for spaces of low dimension, dense static representations may provide a performance and convenience advantage.

Design goals

The goal of this package is to provide a multivector implementation that:

  • Allows for the construction of multivectors in arbitrary metrics, with coefficients that subtype any instance of Julia's base numeric types, Real or Complex.
  • Provides data structures of fixed sizes that represent multivectors. This allows for instances to be allocated on the stack or stored inline in an Array rather than as pointers to individually allocated instances.
  • Provides dense representations of multivectors, as well as convenient sparse representations, which can be constructed from each other, converted in a way that guarantees representability, and allows for promotion between instances.
  • Subtypes Number: The term "Clifford number" emphasizes the perspective of multivectors as an extension of the real numbers, in the same way that complex numbers and quaternions extend them. (It should be noted that both complex numbers and quaternions are Clifford algebras themselves!)
  • Aggressively optimizes all mathematical operations, utilizing fma operations and SIMD instructions whenever possible.
  • Interoperates with automatic differentiation tools and other packages which allow for the implementation of operations from geometric calculus.
+Home · CliffordNumbers.jl

CliffordNumbers

CliffordNumbers.jl is a package that provides fully static multivectors (Clifford numbers) in arbitrary dimensions and metrics. While in many cases, sparse representations of multivectors are more efficient, for spaces of low dimension, dense static representations may provide a performance and convenience advantage.

Design goals

The goal of this package is to provide a multivector implementation that:

  • Allows for the construction of multivectors in arbitrary metrics, with coefficients that subtype any instance of Julia's base numeric types, Real or Complex.
  • Provides data structures of fixed sizes that represent multivectors. This allows for instances to be allocated on the stack or stored inline in an Array rather than as pointers to individually allocated instances.
  • Provides dense representations of multivectors, as well as convenient sparse representations, which can be constructed from each other, converted in a way that guarantees representability, and allows for promotion between instances.
  • Subtypes Number: The term "Clifford number" emphasizes the perspective of multivectors as an extension of the real numbers, in the same way that complex numbers and quaternions extend them. (It should be noted that both complex numbers and quaternions are Clifford algebras themselves!)
  • Aggressively optimizes all mathematical operations, utilizing fma operations and SIMD instructions whenever possible.
  • Interoperates with automatic differentiation tools and other packages which allow for the implementation of operations from geometric calculus.
diff --git a/dev/indexing.html b/dev/indexing.html index 3900590..52fd63b 100644 --- a/dev/indexing.html +++ b/dev/indexing.html @@ -37,4 +37,4 @@ true julia> BitIndices{STA,CliffordNumber{STA}}() == BitIndices{STA,CliffordNumber{STA,Float32,8}}() -true

For this reason, you should call BitIndices(x) or BitIndices(C) instead of directly constructing BitIndices{Q,C}().

TransformedBitIndices{Q,C,F}

If we want to perform a transformation on all elements of a BitIndices instance, we may use dot syntax and broadcast an operation: for instance, reverse.(BitIndices(x)) to obtain the reverse of all indices. Without any explicit specification of behavior, this will return a Vector, and for the sake of performance we'd like to avoid returning types without statically known lengths.

We could solve this by converting BitIndices to a Tuple internally as part of the broadcasting implementation, but doing this will cause its own set of problems: indexing an AbstractCliffordNumber with a Tuple returns a Tuple. This may be fine internally, if we know to call the constructor, but this is potentially confusing for new users. For this reason, we provide TransformedBitIndices{Q,C,F}, which is a lazy representation of a function applied to every element of BitIndices(C).

For convenience, we provide a few aliases for operations which are commonly used with BitIndices:

In the future, we may override some broadcast implementations to ensure that all of these types are interconvertible with each other and with BitIndices{Q,C}.

+true

For this reason, you should call BitIndices(x) or BitIndices(C) instead of directly constructing BitIndices{Q,C}().

TransformedBitIndices{Q,C,F}

If we want to perform a transformation on all elements of a BitIndices instance, we may use dot syntax and broadcast an operation: for instance, reverse.(BitIndices(x)) to obtain the reverse of all indices. Without any explicit specification of behavior, this will return a Vector, and for the sake of performance we'd like to avoid returning types without statically known lengths.

We could solve this by converting BitIndices to a Tuple internally as part of the broadcasting implementation, but doing this will cause its own set of problems: indexing an AbstractCliffordNumber with a Tuple returns a Tuple. This may be fine internally, if we know to call the constructor, but this is potentially confusing for new users. For this reason, we provide TransformedBitIndices{Q,C,F}, which is a lazy representation of a function applied to every element of BitIndices(C).

For convenience, we provide a few aliases for operations which are commonly used with BitIndices:

In the future, we may override some broadcast implementations to ensure that all of these types are interconvertible with each other and with BitIndices{Q,C}.

diff --git a/dev/metrics.html b/dev/metrics.html index 5f71eb9..07ea2b0 100644 --- a/dev/metrics.html +++ b/dev/metrics.html @@ -1,2 +1,2 @@ -Metric signatures · CliffordNumbers.jl

Metric signatures

Clifford algebras are characterized by the metric signatures of the spaces they represent. Some are very commonly used, such as the algebra of physical space (APS), or are generated as part of a family, such as the projective geometric algebras (PGAs), but in other cases you may need the flexibility to work with custom metric signatures.

The CliffordNumbers.Metrics submodule provides tools for working with metric signatures.

Interface

The type parameter Q of AbstractCliffordNumber{Q,T} is not constrained in any way, which means that any type or data consisting of pure bits may reside there. However, for the sake of correctness and fully defined behavior, Q must satisfy an informal interface.

Metric signature objects are treated like AbstractVector{Int8} instances, but with the elements constrained to be equal to +1, 0, or -1, corresponding to basis 1-blades squaring to positive values, negative values, or zero. In the future, we may support arbitrary values for this type.

This array is not constrained to be a 1-based array, and the values of eachindex for the array correspond to the indices of the basis 1-blades of the algebra.

The Metrics.AbstractSignature type

We define a type, Metrics.AbstractSignature <: AbstractVector{Int8}, for which this interface is already partially implemented.

Pre-defined signatures

There are many commonly used families of algebras, and for the sake of convenience, we provide four subtypes of Metrics.AbstractSignature to handles these cases:

  • Metrics.VGA represents vanilla geometric algebras.
  • Metrics.PGA represents projective geometric algebras.
  • Metrics.CGA represents conformal geometric algebras.
  • Metrics.LGA{C} represents Lorentzian geometric algebras:
    • Metrics.LGAEast uses the East Coast convention (timelike dimensions square to -1).
    • Metrics.LGAWest uses the West Coast convention (timelike dimensions square to +1).

To construct an instance of one of these types, call it with the number of modeled spatial dimensions:

  • Metrics.VGA(3) models 3 spatial dimensions with no extra dimensions.
  • Metrics.PGA(3) models 3 spatial dimensions with 1 degenerate (zero-squaring) dimension.
  • Metrics.CGA(3) models 3 spatial dimensions with 2 extra dimensions.
  • Metrics.LGAEast(3) models 3 spatial dimensions with an extra negative-squaring time dimension.
+Metric signatures · CliffordNumbers.jl

Metric signatures

Clifford algebras are characterized by the metric signatures of the spaces they represent. Some are very commonly used, such as the algebra of physical space (APS), or are generated as part of a family, such as the projective geometric algebras (PGAs), but in other cases you may need the flexibility to work with custom metric signatures.

The CliffordNumbers.Metrics submodule provides tools for working with metric signatures.

Interface

The type parameter Q of AbstractCliffordNumber{Q,T} is not constrained in any way, which means that any type or data consisting of pure bits may reside there. However, for the sake of correctness and fully defined behavior, Q must satisfy an informal interface.

Metric signature objects are treated like AbstractVector{Int8} instances, but with the elements constrained to be equal to +1, 0, or -1, corresponding to basis 1-blades squaring to positive values, negative values, or zero. In the future, we may support arbitrary values for this type.

This array is not constrained to be a 1-based array, and the values of eachindex for the array correspond to the indices of the basis 1-blades of the algebra.

The Metrics.AbstractSignature type

We define a type, Metrics.AbstractSignature <: AbstractVector{Int8}, for which this interface is already partially implemented.

Pre-defined signatures

There are many commonly used families of algebras, and for the sake of convenience, we provide four subtypes of Metrics.AbstractSignature to handles these cases:

  • Metrics.VGA represents vanilla geometric algebras.
  • Metrics.PGA represents projective geometric algebras.
  • Metrics.CGA represents conformal geometric algebras.
  • Metrics.LGA{C} represents Lorentzian geometric algebras:
    • Metrics.LGAEast uses the East Coast convention (timelike dimensions square to -1).
    • Metrics.LGAWest uses the West Coast convention (timelike dimensions square to +1).

To construct an instance of one of these types, call it with the number of modeled spatial dimensions:

  • Metrics.VGA(3) models 3 spatial dimensions with no extra dimensions.
  • Metrics.PGA(3) models 3 spatial dimensions with 1 degenerate (zero-squaring) dimension.
  • Metrics.CGA(3) models 3 spatial dimensions with 2 extra dimensions.
  • Metrics.LGAEast(3) models 3 spatial dimensions with an extra negative-squaring time dimension.
diff --git a/dev/numeric.html b/dev/numeric.html index 0800bc8..7d68532 100644 --- a/dev/numeric.html +++ b/dev/numeric.html @@ -8,4 +8,4 @@ 1 + 4σ₁σ₂ + 6σ₁σ₃ + 7σ₂σ₃ julia> convert(EvenCliffordNumber, test) -ERROR: InexactError: ...
Danger

This is an extremely important point: construction of a Clifford number type with fewer grades than the input performs a grade projection operation without throwing an error. However, conversion will throw an error if the grades of the input value are not present in the input type.

This is not how other subtypes of Number defined by Julia Base behave, as their conversion operations are generally defined to be identical to the constructor, and always throw the same error for a given pair of type and value.

If converting an AbstractCliffordNumber to any other numeric type, construction and conversion behave identically, as expected.

Construction and conversion of Clifford numbers from other Clifford numbers the only time that the quadratic form type parameter can be omitted, as it can be inferred directly from the input. In the case of CliffordNumbers.Z2CliffordNumber, the parity type parameter can also be inferred from a KVector input.

Scalar conversion

It may be desirable to convert the scalar type of a Clifford number without having to specify the full typename of the desired output type. The function scalar_convert(T, x) takes a type T<:Union{Real,Complex} and any Clifford number x and converts its scalar type to T. If x is a Real or Complex, it just converts x to an instance of T.

+ERROR: InexactError: ...
Danger

This is an extremely important point: construction of a Clifford number type with fewer grades than the input performs a grade projection operation without throwing an error. However, conversion will throw an error if the grades of the input value are not present in the input type.

This is not how other subtypes of Number defined by Julia Base behave, as their conversion operations are generally defined to be identical to the constructor, and always throw the same error for a given pair of type and value.

If converting an AbstractCliffordNumber to any other numeric type, construction and conversion behave identically, as expected.

Construction and conversion of Clifford numbers from other Clifford numbers the only time that the quadratic form type parameter can be omitted, as it can be inferred directly from the input. In the case of CliffordNumbers.Z2CliffordNumber, the parity type parameter can also be inferred from a KVector input.

Scalar conversion

It may be desirable to convert the scalar type of a Clifford number without having to specify the full typename of the desired output type. The function scalar_convert(T, x) takes a type T<:Union{Real,Complex} and any Clifford number x and converts its scalar type to T. If x is a Real or Complex, it just converts x to an instance of T.

diff --git a/dev/objects.inv b/dev/objects.inv index 62d58af..a8e348c 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/operations.html b/dev/operations.html index 5bba24b..344c03b 100644 --- a/dev/operations.html +++ b/dev/operations.html @@ -1,5 +1,5 @@ Operations · CliffordNumbers.jl

Operations

Like with other numbers, standard mathematical operations are supported that relate Clifford numbers to elements of their scalar field and to each other.

Unary operations

Grade automorphisms

Grade automorphisms are operations which preserves the grades of each basis blade, but changes their sign depending on the grade. All of these operations are their own inverse.

All grade automorphisms are applicable to BitIndex objects, and the way they are implemented is through constructors that use TransformedBitIndices objects to alter each grade.

Reverse

The reverse is an operation which reverses the order of the wedge product that constructed each basis blade. This is implemented with methods for Base.reverse and Base.:~.

Syntax changes

In the future, Base.:~ will no longer be used for this operation; instead Base.adjoint will be overloaded, providing ' as a syntax for the reverse.

This is the most commonly used automorphism, and in a sense can be thought of as equivalent to complex conjugation. When working with even elements of the algebras of 2D or 3D space, this behaves identically to complex conjugation and quaternion conjugation. However, this is not the case when working in the even subalgebras.

Base.reverseMethod
adjoint(i::BitIndex) = reverse(i::BitIndex) = i' -> BitIndex
-adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source

Grade involution

Grade involution changes the sign of all odd grades, an operation equivalent to mirroring every basis vector of the space. This can be acheived with the grade_involution function.

When interpreting even multivectors as elements of the even subalgebra of the algebra of interest, the grade involution in the even subalgebra is equivalent to the reverse in the algebra of interest.

Grade involution is equivalent to complex conjugation in when dealing with the even subalgebra of 2D space, which is isomorphic to the complex numbers, but this is not true for quaternion conjugation. Instead, use the Clifford conjugate (described below).

CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
-grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source

Clifford conjugation

The Clifford conjugate is the combination of the reverse and grade involution. This is available via an overload of Base.conj.

Warning

conj(::AbstractCliffordNumber) implements the Clifford conjugate, not the reverse!

When dealing with the even subalgebras of 2D and 3D VGAs, which are isomorphic to the complex numbers and quaternions, respectively, the Clifford conjugate is equivalent to complex conjugation or quaternion conjugation. Otherwise, this is a less widely used operation than the above two.

Base.conjMethod
conj(i::BitIndex) -> BitIndex
-conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source

Binary operations

Addition and subtraction

Addition and subtraction work as expected for Clifford numbers just as they do for other numbers. The promotion system handles all cases where objects of mixed type are added.

Products

Clifford algebras admit a variety of products. Common ones are implemented with infix operators.

Geometric product

The geometric product, or Clifford product, is the defining product of the Clifford algebra. This is implemented with the usual multiplication operator *, but it is also possible to use parenthetical notation as it is with real numbers.

Wedge product

The wedge product is the defining product of the exterior algebra. This is available with the wedge() function, or with the infix operator.

Tip

You can define elements of exterior algebras directly by using Metrics.Exterior(D), whose geometric product is equivalent to the wedge product.

Contractions and dot products

The contraction operations generalize the dot product of vectors to Clifford numbers. While it is possible to define a symmetric dot product (and one is provided in this package), the generalization of the dot product to Clifford numbers is naturally asymmetric in cases where the grade of one input blade is not equal to that of the other.

For Clifford numbers x and y, the left contraction x ⨼ y describes the result of projecting x onto the space spanned by y. If x and y are homogeneous in grade, this product is equal to the geometric product if grade(y) ≥ grade(x), and zero otherwise. For general multivectors, the left contraction can be calculated by applying this rule to the products of their basis blades.

The analogous right contraction is only nonzero if grade(x) ≥ grade(y), and it can be calculated with .

The dot product is a symmetric variation of the left and right contractions, and provides a looser constraint on the basis blades: grade(CliffordNumbers.dot(x,y)) must equal abs(grade(x) - grade(y)). The Hestenes dot product is equivalent to the dot product above, but is zero if either x or y is a scalar.

Note

Currently, the dot product is implemented with the unexported function CliffordNumbers.dot. This package does not depend on LinearAlgebra, so there would be a name conflict if this method were exported and both this package and LinearAlgebra were loaded.

Contractions are generally favored over the dot products due to their nicer implementations and properties, which have fewer exceptions. It is generally recommended that the Hestenes dot product be avoided, though it is included in this library for the sake of completeness as CliffordNumber.hestenes_dot, which is also not exported.

Commutator and anticommutator products

The commutator product (or antisymmetric product) of Clifford numbers x and y, denoted x × y, is equal to 1//2 * (x*y - y*x). This product is nonzero if the geometric product of x and y does not commute, and the value represents the degree to which they fail to commute.

The commutator product is the building block of Lie algebras; in particular, the commutator products of bivectors, which are also bivectors. With the bivectors of 3D space, the Lie algebra is equivalent to that generated by the cross product, hence the × notation.

The analogous anticommutator product (or symmetric product) is 1//2 * (x*y + y*x). This uses the operator, which is not an operator generally used for this purpose, but was selected as it looks similar to the commutator product, with the dot indicating the similarity with the dot product, which is also symmetric.

Defining new products: Multiplication internals

Products are implemented with the fast multiplication kernel CliffordNumbers.mul, which accepts two Clifford numbers with the same scalar type and a CliffordNumbers.GradeFilter object. This GradeFilter object defines a method that takes two or more BitIndex objects and returns false if their product is constrained to be zero.

CliffordNumbers.mul requires that the coefficient types of the numbers being multiplied are the same. Methods which leverage CliffordNumbers.mul should promote the coefficient types of the arguments to a common type using scalar_promote before passing them to the kernel. Any further promotion needed to return the final result is handled by the kernel.

In general, it is also strongly recommended to promote the types of the arguments to CliffordNumbers.Z2CliffordNumber or CliffordNumber for higher performance. Currently, the implementation of CliffordNumbers.mul is asymmetric, and does not consider which input is longer. Even in the preferred order, we find that KVector incurs a significant performance penalty.

+adjoint(x::AbstractCliffordNumber) = reverse(x::AbstractCliffordNumber) = x' -> typeof(x)

Performs the reverse operation on the basis blade indexed by b or the Clifford number x. The sign of the reverse depends on the grade of the basis blade g, and is positive for g % 4 in 0:1 and negative for g % 4 in 2:3.

source

Grade involution

Grade involution changes the sign of all odd grades, an operation equivalent to mirroring every basis vector of the space. This can be acheived with the grade_involution function.

When interpreting even multivectors as elements of the even subalgebra of the algebra of interest, the grade involution in the even subalgebra is equivalent to the reverse in the algebra of interest.

Grade involution is equivalent to complex conjugation in when dealing with the even subalgebra of 2D space, which is isomorphic to the complex numbers, but this is not true for quaternion conjugation. Instead, use the Clifford conjugate (described below).

CliffordNumbers.grade_involutionMethod
grade_involution(i::BitIndex) -> BitIndex
+grade_involution(x::AbstractCliffordNumber) -> typeof(x)

Calculates the grade involution of the basis blade indexed by b or the Clifford number x. This effectively reflects all of the basis vectors of the space along their own mirror operation, which makes elements of odd grade flip sign.

source

Clifford conjugation

The Clifford conjugate is the combination of the reverse and grade involution. This is available via an overload of Base.conj.

Warning

conj(::AbstractCliffordNumber) implements the Clifford conjugate, not the reverse!

When dealing with the even subalgebras of 2D and 3D VGAs, which are isomorphic to the complex numbers and quaternions, respectively, the Clifford conjugate is equivalent to complex conjugation or quaternion conjugation. Otherwise, this is a less widely used operation than the above two.

Base.conjMethod
conj(i::BitIndex) -> BitIndex
+conj(x::AbstractCliffordNumber) -> typeof(x)

Calculates the Clifford conjugate of the basis blade indexed by b or the Clifford number x. This is equal to grade_involution(reverse(x)).

source

Binary operations

Addition and subtraction

Addition and subtraction work as expected for Clifford numbers just as they do for other numbers. The promotion system handles all cases where objects of mixed type are added.

Products

Clifford algebras admit a variety of products. Common ones are implemented with infix operators.

Geometric product

The geometric product, or Clifford product, is the defining product of the Clifford algebra. This is implemented with the usual multiplication operator *, but it is also possible to use parenthetical notation as it is with real numbers.

Wedge product

The wedge product is the defining product of the exterior algebra. This is available with the wedge() function, or with the infix operator.

Tip

You can define elements of exterior algebras directly by using Metrics.Exterior(D), whose geometric product is equivalent to the wedge product.

Contractions and dot products

The contraction operations generalize the dot product of vectors to Clifford numbers. While it is possible to define a symmetric dot product (and one is provided in this package), the generalization of the dot product to Clifford numbers is naturally asymmetric in cases where the grade of one input blade is not equal to that of the other.

For Clifford numbers x and y, the left contraction x ⨼ y describes the result of projecting x onto the space spanned by y. If x and y are homogeneous in grade, this product is equal to the geometric product if grade(y) ≥ grade(x), and zero otherwise. For general multivectors, the left contraction can be calculated by applying this rule to the products of their basis blades.

The analogous right contraction is only nonzero if grade(x) ≥ grade(y), and it can be calculated with .

The dot product is a symmetric variation of the left and right contractions, and provides a looser constraint on the basis blades: grade(CliffordNumbers.dot(x,y)) must equal abs(grade(x) - grade(y)). The Hestenes dot product is equivalent to the dot product above, but is zero if either x or y is a scalar.

Note

Currently, the dot product is implemented with the unexported function CliffordNumbers.dot. This package does not depend on LinearAlgebra, so there would be a name conflict if this method were exported and both this package and LinearAlgebra were loaded.

Contractions are generally favored over the dot products due to their nicer implementations and properties, which have fewer exceptions. It is generally recommended that the Hestenes dot product be avoided, though it is included in this library for the sake of completeness as CliffordNumber.hestenes_dot, which is also not exported.

Commutator and anticommutator products

The commutator product (or antisymmetric product) of Clifford numbers x and y, denoted x × y, is equal to 1//2 * (x*y - y*x). This product is nonzero if the geometric product of x and y does not commute, and the value represents the degree to which they fail to commute.

The commutator product is the building block of Lie algebras; in particular, the commutator products of bivectors, which are also bivectors. With the bivectors of 3D space, the Lie algebra is equivalent to that generated by the cross product, hence the × notation.

The analogous anticommutator product (or symmetric product) is 1//2 * (x*y + y*x). This uses the operator, which is not an operator generally used for this purpose, but was selected as it looks similar to the commutator product, with the dot indicating the similarity with the dot product, which is also symmetric.

Defining new products: Multiplication internals

Products are implemented with the fast multiplication kernel CliffordNumbers.mul, which accepts two Clifford numbers with the same scalar type and a CliffordNumbers.GradeFilter object. This GradeFilter object defines a method that takes two or more BitIndex objects and returns false if their product is constrained to be zero.

CliffordNumbers.mul requires that the coefficient types of the numbers being multiplied are the same. Methods which leverage CliffordNumbers.mul should promote the coefficient types of the arguments to a common type using scalar_promote before passing them to the kernel. Any further promotion needed to return the final result is handled by the kernel.

In general, it is also strongly recommended to promote the types of the arguments to CliffordNumbers.Z2CliffordNumber or CliffordNumber for higher performance. Currently, the implementation of CliffordNumbers.mul is asymmetric, and does not consider which input is longer. Even in the preferred order, we find that KVector incurs a significant performance penalty.