Repository: hyrodium/BasicBSpline.jl (julia)

Issue:
equality `==` for `BSplineSpace` is not defined
```julia
julia> P1 = BSplineSpace{2}(KnotVector(1,2))
BSplineSpace{2, Float64}(KnotVector([1.0, 2.0]))

julia> P2 = BSplineSpace{2}(KnotVector(1,2))
BSplineSpace{2, Float64}(KnotVector([1.0, 2.0]))

julia> P1 == P2
false
```

Pull request description:
This PR fixes #152.

Patch:
diff --git a/src/_BSplineSpace.jl b/src/_BSplineSpace.jl
index 3e20d8870..504cad1d5 100644
--- a/src/_BSplineSpace.jl
+++ b/src/_BSplineSpace.jl
@@ -5,6 +5,10 @@ abstract type AbstractBSplineSpace{p,T} end
 # Broadcast like a scalar
 Base.Broadcast.broadcastable(P::AbstractBSplineSpace) = Ref(P)
 
+# Equality
+@inline Base.:(==)(P1::AbstractBSplineSpace{p}, P2::AbstractBSplineSpace{p}) where p = knotvector(P1) == knotvector(P2)
+@inline Base.:(==)(P1::AbstractBSplineSpace{p1}, P2::AbstractBSplineSpace{p2}) where {p1, p2} = false
+
 @doc raw"""
 Construct B-spline space from given polynominal degree and knot vector.
 ```math


Test patch:
diff --git a/test/test_BSplineSpace.jl b/test/test_BSplineSpace.jl
index 46a5f8c69..07e76021c 100644
--- a/test/test_BSplineSpace.jl
+++ b/test/test_BSplineSpace.jl
@@ -1,65 +1,90 @@
 @testset "BSplineSpace" begin
     Random.seed!(42)
 
-    P1 = BSplineSpace{2}(KnotVector([1, 3, 5, 6, 8, 9]))
-    @test bsplinesupport(P1, 2) == 3..8
-    @test dim(P1) == 3
-    @test exactdim(P1) == 3
-    @test isnondegenerate(P1) == true
-    @test isdegenerate(P1) == false
+    @testset "dimension, dengenerate" begin
+        P1 = BSplineSpace{2}(KnotVector([1, 3, 5, 6, 8, 9]))
+        @test bsplinesupport(P1, 2) == 3..8
+        @test dim(P1) == 3
+        @test exactdim(P1) == 3
+        @test isnondegenerate(P1) == true
+        @test isdegenerate(P1) == false
 
-    P2 = BSplineSpace{1}(KnotVector([1, 3, 3, 3, 8, 9]))
-    @test isnondegenerate(P2) == false
-    @test isdegenerate(P2) == true
-    @test isdegenerate(P2,1) == false
-    @test isdegenerate(P2,2) == true
-    @test isdegenerate(P2,3) == false
-    @test isdegenerate(P2,4) == false
-    @test isnondegenerate(P2,1) == true
-    @test isnondegenerate(P2,2) == false
-    @test isnondegenerate(P2,3) == true
-    @test isnondegenerate(P2,4) == true
-    @test dim(P2) == 4
-    @test exactdim(P2) == 3
+        P2 = BSplineSpace{1}(KnotVector([1, 3, 3, 3, 8, 9]))
+        @test isnondegenerate(P2) == false
+        @test isdegenerate(P2) == true
+        @test isdegenerate(P2,1) == false
+        @test isdegenerate(P2,2) == true
+        @test isdegenerate(P2,3) == false
+        @test isdegenerate(P2,4) == false
+        @test isnondegenerate(P2,1) == true
+        @test isnondegenerate(P2,2) == false
+        @test isnondegenerate(P2,3) == true
+        @test isnondegenerate(P2,4) == true
+        @test dim(P2) == 4
+        @test exactdim(P2) == 3
+    end
 
-    i = 2
-    k = KnotVector([5, 12, 13, 13, 14])
-    p = 2
-    P = BSplineSpace{p}(k)
-    @test bsplinesupport(P) == [5..13, 12..14]
-    @test bsplinesupport(P, i) == 12..14
+    @testset "support" begin
+        k = KnotVector(rand(10))
+        P = BSplineSpace{2}(k)
+        @test bsplinesupport(P) == [bsplinesupport(P, i) for i in 1:dim(P)]
+    end
 
-    @test isnondegenerate(BSplineSpace{2}(KnotVector([1, 3, 5, 6, 8, 9])))
-    @test isdegenerate(BSplineSpace{1}(KnotVector([1, 3, 3, 3, 8, 9])))
+    @testset "denegeration with lower degree" begin
+        k = KnotVector([1, 3, 3, 3, 6, 8, 9])
+        @test isnondegenerate(BSplineSpace{2}(k))
+        @test isdegenerate(BSplineSpace{1}(k))
+    end
 
-    @test dim(BSplineSpace{2}(KnotVector([1, 3, 5, 6, 8, 9]))) == 3
+    @testset "subset" begin
+        P1 = BSplineSpace{1}(KnotVector([1, 3, 5, 8]))
+        P2 = BSplineSpace{1}(KnotVector([1, 3, 5, 6, 8, 9]))
+        P3 = BSplineSpace{2}(KnotVector([1, 1, 3, 3, 5, 5, 8, 8]))
+        @test P1 ⊆ P2
+        @test P1 ⋢ P2
+        @test P1 ⊆ P3
+        @test P2 ⊈ P3
+    end
 
-    P1 = BSplineSpace{1}(KnotVector([1, 3, 5, 8]))
-    P2 = BSplineSpace{1}(KnotVector([1, 3, 5, 6, 8, 9]))
-    P3 = BSplineSpace{2}(KnotVector([1, 1, 3, 3, 5, 5, 8, 8]))
-    @test P1 ⊆ P2
-    @test P1 ⋢ P2
-    @test P1 ⊆ P3
-    @test P2 ⊈ P3
+    @testset "equality" begin
+        P1 = BSplineSpace{2}(KnotVector([1, 2, 3, 5, 8, 8, 9]))
+        P2 = BSplineSpace{2}(KnotVector([1, 2, 3, 5, 8, 8, 9]))
+        P3 = BSplineSpace{1}(KnotVector([1, 2, 3, 5, 8, 8, 9]))
+        P4 = BSplineSpace{1}(KnotVector([1, 2, 3, 5, 8, 8, 9]))
 
-    P4 = BSplineSpace{1}(KnotVector([1, 2, 3, 4, 5]))
-    P5 = BSplineSpace{2}(KnotVector([-1, 0.3, 2, 3, 3, 4, 5.2, 6]))
-    _P4 = BSplineSpace{degree(P4)-1}(knotvector(P4)[2:end-1])
-    _P5 = BSplineSpace{degree(P5)-1}(knotvector(P5)[2:end-1])
-    @test P4 ⊑ P4
-    @test P4 ⊑ P5
-    @test P5 ⊒ P4
-    @test P5 ⋢ P4
-    @test P4 ⋣ P5
-    @test (P4 ⊑ P4) == (_P4 ⊑ _P4)
-    @test (P4 ⊑ P5) == (_P4 ⊑ _P5)
-    @test (P5 ⊑ P4) == (_P5 ⊑ _P4)
+        @test P1 ⊆ P2
+        @test P2 ⊆ P1
+        @test P1 == P2
 
-    P6 = BSplineSpace{2}(KnotVector(1,2,3,4,5,6,7))
-    P7 = BSplineSpace{2}(KnotVector(0,1,3,4,5,8,9))
-    @test P6 ⊑ P7
-    @test P7 ⊑ P6
-    @test P6 ≃ P7
-    @test P6 ⊈ P7
-    @test P7 ⊈ P6
+        @test P3 ⊆ P4
+        @test P4 ⊆ P3
+        @test P3 == P4
+
+        @test P1 != P3
+    end
+
+    @testset "subset but not sqsubset" begin
+        P4 = BSplineSpace{1}(KnotVector([1, 2, 3, 4, 5]))
+        P5 = BSplineSpace{2}(KnotVector([-1, 0.3, 2, 3, 3, 4, 5.2, 6]))
+        _P4 = BSplineSpace{degree(P4)-1}(knotvector(P4)[2:end-1])
+        _P5 = BSplineSpace{degree(P5)-1}(knotvector(P5)[2:end-1])
+        @test P4 ⊑ P4
+        @test P4 ⊑ P5
+        @test P5 ⊒ P4
+        @test P5 ⋢ P4
+        @test P4 ⋣ P5
+        @test (P4 ⊑ P4) == (_P4 ⊑ _P4)
+        @test (P4 ⊑ P5) == (_P4 ⊑ _P5)
+        @test (P5 ⊑ P4) == (_P5 ⊑ _P4)
+    end
+
+    @testset "sqsubset but not subset" begin
+        P6 = BSplineSpace{2}(KnotVector(1,2,3,4,5,6,7))
+        P7 = BSplineSpace{2}(KnotVector(0,1,3,4,5,8,9))
+        @test P6 ⊑ P7
+        @test P7 ⊑ P6
+        @test P6 ≃ P7
+        @test P6 ⊈ P7
+        @test P7 ⊈ P6
+    end
 end