Skip to content

Commit

Permalink
Add methods for hash (#340)
Browse files Browse the repository at this point in the history
* add `hash(k::AbstractKnotVector, h::UInt)` method

* add `hash(k::BSplineSpace, h::UInt)` method

* add `hash(k::BSplineDerivativeSpace, h::UInt)` method

* add `hash(::BSplineManifold, ::UInt)` method

* add `hash(::RationalBSplineManifold, ::UInt)` method

* add tests for hash

* update hash methods

* update tests for hash
  • Loading branch information
hyrodium authored Nov 11, 2023
1 parent 7b5ba2b commit 4259f0c
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/_BSplineManifold.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ Base.:(==)(M1::AbstractManifold, M2::AbstractManifold) = (bsplinespaces(M1)==bsp
bsplinespaces(M::BSplineManifold) = M.bsplinespaces
controlpoints(M::BSplineManifold) = M.controlpoints

function Base.hash(M::BSplineManifold{0}, h::UInt)
hash(BSplineManifold{0}, hash(controlpoints(M), h))
end

function Base.hash(M::BSplineManifold, h::UInt)
hash(xor(hash.(bsplinespaces(M), h)...), hash(controlpoints(M), h))
end

@doc raw"""
unbounded_mapping(M::BSplineManifold{Dim}, t::Vararg{Real,Dim})
Expand Down
5 changes: 5 additions & 0 deletions src/_BSplineSpace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,8 @@ end
function expandspace(P::BSplineSpace{p,T}, k₊::AbstractKnotVector=EmptyKnotVector{T}()) where {p,T}
expandspace_I(P,k₊)
end

function Base.hash(P::BSplineSpace{p}, h::UInt) where p
k = knotvector(P)
hash(BSplineSpace{p}, hash(_vec(k), h))
end
6 changes: 6 additions & 0 deletions src/_DerivativeSpace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,9 @@ function Base.issubset(P::BSplineSpace, dP′::BSplineDerivativeSpace)
end

# TODO: Add issqsubset

function Base.hash(dP::BSplineDerivativeSpace{r,<:BSplineSpace{p}}, h::UInt) where {r,p}
P = bsplinespace(dP)
k = knotvector(P)
hash(BSplineDerivativeSpace{r,<:BSplineSpace{p}}, hash(_vec(k), h))
end
4 changes: 4 additions & 0 deletions src/_KnotVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,7 @@ KnotVector([6])
macro knotvector_str(s)
return sum(KnotVector(findall(==('0'+i), s))*i for i in 1:9)
end

function Base.hash(k::AbstractKnotVector, h::UInt)
hash(AbstractKnotVector, hash(_vec(k), h))
end
8 changes: 8 additions & 0 deletions src/_RationalBSplineManifold.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ RationalBSplineManifold(a::Array{C,Dim},w::Array{T,Dim},Ps::Vararg{BSplineSpace,

Base.:(==)(M1::RationalBSplineManifold, M2::RationalBSplineManifold) = (bsplinespaces(M1)==bsplinespaces(M2)) & (controlpoints(M1)==controlpoints(M2)) & (weights(M1)==weights(M2))

function Base.hash(M::RationalBSplineManifold{0}, h::UInt)
hash(RationalBSplineManifold{0}, hash(weights(M), hash(controlpoints(M), h)))
end

function Base.hash(M::RationalBSplineManifold, h::UInt)
hash(xor(hash.(bsplinespaces(M), h)...), hash(weights(M), hash(controlpoints(M), h)))
end

controlpoints(M::RationalBSplineManifold) = M.controlpoints
weights(M::RationalBSplineManifold) = M.weights
bsplinespaces(M::RationalBSplineManifold) = M.bsplinespaces
Expand Down
31 changes: 31 additions & 0 deletions test/test_BSplineManifold.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,37 @@
return a′
end

@testset "constructor" begin
k1 = KnotVector([0,0,1,1])
k2 = UniformKnotVector(1:8)
k3 = KnotVector(rand(8))
_k1 = KnotVector([0,0,1,1])
_k2 = KnotVector(1:8)
_k3 = copy(k3)
P1 = BSplineSpace{1}(k1)
P2 = BSplineSpace{3}(k2)
P3 = BSplineSpace{2}(k3)
_P1 = BSplineSpace{1}(_k1)
_P2 = BSplineSpace{3}(_k2)
_P3 = BSplineSpace{2}(_k3)

# 0-dim
a = fill(1.2)
@test BSplineManifold(a) == BSplineManifold(a)
@test BSplineManifold(a) == BSplineManifold(copy(a))
@test hash(BSplineManifold(a)) == hash(BSplineManifold(a))
@test hash(BSplineManifold(a)) == hash(BSplineManifold(copy(a)))

# 4-dim
a = rand(dim(P1), dim(P2), dim(P3), dim(P3))
@test BSplineManifold(a, P1, P2, P3, P3) == BSplineManifold(a, P1, P2, P3, P3)
@test hash(BSplineManifold(a, P1, P2, P3, P3)) == hash(BSplineManifold(a, P1, P2, P3, P3))
@test BSplineManifold(a, P1, P2, P3, P3) == BSplineManifold(a, _P1, _P2, _P3, _P3)
@test hash(BSplineManifold(a, P1, P2, P3, P3)) == hash(BSplineManifold(a, _P1, _P2, _P3, _P3))
@test BSplineManifold(a, P1, P2, P3, P3) == BSplineManifold(copy(a), _P1, _P2, _P3, _P3)
@test hash(BSplineManifold(a, P1, P2, P3, P3)) == hash(BSplineManifold(copy(a), _P1, _P2, _P3, _P3))
end

@testset "1dim" begin
@testset "BSplineManifold-1dim" begin
P1 = BSplineSpace{1}(KnotVector([0, 0, 1, 1]))
Expand Down
3 changes: 3 additions & 0 deletions test/test_BSplineSpace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@
@test P1 P2
@test P2 P1
@test P1 == P2
@test hash(P1) == hash(P2)

@test P3 P4
@test P4 P3
@test P3 == P4
@test hash(P3) == hash(P4)

@test P1 != P3
@test hash(P1) != hash(P3)
end

@testset "expandspace" begin
Expand Down
2 changes: 2 additions & 0 deletions test/test_Derivative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
dP7 = BSplineDerivativeSpace{2,typeof(P3)}(dP6)
@test dP1 == dP2 == dP3 != dP4
@test dP1 !== dP2
@test hash(dP1) == hash(dP2) == hash(dP3) != hash(dP4)
@test_throws MethodError BSplineDerivativeSpace{1,typeof(P2)}(dP1)
@test_throws MethodError BSplineDerivativeSpace(dP1)
@test_throws MethodError BSplineDerivativeSpace{}(dP1)
Expand All @@ -25,6 +26,7 @@
@test dP1 isa BSplineDerivativeSpace{1,<:BSplineSpace{p,T,KnotVector{T}} where {p,T}}
@test dP2 isa BSplineDerivativeSpace{1,<:UniformBSplineSpace{p,T} where {p,T}}
@test dP4 == dP5 == dP6 == dP7
@test hash(dP4) == hash(dP5) == hash(dP6) == hash(dP7)

@test dP2 == convert(BSplineDerivativeSpace,dP2)
@test dP2 == convert(BSplineDerivativeSpace{1},dP2)
Expand Down
15 changes: 14 additions & 1 deletion test/test_KnotVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
@test k1 != k2
@test k1.vector !== copy(k1).vector

@test hash(k1) == hash(KnotVector(1:3)::KnotVector{Int})
@test hash(k1) == hash(KnotVector([1,3,2])::KnotVector{Int64})
@test hash(k1) == hash(KnotVector([1,2,3])::KnotVector{Int64})
@test hash(k1) == hash(KnotVector([1,3,2])::KnotVector{Int64})
@test hash(k1) == hash(KnotVector([1.,3,2])::KnotVector{Float64})
@test hash(k1) == hash(KnotVector{Int}([1,3,2])::KnotVector{Int})
@test hash(k1) != hash(k2)

@test KnotVector{Int}([1,2]) isa KnotVector{Int}
@test KnotVector{Int}([1,2]) isa KnotVector{Int}
@test KnotVector{Int}([1,2.]) isa KnotVector{Int}
Expand Down Expand Up @@ -59,7 +67,12 @@
@test KnotVector(Float64[]) == EmptyKnotVector()
@test KnotVector(Float64[]) |> isempty
@test KnotVector(Float64[]) |> iszero
# @test KnotVector() this shold be return error

@test hash(KnotVector(Float64[])) == hash(zero(KnotVector))
@test hash(KnotVector(Float64[])) == hash(0*k1) == hash(k1*0) == hash(zero(k1))
@test hash(KnotVector(Float64[])) == hash(EmptyKnotVector())

@test_throws MethodError KnotVector()
@test EmptyKnotVector() |> isempty
@test EmptyKnotVector() |> iszero
@test EmptyKnotVector() == KnotVector(Float64[])
Expand Down
33 changes: 33 additions & 0 deletions test/test_RationalBSplineManifold.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
@testset "RationalBSplineManifold" begin
@testset "constructor" begin
k1 = KnotVector([0,0,1,1])
k2 = UniformKnotVector(1:8)
k3 = KnotVector(rand(8))
_k1 = KnotVector([0,0,1,1])
_k2 = KnotVector(1:8)
_k3 = copy(k3)
P1 = BSplineSpace{1}(k1)
P2 = BSplineSpace{3}(k2)
P3 = BSplineSpace{2}(k3)
_P1 = BSplineSpace{1}(_k1)
_P2 = BSplineSpace{3}(_k2)
_P3 = BSplineSpace{2}(_k3)

# 0-dim
a = fill(1.2)
w = fill(4.2)
@test RationalBSplineManifold(a, w) == RationalBSplineManifold(a, w)
@test RationalBSplineManifold(a, w) == RationalBSplineManifold(copy(a), copy(w))
@test hash(RationalBSplineManifold(a, w)) == hash(RationalBSplineManifold(a, w))
@test hash(RationalBSplineManifold(a, w)) == hash(RationalBSplineManifold(copy(a), copy(w)))

# 4-dim
a = rand(dim(P1), dim(P2), dim(P3), dim(P3))
w = rand(dim(P1), dim(P2), dim(P3), dim(P3))
@test RationalBSplineManifold(a, w, P1, P2, P3, P3) == RationalBSplineManifold(a, w, P1, P2, P3, P3)
@test hash(RationalBSplineManifold(a, w, P1, P2, P3, P3)) == hash(RationalBSplineManifold(a, w, P1, P2, P3, P3))
@test RationalBSplineManifold(a, w, P1, P2, P3, P3) == RationalBSplineManifold(a, w, _P1, _P2, _P3, _P3)
@test hash(RationalBSplineManifold(a, w, P1, P2, P3, P3)) == hash(RationalBSplineManifold(a, w, _P1, _P2, _P3, _P3))
@test RationalBSplineManifold(a, w, P1, P2, P3, P3) == RationalBSplineManifold(copy(a), copy(w), _P1, _P2, _P3, _P3)
@test hash(RationalBSplineManifold(a, w, P1, P2, P3, P3)) == hash(RationalBSplineManifold(copy(a), copy(w), _P1, _P2, _P3, _P3))
end

@testset "1dim-arc" begin
a = [SVector(1,0), SVector(1,1), SVector(0,1), SVector(-1,1), SVector(-1,0)]
w = [1, 1/√2, 1, 1/√2, 1]
Expand Down
5 changes: 4 additions & 1 deletion test/test_UniformBSplineSpace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@test exactdim_R(P2) == exactdim_R(P2′) == 0
@test isnondegenerate(P2) == false
@test isdegenerate(P2) == true
@test P2 == P2′
@test P2 === P2′

k3 = UniformKnotVector(1.0:0.5:12.0)
P3 = BSplineSpace{2}(k3)
Expand Down Expand Up @@ -79,6 +79,9 @@
@test P1 == P2 == P3 == P4
@test P1 != P5
@test P1 != P6
@test hash(P1) == hash(P2) == hash(P3) == hash(P4)
@test hash(P1) != hash(P5)
@test hash(P1) != hash(P6)
end

@testset "subset but not sqsubset" begin
Expand Down
8 changes: 8 additions & 0 deletions test/test_UniformKnotVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
@test k2 != 1:3
@test k1.vector === copy(k1).vector
@test k1 === copy(k1)

@test hash(k1) == hash(k1)
@test hash(k1) == hash(k2)
@test hash(k2) != hash(k3)
@test hash(k4) != hash(k3)
@test hash(k4) != hash(k2)
@test hash(k2) == hash(KnotVector(1:3))
@test hash(k2) != hash(1:3)
end

@testset "constructor, conversion" begin
Expand Down

0 comments on commit 4259f0c

Please sign in to comment.