Repository: hyrodium/BasicBSpline.jl (julia)

Issue:
`InexactError` with `fittingcontrolpoints`
```julia
julia> P = BSplineSpace{3}(KnotVector(1:12))
BSplineSpace{3, Int64}(KnotVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]))

julia> BasicBSpline.innerproduct_R(x->x, (P,))
ERROR: InexactError: Int64(0.17499999999999996)
Stacktrace:
 [1] Int64
   @ ./float.jl:812 [inlined]
 [2] convert
   @ ./number.jl:7 [inlined]
 [3] setindex!
   @ ./array.jl:903 [inlined]
 [4] innerproduct_I(func::var"#3#4", Ps::Tuple{BSplineSpace{3, Int64}})
   @ BasicBSpline ~/.julia/dev/BasicBSpline/src/_Fitting.jl:95
 [5] innerproduct_R(func::var"#3#4", Ps::Tuple{BSplineSpace{3, Int64}})
   @ BasicBSpline ~/.julia/dev/BasicBSpline/src/_Fitting.jl:200
 [6] top-level scope
   @ REPL[12]:1
```

Pull request description:
This PR fixes #214.

Patch:
diff --git a/src/_Fitting.jl b/src/_Fitting.jl
index c889eefa3..c270cf210 100644
--- a/src/_Fitting.jl
+++ b/src/_Fitting.jl
@@ -78,7 +78,7 @@ function innerproduct_I(func, Ps::Tuple{<:AbstractBSplineSpace{p₁}}) where {p
     l₁ = length(k₁)
     nodes₁, weights₁ = SVector{p₁+1}.(gausslegendre(p₁+1))
 
-    sample_point = func(leftendpoint(domain(P₁)))
+    sample_point = func(float(leftendpoint(domain(P₁))))
     b = Array{typeof(sample_point),1}(undef, n₁)
     fill!(b, zero(sample_point))
 
@@ -106,7 +106,7 @@ function innerproduct_I(func, Ps::Tuple{<:AbstractBSplineSpace{p₁},<:AbstractB
     nodes₁, weights₁ = SVector{p₁+1}.(gausslegendre(p₁+1))
     nodes₂, weights₂ = SVector{p₂+1}.(gausslegendre(p₂+1))
 
-    sample_point = func(leftendpoint(domain(P₁)),leftendpoint(domain(P₂)))
+    sample_point = func(float(leftendpoint(domain(P₁))),float(leftendpoint(domain(P₂))))
     b = Array{typeof(sample_point),2}(undef, n₁, n₂)
     fill!(b, zero(sample_point))
 
@@ -146,7 +146,7 @@ function innerproduct_I(func, Ps::Tuple{<:AbstractBSplineSpace{p₁},<:AbstractB
     nodes₂, weights₂ = SVector{p₂+1}.(gausslegendre(p₂+1))
     nodes₃, weights₃ = SVector{p₃+1}.(gausslegendre(p₃+1))
 
-    sample_point = func(leftendpoint(domain(P₁)),leftendpoint(domain(P₂)),leftendpoint(domain(P₃)))
+    sample_point = func(float(leftendpoint(domain(P₁))),float(leftendpoint(domain(P₂))),float(leftendpoint(domain(P₃))))
     b = Array{typeof(sample_point),3}(undef, n₁, n₂, n₃)
     fill!(b, zero(sample_point))
 


Test patch:
diff --git a/test/test_Fitting.jl b/test/test_Fitting.jl
index 5bbdb1df6..ad1379f86 100644
--- a/test/test_Fitting.jl
+++ b/test/test_Fitting.jl
@@ -226,4 +226,12 @@
             @test BasicBSpline.innerproduct_R(BSplineSpace(P)) isa Symmetric{Float64,Matrix{Float64}}
         end
     end
+
+    @testset "specific issues" begin
+        # https://github.com/hyrodium/BasicBSpline.jl/issues/214
+        P = BSplineSpace{3}(KnotVector(1:12))
+        @test BasicBSpline.innerproduct_R(t->t, (P,)) ≈ 3:10
+        @test BasicBSpline.innerproduct_R((t1,t2)->t1+t2, (P,P)) ≈ [i+j for i in 3:10, j in 3:10]
+        @test BasicBSpline.innerproduct_R((t1,t2,t3)->t1+t2+t3, (P,P,P)) ≈ [i+j+k for i in 3:10, j in 3:10, k in 3:10]
+    end
 end