Skip to content

Commit

Permalink
Merge 35f2c6c into 0c68892
Browse files Browse the repository at this point in the history
  • Loading branch information
karlwessel committed Jun 10, 2019
2 parents 0c68892 + 35f2c6c commit ded8478
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 2 deletions.
21 changes: 19 additions & 2 deletions src/multivectors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ end

## Generic

import Base: isinf
export basis, grade, hasinf, hasorigin, isorigin
import Base: isinf, isapprox
export basis, grade, hasinf, hasorigin, isorigin, scalar

const VBV = Union{MValue,SValue,MBlade,SBlade,MultiVector}

Expand All @@ -337,6 +337,23 @@ const VBV = Union{MValue,SValue,MBlade,SBlade,MultiVector}
@pure hasorigin(t::Union{MValue,SValue}) = hasorigin(basis(t))
@pure hasorigin(m::TensorAlgebra) = hasorigin(vectorspace(m))

function isapprox(a::TensorMixed{T1}, b::TensorMixed{T2}) where {T1, T2}
rtol = Base.rtoldefault(T1, T2, 0)
return norm(value(a-b)) <= rtol * max(norm(value(a)), norm(value(b)))
end
isapprox(a::TensorMixed, b::TensorTerm) = isapprox(a, MultiVector(b))
isapprox(b::TensorTerm, a::TensorMixed) = isapprox(a, MultiVector(b))
isapprox(a::TensorTerm, b::TensorTerm) = isapprox(MultiVector(a), MultiVector(b))

"""
scalar(multivector)
Return the scalar (grade 0) part of any multivector.
"""
scalar(a::TensorMixed) = grade(a) == 0 ? a[1] : 0
scalar(a::MultiVector) = a[0][1]
scalar(a::TensorAlgebra) = scalar(MultiVector(a))

## MultiGrade{N}

struct MultiGrade{V} <: TensorAlgebra{V}
Expand Down
169 changes: 169 additions & 0 deletions test/generictests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@

"""
Tests based on mathematic properties of a Geometric Algebra that should pass
for any signature or field.
"""
module GenericTests
using Grassmann
using Test
using LinearAlgebra

# TODO: move tests for isapprox and scalar to a more appropriate file
# since they are no general mathematical properties of an GA
@testset "Test isapprox" begin
basis"2"

# basis
@test v v
@test v1 v1
@test v2 v2
@test v12 v12
# S/MValue
@test 2v 2v
@test 2v1 2v1
# blade
@test v1 + v2 v1 + v2
# multivector
@test v + v2 v + v2
@test v + v12 v + v12
@test v + v2 + v12 v + v2 + v12

# basis and others
@test !(v v1)
@test !(v v12)
@test !(v v1+v2)
@test !(v v1+v)
@test !(v v1+v12)
@test !(v v+v1+v12)

# S/MValue and others
@test !(2v v1)
@test !(2v v12)
@test !(2v v1+v2)
@test !(2v v1+v)
@test !(2v v1+v12)
@test !(2v v+v1+v12)

# Blade and others
@test !(v1 + v2 v1)
@test !(v1 + v2 v12)
@test !(v1 + v2 v1+v)
@test !(v1 + v2 v1+v12)
@test !(v1 + v2 v+v1+v12)

# multivector and others
@test !(v+v1+v12 v1)
@test !(v+v1+v12 v12)
@test !(v+v1+v12 v1+v)
@test !(v+v1+v12 v1+v12)
end

@testset "method: scalar" begin
basis"2"
@test scalar(v) == 1v
@test scalar(2v) == 2v
@test scalar(v1) == 0v
@test scalar(-v+v1) == -1v
@test scalar(v-v) == 0v
@test scalar(v1+v2) == 0v
end

for 𝔽 in [Float64]
e = one(𝔽)
α = rand(𝔽)
@test α*e == α
@testset "Field: $(𝔽)" begin
for G in [V"+++", S"∞+", S"∅+", V"-+++",
S"∞∅+" # is currently broken for associativity
]
@testset "Algebra: $(G)" begin
dims = ndims(G)

# all basis elements of the whole algebra
basis = collect(G)[1:end]

# all basis vectors of the generating vectorspace
basisvecs = basis[2:dims+1]

# test set of vectors
b = collect(1:dims)
B = sum(b.*basisvecs)
vectors = Any[basisvecs...]
push!(vectors, B)

# test set of multivectors
a = rand(𝔽, 2^dims)
A = sum(a.*basis)
multivectors = Any[basis...]
push!(multivectors, A)
push!(multivectors, B)

@testset "Existence of unity" begin
for A in multivectors
@test e*A == A == A*e
end
end

@testset "a² ∈ 𝔽" begin
for a in vectors
@test a^2 scalar(a^2)*basis[1]
end
end

# currently fails for S"∞∅+"
if G != S"∞∅+"
@testset "Associativity" begin
for A in multivectors,
B in multivectors,
C in multivectors

@test (A*(B*C)) ((A*B)*C)
end
end

# currently fails for S"∞∅+"
@testset "Distributivity" begin
for A in multivectors,
B in multivectors,
C in multivectors

@test A*(B + C) (A*B) + (A*C)
end
end
end

@testset "a⋅b = 0.5(ab + ba)" begin
for a in vectors, b in vectors
@test ab == 0.5*(a*b + b*a)
end
end

@testset "a∧b = 0.5(ab - ba)" begin
for a in vectors, b in vectors
@test ab == 0.5*(a*b - b*a)
end
end

@testset "ab = a⋅b + a∧b" begin
for a in vectors, b in vectors
@test a*b == ab + ab
end
end

@testset "ab = 2a⋅b - ba" begin
for a in vectors, b in vectors
@test a*b == 2*ab - b*a
end
end

@testset "aa = a⋅a" begin
for a in vectors
@test a*a == aa
end
end
end
end
end
end

end
83 changes: 83 additions & 0 deletions test/issuestests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
Unittests for issues from Github
"""
module IssuesTests

using Grassmann
using Test

@testset "Issue #19: Conformal split example" begin
@basis S"∞∅++"
@test (v∞^2, v∅^2, v1^2, v2^2) == (0v, 0v, v, v)
@test v∞ v∅ == -1v
@test v∞∅^2 == v
@test (v∞∅ * v∞, v∞∅ * v∅) == (-1v∞, v∅)
@test (v∞ * v∅, v∅ * v∞) == (-1 + 1v∞∅, -1 - 1v∞∅)
end

@testset "Issue #17: Equality between Number and MultiVector" begin
basis"2"

a = v + v1 - v1
@test a == v
@test typeof(a) <: MultiVector
@test a == 1

b = a - 1
@test b == 0
@test b == 0

@test a - 1 == 0
end

@testset "Issue #16: Adding basis vector to multivector" begin
basis"2"

A = 2v1 + v2
B = v1 + v2

@test A + B == 3v1 + 2v2
@test A == 2v1 + v2
@test B == v1 + v2

@test v1 + A == 3v1 + 1v2
@test A == 2v1 + v2
end

@testset "Issue #14: Error when adding MultiVectors" begin
basis"+++"
@test (v1+v2) + (v1+v2)*(v1+v2) == 2 + 1v1 + 1v2
end

@testset "Issue #15: generate rotation quaternions using exp" begin
basis"3"
i, j, k = hyperplanes(ℝ^3)
alpha = 0.5π

@test exp(alpha/2*(i)) == 0.7071067811865476 - 0.7071067811865475v23

a, b, c = 1/sqrt(2) * [1, 1, 0]
@test_broken exp(alpha/2*(a*i + b*j + c*k))
end

@testset "Issue #20: geometric product of null basis and negative origin" begin
@basis S"∞∅+"

@test v∅*v∞ == -1 - v∞∅
@test_broken v∅*(-v∞) == 1 + v∞∅

a = v∅*basis(-v∞)
@test a == -1 - v∞∅
@test_broken SValue{V}(-1, a)
end

@testset "Issue #22: Error in MultiVector constructor for Blades" begin
basis"++"

a = v1 + v2
@test typeof(a) <: MBlade

@test MultiVector(a) == v1 + v2
@test_broken SBlade(v) == v
end
end
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ using Test
@test Λ.V3 == Λ.C3'
@test Λ(14) + Λ(14)' == Λ(vectorspace(14)+vectorspace(14)')
@test ((a,b) = ((:a*Λ(2).v1 + :b*Λ(2).v2),(:c*Λ(2).v1 + :d*Λ(2).v2)); Algebra.:+(ab,ab)==a*b)

include("issuestests.jl")
include("generictests.jl")

0 comments on commit ded8478

Please sign in to comment.