Skip to content

Commit

Permalink
Merge pull request #12 from chakravala/diagonalform
Browse files Browse the repository at this point in the history
transitioned to DirectSum v0.2 with generalized metrics
  • Loading branch information
chakravala authored Apr 9, 2019
2 parents 2b8b2d7 + 84200a6 commit 13f84cb
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 207 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
[![Build status](https://ci.appveyor.com/api/projects/status/c36u0rgtm2rjcquk?svg=true)](https://ci.appveyor.com/project/chakravala/grassmann-jl)
[![Coverage Status](https://coveralls.io/repos/chakravala/Grassmann.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/chakravala/Grassmann.jl?branch=master)
[![codecov.io](http://codecov.io/github/chakravala/Grassmann.jl/coverage.svg?branch=master)](http://codecov.io/github/chakravala/Grassmann.jl?branch=master)
[![Gitter](https://badges.gitter.im/Grassmann-jl/community.svg)](https://gitter.im/Grassmann-jl/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/chakravala.svg)](https://liberapay.com/chakravala)

This package is a work in progress providing the necessary tools to work with arbitrary dual `MultiVector` elements with optional origin. Due to the parametric type system for the generating `VectorSpace`, the Julia compiler can fully preallocate and often cache values efficiently. Both static and mutable vector types are supported.

Expand Down Expand Up @@ -40,7 +42,7 @@ Let `N` be the dimension of a `VectorSpace{N}`.
The metric signature of the `Basis{V,1}` elements of a vector space `V` can be specified with the `V"..."` constructor by using `+` and `-` to specify whether the `Basis{V,1}` element of the corresponding index squares to `+1` or `-1`.
For example, `V"+++"` constructs a positive definite 3-dimensional `VectorSpace`.
```Julia
julia>^3 == V"+++" == VectorSpace(3)
julia>^3 == V"+++" == vectorspace(3)
true
```
The direct sum operator `` can be used to join spaces (alternatively `+`), and `'` is an involution which toggles a dual vector space with inverted signature.
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Combinatorics
StaticArrays
ComputedFieldTypes
Requires
DirectSum 0.1 0.2-
DirectSum 0.2
AbstractTensors
AbstractLattices
Reduce
123 changes: 63 additions & 60 deletions src/Grassmann.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ using Combinatorics, StaticArrays, Requires
using ComputedFieldTypes, AbstractLattices
using DirectSum, AbstractTensors

export VectorSpace, vectorspace, , ℝ, @V_str
import DirectSum: hasdual, hasorigin, dualtype, dual, value, vectorspace, V0,
export vectorspace, , ℝ, @V_str, @D_str, Signature, DiagonalForm, value
import DirectSum: hasinf, hasorigin, dualtype, dual, value, vectorspace, V0,

include("utilities.jl")
include("multivectors.jl")
Expand All @@ -24,7 +24,7 @@ export hyperplanes

abstract type SubAlgebra{V} <: TensorAlgebra{V} end

@pure adjoint(G::A) where A<:SubAlgebra{V} where V = Λ(dual(V))
adjoint(G::A) where A<:SubAlgebra{V} where V = Λ(dual(V))
@pure dual(G::A) where A<: SubAlgebra = G'
Base.firstindex(a::T) where T<:SubAlgebra = 1
Base.lastindex(a::T) where T<:SubAlgebra{V} where V = 1<<ndims(V)
Expand All @@ -42,9 +42,9 @@ Base.length(a::T) where T<:SubAlgebra{V} where V = 1<<ndims(V)
g::Dict{Symbol,Int}
end

@pure getindex(a::Algebra,i::Int) = getfield(a,:b)[i]
@pure getindex(a::Algebra,i::Colon) = getfield(a,:b)
@pure getindex(a::Algebra,i::UnitRange{Int}) = [getindex(a,j) for j i]
getindex(a::Algebra,i::Int) = getfield(a,:b)[i]
getindex(a::Algebra,i::Colon) = getfield(a,:b)
getindex(a::Algebra,i::UnitRange{Int}) = [getindex(a,j) for j i]

@pure function Base.getproperty(a::Algebra{V},v::Symbol) where V
return if v (:b,:g)
Expand All @@ -56,15 +56,15 @@ end
end
end

@pure function Base.collect(s::VectorSpace)
function Base.collect(s::VectorSpace)
sym = labels(s)
@inbounds Algebra{s}(generate(s),Dict{Symbol,Int}([sym[i]=>i for i 1:1<<ndims(s)]))
end

@pure Algebra(s::VectorSpace) = getalgebra(s)
@pure Algebra(n::Int,d::Int=0,o::Int=0,s=zero(Bits)) = getalgebra(n,d,o,s)
Algebra(s::String) = getalgebra(VectorSpace(s))
Algebra(s::String,v::Symbol) = getbasis(VectorSpace(s),v)
Algebra(s::String) = getalgebra(vectorspace(s))
Algebra(s::String,v::Symbol) = getbasis(vectorspace(s),v)

function show(io::IO,a::Algebra{V}) where V
N = ndims(V)
Expand All @@ -83,14 +83,6 @@ macro Λ_str(str)
Algebra(str)
end

@pure getalgebra(n::Int,d::Int,o::Int,s,c::Int=0) = getalgebra(n,doc2m(d,o,c),s)
@pure getalgebra(n::Int,m::Int,s) = getalgebra(n,m,Bits(s))
@pure function getalgebra(V::VectorSpace)
N,C = ndims(V),dualtype(V)
C<0 && N>2algebra_limit && (return getextended(V))
getalgebra(N,doc2m(Int(hasdual(V)),Int(hasorigin(V)),C),value(V))
end

@pure function Base.getproperty::typeof(Λ),v::Symbol)
v (:body,:var) && (return getfield(λ,v))
V = string(v)
Expand All @@ -103,20 +95,34 @@ end

# Allocating thread-safe $(2^n)×Basis{VectorSpace}
const Λ0 = Λ{V0}(SVector{1,Basis{V0}}(Basis{V0,0,zero(Bits)}()),Dict(:e=>1))
const algebra_cache = Vector{Dict{Bits,Λ}}[]
@pure function getalgebra(n::Int,m::Int,s::Bits)
n==0 && (return Λ0)
n > sparse_limit && (return getextended(n,m,s))
n > algebra_limit && (return getsparse(n,m,s))
for N length(algebra_cache)+1:n
push!(algebra_cache,[Dict{Int,Λ}() for k1:12])
end
@inbounds if !haskey(algebra_cache[n][m+1],s)
@inbounds push!(algebra_cache[n][m+1],s=>collect(VectorSpace{n,m,s}()))

for (vs,dat) ((:Signature,Bits),(:DiagonalForm,Int))
algebra_cache = Symbol(:algebra_cache_,vs)
getalg = Symbol(:getalgebra_,vs)
@eval begin
const $algebra_cache = Vector{Dict{$dat,Λ}}[]
@pure function $getalg(n::Int,m::Int,s::$dat)
n==0 && (return Λ0)
n > sparse_limit && (return $(Symbol(:getextended_,vs))(n,m,s))
n > algebra_limit && (return $(Symbol(:getsparse_,vs))(n,m,s))
for N length($algebra_cache)+1:n
push!($algebra_cache,[Dict{$dat,Λ}() for k1:12])
end
@inbounds if !haskey($algebra_cache[n][m+1],s)
@inbounds push!($algebra_cache[n][m+1],s=>collect($vs{n,m,s}()))
end
@inbounds $algebra_cache[n][m+1][s]
end
@pure function getalgebra(V::$vs{N,M,S}) where {N,M,S}
dualtype(V)<0 && N>2algebra_limit && (return getextended(V))
$(Symbol(:getalgebra_,vs))(N,M,S)
end
end
@inbounds algebra_cache[n][m+1][s]
end

@pure getalgebra(n::Int,d::Int,o::Int,s,c::Int=0) = getalgebra_Signature(n,doc2m(d,o,c),s)
@pure getalgebra(n::Int,m::Int,s) = getalgebra_Signature(n,m,Bits(s))

@pure getbasis(V::VectorSpace,v::Symbol) = getproperty(getalgebra(V),v)
@pure function getbasis(V::VectorSpace{N},b) where N
B = Bits(b)
Expand Down Expand Up @@ -162,29 +168,13 @@ end
end

@pure SparseAlgebra(n::Int,d::Int=0,o::Int=0,s=zero(Bits)) = getsparse(n,d,o,s)
SparseAlgebra(s::String) = getsparse(VectorSpace(s))
SparseAlgebra(s::String,v::Symbol) = getbasis(VectorSpace(s),v)
SparseAlgebra(s::String) = getsparse(vectorspace(s))
SparseAlgebra(s::String,v::Symbol) = getbasis(vectorspace(s),v)

function show(io::IO,a::SparseAlgebra{V}) where V
print(io,"Grassmann.SparseAlgebra{$V,$(1<<ndims(V))}($(a[1]), ..., $(a[end]))")
end

# Declaring thread-safe $(1<<n)×Basis{VectorSpace}
const sparse_cache = Vector{Dict{Bits,SparseAlgebra}}[]
@pure getsparse(n::Int,d::Int,o::Int,s,c::Int=0) = getsparse(n,doc2m(d,o,c),s)
@pure getsparse(n::Int,m::Int,s) = getsparse(n,m,Bits(s))
@pure getsparse(V::VectorSpace) = getsparse(ndims(V),do2m(Int(hasdual(V)),Int(hasorigin(V)),dualtype(V)),value(V))
@pure function getsparse(n::Int,m::Int,s::Bits)
n==0 && (return SparseAlgebra(V0))
for N length(sparse_cache)+1:n
push!(sparse_cache,[Dict{Int,SparseAlgebra}() for k1:12])
end
@inbounds if !haskey(sparse_cache[n][m+1],s)
@inbounds push!(sparse_cache[n][m+1],s=>SparseAlgebra(VectorSpace{n,m,s}()))
end
@inbounds sparse_cache[n][m+1][s]
end

## ExtendedAlgebra{V}

struct ExtendedAlgebra{V} <: SubAlgebra{V} end
Expand All @@ -200,28 +190,41 @@ struct ExtendedAlgebra{V} <: SubAlgebra{V} end
end

@pure ExtendedAlgebra(n::Int,d::Int=0,o::Int=0,s=zero(Bits)) = getextended(n,d,o,s)
ExtendedAlgebra(s::String) = getextended(VectorSpace(s))
ExtendedAlgebra(s::String,v::Symbol) = getbasis(VectorSpace(s),v)
ExtendedAlgebra(s::String) = getextended(vectorspace(s))
ExtendedAlgebra(s::String,v::Symbol) = getbasis(vectorspace(s),v)

function show(io::IO,a::ExtendedAlgebra{V}) where V
N = 1<<ndims(V)
print(io,"Grassmann.ExtendedAlgebra{$V,$N}($(getbasis(V,0)), ..., $(getbasis(V,N-1)))")
end

# Extending thread-safe $(2^n)×Basis{VectorSpace}
const extended_cache = Vector{Dict{Bits,ExtendedAlgebra}}[]
@pure getextended(n::Int,d::Int,o::Int,s,c::Int=0) = getextended(n,doc2m(d,o,c),s)
@pure getextended(n::Int,m::Int,s) = getextended(n,m,Bits(s))
@pure getextended(V::VectorSpace) = getextended(ndims(V),doc2m(Int(hasdual(V)),Int(hasorigin(V)),dualtype(V)),value(V))
@pure function getextended(n::Int,m::Int,s::Bits)
n==0 && (return ExtendedAlgebra(V0))
for N length(extended_cache)+1:n
push!(extended_cache,[Dict{Bits,ExtendedAlgebra}() for k1:12])
# Extending (2^n)×Basis{VectorSpace}

for (ExtraAlgebra,extra) ((SparseAlgebra,:sparse),(ExtendedAlgebra,:extended))
getextra = Symbol(:get,extra)
gets = Symbol(getextra,:_Signature)
for (vs,dat) ((:Signature,Bits),(:DiagonalForm,Int))
extra_cache = Symbol(extra,:_cache_,vs)
getalg = Symbol(:get,extra,:_,vs)
@eval begin
const $extra_cache = Vector{Dict{$dat,$ExtraAlgebra}}[]
@pure function $getalg(n::Int,m::Int,s::$dat)
n==0 && (return $ExtraAlgebra(V0))
for N length($extra_cache)+1:n
push!($extra_cache,[Dict{$dat,$ExtraAlgebra}() for k1:12])
end
@inbounds if !haskey($extra_cache[n][m+1],s)
@inbounds push!($extra_cache[n][m+1],s=>$ExtraAlgebra($vs{n,m,s}()))
end
@inbounds $extra_cache[n][m+1][s]
end
@pure $getextra(V::$vs{N,M,S}) where {N,M,S} = $getalg(N,M,S)
end
end
@inbounds if !haskey(extended_cache[n][m+1],s)
@inbounds push!(extended_cache[n][m+1],s=>ExtendedAlgebra(VectorSpace{n,m,s}()))
@eval begin
@pure $getextra(n::Int,d::Int,o::Int,s,c::Int=0) = $gets(n,doc2m(d,o,c),s)
@pure $getextra(n::Int,m::Int,s) = $gets(n,m,Bits(s))
end
@inbounds extended_cache[n][m+1][s]
end

# ParaAlgebra
Expand Down
Loading

0 comments on commit 13f84cb

Please sign in to comment.