Skip to content

Commit

Permalink
improved dispatch performance and deprecated MSimplex, MChain
Browse files Browse the repository at this point in the history
  • Loading branch information
chakravala committed Nov 17, 2019
1 parent 6f050d5 commit e7fd9e0
Show file tree
Hide file tree
Showing 10 changed files with 1,138 additions and 1,379 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Grassmann"
uuid = "4df31cd9-4c27-5bea-88d0-e6a7146666d8"
authors = ["Michael Reed"]
version = "0.3.3"
version = "0.4.0"

[deps]
AbstractLattices = "398f06c4-4d28-53ec-89ca-5b2656b7603d"
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ streamplot(vectorfield(exp((π/4)*(v12+v∞3)),V(2,3,4),V(1,2,3)),-1.5..1.5,-1.5
![paper/img/wave.png](paper/img/wave.png)

Due to the abstract generality of the product algebra code generation, it is possible to extend the `Grassmann` library to include additional high performance products with few extra definitions.
Operations on ultra-sparse representations for very high dimensional algebras will be gaining further performance enhancements in future updates, along with the standard lower dimensional algebras to be fully optimized.
Operations on ultra-sparse representations for very high dimensional algebras will be gaining further performance enhancements in future updates, along with hybrid optimizations for low-dimensional algebra code generation.
Thanks to the design of the product algebra code generation, any additional optimizations to the type stability will automatically enhance all the different products simultaneously.
Likewise, any new product formulas will be able to quickly gain from the setup of all of the existing optimizations.

Expand Down Expand Up @@ -205,7 +205,7 @@ Combined, the mixed-symmetry algebra yield a multi-linear propositional lattice.
The formal sum of equal `grade` elements is an oriented `Chain` and with mixed `grade` it is a `MultiVector` simplicial complex.
Thus, various standard operations on the oriented multi-sets are possible including `∪,∩,⊕` and the index operation `⊖`, which is symmetric difference operation `⊻`.
By virtue of Julia's multiple dispatch on the field type `T`, methods can specialize on the `Dimension{N}` and `Grade{G}` and `VectorBundle{N,D,O}` via the `TensorAlgebra` subtypes, such as `Basis{V,G}`, `Simplex{V,G,B,T}`, `MSimplex{V,G,B,T}`, `SChain{T,V,G}`, `MChain{T,V,G}`, `MultiVector{T,V}`, and `MultiGrade{V}` types.
By virtue of Julia's multiple dispatch on the field type `T`, methods can specialize on the `Dimension{N}` and `Grade{G}` and `VectorBundle{N,D,O}` via the `TensorAlgebra` subtypes, such as `Basis{V,G}`, `Simplex{V,G,B,T}`, `Chain{T,V,G}`, `SparseChain{V,G}`, `MultiVector{T,V}`, and `MultiGrade{V}` types.
For the oriented sets of the Grassmann exterior algebra, the parity of `(-1)^P` is factored into transposition compositions when interchanging ordering of the tensor product argument permutations.
The symmetrical algebra does not need to track this parity, but has higher multiplicities in its indices.
Expand Down Expand Up @@ -236,12 +236,12 @@ julia> v13∧v2 # exterior tensor product
julia> ans^2 # applies geometric product
1v

julia> @btime h = 2v1+v3 # vector element
julia> @btime 2v1+v3 # vector element
37.794 ns (3 allocations: 80 bytes)
2v₁ + 0v₂ + 1v₃ + 0v₄

julia> @btime $h$h # inner product
105.948 ns (2 allocations: 160 bytes)
julia> @btime $ans$ans # inner product
15.266 ns (3 allocations: 48 bytes)
-3v
```
It is entirely possible to assign multiple different bases with different signatures without any problems. In the following command, the `@basis` macro arguments are used to assign the vector space name to `S` instead of `V` and basis elements to `b` instead of `v`, so that their local names do not interfere:
Expand Down Expand Up @@ -284,17 +284,17 @@ julia> i,j,k = hyperplanes(ℝ^3)
1v₁₃
-1v₁₂

julia> @btime i^2, j^2, k^2, i*j*k
158.925 ns (5 allocations: 112 bytes)
julia> @btime $i^2, $j^2, $k^2, $i*$j*$k
0.027 ns (0 allocations: 0 bytes)
(-1v, -1v, -1v, -1v)

julia> @btime -(j+k) * (j+k)
176.233 ns (8 allocations: 240 bytes)
2
97.373 ns (4 allocations: 176 bytes)
2.0v⃖

julia> @btime -(j+k) * i
111.394 ns (6 allocations: 192 bytes)
0 - 1v₁₂ - 1v₁₃
67.695 ns (3 allocations: 144 bytes)
0.0 - 1.0v₁₂ - 1.0v₁₃
```
Alternatively, another representation of the quaternions is
```Julia
Expand Down Expand Up @@ -636,7 +636,7 @@ julia> @btime F(3)*v1
3v₁

julia> @btime inv($ans)
26.636 ns (0 allocations: 0 bytes)
14.965 ns (0 allocations: 0 bytes)
5v₁
```
By default, the coefficients are required to be `<:Number`. However, if this does not suit your needs, alternative scalar product algebras can be specified with
Expand Down
14 changes: 6 additions & 8 deletions src/Grassmann.jl
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ export ∇, Δ, ∂, d, ↑, ↓
generate_products(:(Leibniz.Operator),:svec)

@pure function (V::Signature{N})(d::Leibniz.Derivation{T,O}) where {N,T,O}
(O<1||diffvars(V)==0) && (return SChain{Int,V,1}(ones(Int,ndims(V))))
(O<1||diffvars(V)==0) && (return Chain{Int,V,1}(ones(Int,ndims(V))))
G,D,C = grade(V),diffvars(V)==1,mixedmode(V)<0
G2 = (C ? Int(G/2) : G)-1
= sum([getbasis(V,1<<(D ? G : k+G))*getbasis(V,1<<k) for k 0:G2])
Expand Down Expand Up @@ -470,8 +470,7 @@ export skeleton, 𝒫, collapse, subcomplex, chain, path
absym(t) = abs(t)
absym(t::Basis) = t
absym(t::T) where T<:TensorTerm{V,G} where {V,G} = Simplex{V,G}(absym(value(t)),basis(t))
absym(t::SChain{T,V,G}) where {T,V,G} = SChain{T,V,G}(absym.(value(t)))
absym(t::MChain{T,V,G}) where {T,V,G} = MChain{T,V,G}(absym.(value(t)))
absym(t::Chain{T,V,G}) where {T,V,G} = Chain{T,V,G}(absym.(value(t)))
absym(t::MultiVector{T,V}) where {T,V} = MultiVector{T,V}(absym.(value(t)))

collapse(a,b) = aabsym((b))
Expand All @@ -488,7 +487,7 @@ function chain(t::S,::Val{T}=Val{true}()) where S<:TensorTerm{V} where {V,T}
for k 2:G
setblade!(out,v,bit2int(indexbits(N,ind[[k-1,k]])),Dimension{N}())
end
return MChain{Int,V,2}(out)
return Chain{Int,V,2}(out)
end
path(t) = chain(t,Val{false}())

Expand Down Expand Up @@ -594,16 +593,15 @@ function __init__()
end
end
@require GeometryTypes="4d00f742-c7ba-57c2-abde-4428a4b178cb" begin
Base.convert(::Type{GeometryTypes.Point},t::T) where T<:TensorTerm{V} where V = GeometryTypes.Point(value(SChain{valuetype(t),V}(vector(t))))
Base.convert(::Type{GeometryTypes.Point},t::T) where T<:TensorTerm{V} where V = GeometryTypes.Point(value(Chain{valuetype(t),V}(vector(t))))
Base.convert(::Type{GeometryTypes.Point},t::T) where T<:TensorTerm{V,0} where V = GeometryTypes.Point(zeros(valuetype(t),ndims(V))...)
Base.convert(::Type{GeometryTypes.Point},t::T) where T<:TensorAlgebra{V} where V = GeometryTypes.Point(value(vector(t)))
Base.convert(::Type{GeometryTypes.Point},t::MChain{T,V,G}) where {T,V,G} = G == 1 ? GeometryTypes.Point(value(vector(t))) : GeometryTypes.Point(zeros(T,ndims(V))...)
Base.convert(::Type{GeometryTypes.Point},t::SChain{T,V,G}) where {T,V,G} = G == 1 ? GeometryTypes.Point(value(vector(t))) : GeometryTypes.Point(zeros(T,ndims(V))...)
Base.convert(::Type{GeometryTypes.Point},t::Chain{T,V,G}) where {T,V,G} = G == 1 ? GeometryTypes.Point(value(vector(t))) : GeometryTypes.Point(zeros(T,ndims(V))...)
GeometryTypes.Point(t::T) where T<:TensorAlgebra = convert(GeometryTypes.Point,t)
@pure ptype(::GeometryTypes.Point{N,T} where N) where T = T
export points, vectorfield
points(f,V=identity;r=-2π:0.0001:2π) = [GeometryTypes.Point(V(vector(f(t)))) for t r]
vectorfield(t,V=vectorspace(t),W=V) = p->GeometryTypes.Point(V(vector((((Vvectorspace(t))(SChain{ptype(p),W,1}(p.data)))t))))
vectorfield(t,V=vectorspace(t),W=V) = p->GeometryTypes.Point(V(vector((((Vvectorspace(t))(Chain{ptype(p),W,1}(p.data)))t))))
end
#@require AbstractPlotting="537997a7-5e4e-5d89-9595-2241ea00577e" nothing
#@require Makie="ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" nothing
Expand Down
Loading

0 comments on commit e7fd9e0

Please sign in to comment.