Repository: hyrodium/BasicBSpline.jl
Pull request #127 (2021-12-30 06:00:55)

Update type promotions in `bsplinebasis`
Before this PR
```julia
julia> p = 3
3

julia> k = KnotVector{Int}(1:12)
KnotVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

julia> P = BSplineSpace{p}(k)
BSplineSpace{3, Int64}(KnotVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]))

julia> bsplinebasis(P,1,11//5)
ERROR: MethodError: no method matching bsplinebasis(::BSplineSpace{3, Int64}, ::Int64, ::Rational{Int64})
Closest candidates are:
  bsplinebasis(::BSplineSpace{p, T}, ::Integer, ::T) where {p, T} at ~/.julia/dev/BasicBSpline/src/_BSplineBasis.jl:107
  bsplinebasis(::BSplineDerivativeSpace{r, BSplineSpace{p, T}}, ::Integer, ::Real) where {r, p, T} at ~/.julia/dev/BasicBSpline/src/_DerivativeBasis.jl:73
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

julia> bsplinebasis(P,2,16//5)
ERROR: MethodError: no method matching bsplinebasis(::BSplineSpace{3, Int64}, ::Int64, ::Rational{Int64})
Closest candidates are:
  bsplinebasis(::BSplineSpace{p, T}, ::Integer, ::T) where {p, T} at ~/.julia/dev/BasicBSpline/src/_BSplineBasis.jl:107
  bsplinebasis(::BSplineDerivativeSpace{r, BSplineSpace{p, T}}, ::Integer, ::Real) where {r, p, T} at ~/.julia/dev/BasicBSpline/src/_DerivativeBasis.jl:73
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1
```

After this PR
```julia
julia> p = 3
3

julia> k = KnotVector{Int}(1:12)
KnotVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

julia> P = BSplineSpace{p}(k)
BSplineSpace{3, Int64}(KnotVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]))

julia> bsplinebasis(P,1,11//5)
106//375

julia> bsplinebasis(P,2,16//5)
106//375
```


Patch:
diff --git a/docs/src/assets/logo-dark.svg b/docs/src/assets/logo-dark.svg
deleted file mode 100644
index c4da0c1c..00000000
--- a/docs/src/assets/logo-dark.svg
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   inkscape:export-ydpi="96"
-   inkscape:export-xdpi="96"
-   inkscape:export-filename="/home/hyrodium/.julia/dev/BasicBSpline/docs/src/assets/logo.png"
-   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
-   sodipodi:docname="logo-dark.svg"
-   id="svg15"
-   version="1.1"
-   viewBox="0 0 500 500"
-   height="500pt"
-   width="500pt"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:dc="http://purl.org/dc/elements/1.1/">
-  <metadata
-     id="metadata21">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs19" />
-  <sodipodi:namedview
-     inkscape:snap-center="true"
-     inkscape:snap-object-midpoints="true"
-     inkscape:snap-midpoints="true"
-     inkscape:snap-smooth-nodes="true"
-     inkscape:snap-intersection-paths="true"
-     inkscape:object-paths="true"
-     inkscape:current-layer="svg15"
-     inkscape:window-maximized="1"
-     inkscape:window-y="0"
-     inkscape:window-x="0"
-     inkscape:cy="658.24645"
-     inkscape:cx="64.886526"
-     inkscape:zoom="1.2791562"
-     showgrid="false"
-     id="namedview17"
-     inkscape:window-height="2095"
-     inkscape:window-width="3840"
-     inkscape:pageshadow="2"
-     inkscape:pageopacity="0"
-     guidetolerance="10"
-     gridtolerance="10"
-     objecttolerance="10"
-     borderopacity="1"
-     bordercolor="#666666"
-     pagecolor="#ffffff"
-     inkscape:pagecheckerboard="0"
-     inkscape:document-units="pt" />
-  <path
-     style="fill:none;stroke:#4063d8;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25,470.17522 c 18.51288,0 37.008413,-74.03519 55.521267,-222.08765 C 99.034159,100.03498 117.52964,58.185419 136.04254,122.55585 202.66804,354.30772 269.29363,470.17522 335.9191,470.17522 h 133.25105"
-     id="path12"
-     sodipodi:nodetypes="cscsc" />
-  <path
-     style="fill:none;stroke:#cb3c33;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25.000063,470.17522 h 55.521256 c 18.5129,0 37.008451,-32.18532 55.521221,-96.55619 66.62559,-231.75191 133.25115,-199.56658 199.87656,96.55619 h 133.25117"
-     id="path61"
-     sodipodi:nodetypes="csccc" />
-  <path
-     style="fill:none;stroke:#389826;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25.000025,470.17522 h 55.521242 55.521243 c 66.62556,0 133.25114,-148.05269 199.87654,-444.17522 44.41707,296.12253 88.83409,444.17522 133.25114,444.17522"
-     id="path110"
-     sodipodi:nodetypes="ccscc" />
-  <path
-     style="fill:none;stroke:#9558b2;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="M 25,470.17522 H 80.521267 136.04254 335.9191 c 44.41702,-296.12277 88.83404,-296.12277 133.25109,0"
-     id="path159"
-     sodipodi:nodetypes="ccccc" />
-  <path
-     inkscape:transform-center-x="3.1348776"
-     id="path71-3-5"
-     d="m 136.04251,453.20671 v 33.93702"
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 80.521267,453.20671 v 33.93702"
-     id="path71-3-5-6"
-     inkscape:transform-center-x="3.1348798"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     inkscape:transform-center-x="3.1348811"
-     id="path71-3-5-6-2"
-     d="m 25,453.20671 v 33.93702"
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 330.08938,453.20671 v 33.93702"
-     id="path71-3-5-1"
-     inkscape:transform-center-x="3.1348765"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     inkscape:transform-center-x="3.1348712"
-     id="path71-3-5-1-2"
-     d="m 341.74892,453.20671 v 33.93702"
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     inkscape:transform-center-x="3.1348774"
-     id="path71-3-5-1-0"
-     d="m 463.34047,453.20671 v 33.93702"
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
-  <path
-     style="fill:none;stroke:#ffffff;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 475.00001,453.20671 v 33.93702"
-     id="path71-3-5-1-2-9"
-     inkscape:transform-center-x="3.1348721"
-     inkscape:transform-center-y="1.1654046e-05" />
-</svg>
diff --git a/docs/src/assets/logo.svg b/docs/src/assets/logo.svg
index 4a7b80a8..89e3cf0c 100644
--- a/docs/src/assets/logo.svg
+++ b/docs/src/assets/logo.svg
@@ -1,22 +1,22 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    inkscape:export-ydpi="96"
    inkscape:export-xdpi="96"
    inkscape:export-filename="/home/hyrodium/.julia/dev/BasicBSpline/docs/src/assets/logo.png"
-   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+   inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
    sodipodi:docname="logo.svg"
    id="svg15"
    version="1.1"
    viewBox="0 0 500 500"
    height="500pt"
-   width="500pt"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:dc="http://purl.org/dc/elements/1.1/">
+   width="500pt">
   <metadata
      id="metadata21">
     <rdf:RDF>
@@ -38,16 +38,16 @@
      inkscape:snap-intersection-paths="true"
      inkscape:object-paths="true"
      inkscape:current-layer="svg15"
-     inkscape:window-maximized="1"
-     inkscape:window-y="0"
-     inkscape:window-x="0"
-     inkscape:cy="499.54807"
-     inkscape:cx="164.17073"
-     inkscape:zoom="1.2791562"
+     inkscape:window-maximized="0"
+     inkscape:window-y="587"
+     inkscape:window-x="363"
+     inkscape:cy="357.89304"
+     inkscape:cx="387.09098"
+     inkscape:zoom="0.9045"
      showgrid="false"
      id="namedview17"
-     inkscape:window-height="2095"
-     inkscape:window-width="3840"
+     inkscape:window-height="1138"
+     inkscape:window-width="1402"
      inkscape:pageshadow="2"
      inkscape:pageopacity="0"
      guidetolerance="10"
@@ -55,69 +55,60 @@
      objecttolerance="10"
      borderopacity="1"
      bordercolor="#666666"
-     pagecolor="#ffffff"
-     inkscape:pagecheckerboard="0"
-     inkscape:document-units="pt" />
+     pagecolor="#ffffff" />
   <path
-     style="fill:none;stroke:#4063d8;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25,470.17522 c 18.51288,0 37.008413,-74.03519 55.521267,-222.08765 C 99.034159,100.03498 117.52964,58.185419 136.04254,122.55585 202.66804,354.30772 269.29363,470.17522 335.9191,470.17522 h 133.25105"
+     style="fill:none;stroke:#4063d8;stroke-width:21.4309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+     d="m 35.715211,464.28427 c 17.862625,0 35.708512,-71.43474 53.571112,-214.28694 C 107.14896,107.14501 124.9948,66.765396 142.85744,128.87485 c 64.28532,223.61171 128.57072,335.40942 192.856,335.40942 h 128.57068"
      id="path12"
      sodipodi:nodetypes="cscsc" />
   <path
-     style="fill:none;stroke:#cb3c33;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25.000063,470.17522 h 55.521256 c 18.5129,0 37.008451,-32.18532 55.521221,-96.55619 66.62559,-231.75191 133.25115,-199.56658 199.87656,96.55619 h 133.25117"
+     style="fill:none;stroke:#cb3c33;stroke-width:21.4309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+     d="m 35.715271,464.28427 h 53.571102 c 17.862647,0 35.708547,-31.05482 53.571067,-93.1647 64.2854,-223.61175 128.57078,-192.55691 192.856,93.1647 h 128.5708"
      id="path61"
      sodipodi:nodetypes="csccc" />
   <path
-     style="fill:none;stroke:#389826;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="m 25.000025,470.17522 h 55.521242 55.521243 c 66.62556,0 133.25114,-148.05269 199.87654,-444.17522 44.41707,296.12253 88.83409,444.17522 133.25114,444.17522"
+     style="fill:none;stroke:#389826;stroke-width:21.4309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+     d="m 35.715235,464.28427 h 53.571088 53.571087 c 64.28537,0 128.57077,-142.85241 192.85599,-428.573798 42.85694,285.721388 85.71384,428.573798 128.57076,428.573798"
      id="path110"
      sodipodi:nodetypes="ccscc" />
   <path
-     style="fill:none;stroke:#9558b2;stroke-width:30;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
-     d="M 25,470.17522 H 80.521267 136.04254 335.9191 c 44.41702,-296.12277 88.83404,-296.12277 133.25109,0"
+     style="fill:none;stroke:#9558b2;stroke-width:21.4309;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+     d="m 35.715211,464.28427 h 53.571112 53.571117 192.856 c 42.8569,-285.72161 85.7138,-285.72161 128.57072,0"
      id="path159"
      sodipodi:nodetypes="ccccc" />
   <path
-     inkscape:transform-center-x="3.1348776"
+     inkscape:transform-center-x="3.0247701"
      id="path71-3-5"
-     d="m 136.04251,453.20671 v 33.93702"
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
+     d="m 142.85741,447.91177 v 32.745"
+     style="fill:none;stroke:#000000;stroke-width:7.49999977;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
   <path
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 80.521267,453.20671 v 33.93702"
+     style="fill:none;stroke:#000000;stroke-width:7.49999977;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 89.286323,447.91177 v 32.745"
      id="path71-3-5-6"
-     inkscape:transform-center-x="3.1348798"
-     inkscape:transform-center-y="1.1654046e-05" />
+     inkscape:transform-center-x="3.0247701" />
   <path
-     inkscape:transform-center-x="3.1348811"
+     inkscape:transform-center-x="3.0247701"
      id="path71-3-5-6-2"
-     d="m 25,453.20671 v 33.93702"
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
+     d="m 35.715211,447.91177 v 32.745"
+     style="fill:none;stroke:#000000;stroke-width:7.49999977;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
   <path
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 330.08938,453.20671 v 33.93702"
+     style="fill:none;stroke:#000000;stroke-width:7.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 330.08849,447.91177 v 32.745"
      id="path71-3-5-1"
-     inkscape:transform-center-x="3.1348765"
-     inkscape:transform-center-y="1.1654046e-05" />
+     inkscape:transform-center-x="3.0247701" />
   <path
-     inkscape:transform-center-x="3.1348712"
+     inkscape:transform-center-x="3.0247701"
      id="path71-3-5-1-2"
-     d="m 341.74892,453.20671 v 33.93702"
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
+     d="m 341.33849,447.91177 v 32.745"
+     style="fill:none;stroke:#000000;stroke-width:7.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
   <path
-     inkscape:transform-center-x="3.1348774"
+     inkscape:transform-center-x="3.0247701"
      id="path71-3-5-1-0"
-     d="m 463.34047,453.20671 v 33.93702"
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     inkscape:transform-center-y="1.1654046e-05" />
+     d="m 458.65921,447.91177 v 32.745"
+     style="fill:none;stroke:#000000;stroke-width:7.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
   <path
-     style="fill:none;stroke:#000000;stroke-width:9;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-     d="m 475.00001,453.20671 v 33.93702"
+     style="fill:none;stroke:#000000;stroke-width:7.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 469.90921,447.91177 v 32.745"
      id="path71-3-5-1-2-9"
-     inkscape:transform-center-x="3.1348721"
-     inkscape:transform-center-y="1.1654046e-05" />
+     inkscape:transform-center-x="3.0247701" />
 </svg>
diff --git a/src/_BSplineBasis.jl b/src/_BSplineBasis.jl
index 7ea80be5..136b2c1f 100644
--- a/src/_BSplineBasis.jl
+++ b/src/_BSplineBasis.jl
@@ -1,6 +1,7 @@
 # B-Spline Basis Function
 
 @inline _d(a::T,b::T) where T = ifelse(iszero(b), zero(T), T(a/b))
+@inline _d(a,b) = _d(promote(a,b)...)
 
 @doc raw"""
 ``i``-th B-spline basis function.
@@ -19,7 +20,8 @@ Right-sided limit version.
 \end{cases}
 \end{aligned}
 """
-@generated function bsplinebasis₊₀(P::BSplineSpace{p,T}, i::Integer, t::T) where {p, T}
+@generated function bsplinebasis₊₀(P::BSplineSpace{p,T}, i::Integer, t::S) where {p, T, S<:Real}
+    U = promote_type(T,S)
     ks = [Symbol(:k,i) for i in 1:p+2]
     Ks = [Symbol(:K,i) for i in 1:p+1]
     Bs = [Symbol(:B,i) for i in 1:p+1]
@@ -27,7 +29,7 @@ Right-sided limit version.
     k_r = Expr(:tuple, :(v[i]), (:(v[i+$j]) for j in 1:p+1)...)
     K_l(n) = Expr(:tuple, Ks[1:n]...)
     B_l(n) = Expr(:tuple, Bs[1:n]...)
-    A_r(n) = Expr(:tuple, [:(T($(ks[i])≤t<$(ks[i+1]))) for i in 1:n]...)
+    A_r(n) = Expr(:tuple, [:($U($(ks[i])≤t<$(ks[i+1]))) for i in 1:n]...)
     K_r(m,n) = Expr(:tuple, [:(_d(t-$(ks[i]),$(ks[i+m])-$(ks[i]))) for i in 1:n]...)
     B_r(n) = Expr(:tuple, [:($(Ks[i])*$(Bs[i])+(1-$(Ks[i+1]))*$(Bs[i+1])) for i in 1:n]...)
     exs = Expr[]
@@ -61,7 +63,8 @@ Left-sided limit version.
 \end{cases}
 \end{aligned}
 """
-@generated function bsplinebasis₋₀(P::BSplineSpace{p,T}, i::Integer, t::T) where {p, T}
+@generated function bsplinebasis₋₀(P::BSplineSpace{p,T}, i::Integer, t::S) where {p, T, S<:Real}
+    U = promote_type(T,S)
     ks = [Symbol(:k,i) for i in 1:p+2]
     Ks = [Symbol(:K,i) for i in 1:p+1]
     Bs = [Symbol(:B,i) for i in 1:p+1]
@@ -69,7 +72,7 @@ Left-sided limit version.
     k_r = Expr(:tuple, :(v[i]), (:(v[i+$j]) for j in 1:p+1)...)
     K_l(n) = Expr(:tuple, Ks[1:n]...)
     B_l(n) = Expr(:tuple, Bs[1:n]...)
-    A_r(n) = Expr(:tuple, [:(T($(ks[i])<t≤$(ks[i+1]))) for i in 1:n]...)
+    A_r(n) = Expr(:tuple, [:($U($(ks[i])<t≤$(ks[i+1]))) for i in 1:n]...)
     K_r(m,n) = Expr(:tuple, [:(_d(t-$(ks[i]),$(ks[i+m])-$(ks[i]))) for i in 1:n]...)
     B_r(n) = Expr(:tuple, [:($(Ks[i])*$(Bs[i])+(1-$(Ks[i+1]))*$(Bs[i+1])) for i in 1:n]...)
     exs = Expr[]
@@ -104,7 +107,8 @@ Modified version.
 \end{cases}
 \end{aligned}
 """
-@generated function bsplinebasis(P::BSplineSpace{p,T}, i::Integer, t::T) where {p, T}
+@generated function bsplinebasis(P::BSplineSpace{p,T}, i::Integer, t::S) where {p, T, S<:Real}
+    U = promote_type(T,S)
     ks = [Symbol(:k,i) for i in 1:p+2]
     Ks = [Symbol(:K,i) for i in 1:p+1]
     Bs = [Symbol(:B,i) for i in 1:p+1]
@@ -112,7 +116,7 @@ Modified version.
     k_r = Expr(:tuple, :(v[i]), (:(v[i+$j]) for j in 1:p+1)...)
     K_l(n) = Expr(:tuple, Ks[1:n]...)
     B_l(n) = Expr(:tuple, Bs[1:n]...)
-    A_r(n) = Expr(:tuple, [:(T($(ks[i])≤t<$(ks[i+1]))) for i in 1:n]...)
+    A_r(n) = Expr(:tuple, [:($U($(ks[i])≤t<$(ks[i+1]))) for i in 1:n]...)
     K_r(m,n) = Expr(:tuple, [:(_d(t-$(ks[i]),$(ks[i+m])-$(ks[i]))) for i in 1:n]...)
     B_r(n) = Expr(:tuple, [:($(Ks[i])*$(Bs[i])+(1-$(Ks[i+1]))*$(Bs[i+1])) for i in 1:n]...)
     exs = Expr[]
@@ -124,7 +128,7 @@ Modified version.
         :(v = knotvector(P).vector),
         :($k_l = $k_r),
         :($(B_l(p+1)) = $(A_r(p+1))),
-        :($(Bs[end]) += $(T)(t == $(ks[end]) == v[end])),
+        :($(Bs[end]) += $(U)(t == $(ks[end]) == v[end])),
         exs...,
         :(return B1)
     )
@@ -137,18 +141,19 @@ bsplinebasisall
 
 # TODO: faster implementation
 # TODO: use @generated macro
-@inline function bsplinebasisall(P::BSplineSpace{0,T},i::Integer,t::T) where T
-    (one(T),)
+@inline function bsplinebasisall(P::BSplineSpace{0,T},i::Integer,t::S) where {T, S<:Real}
+    U = promote_type(T,S)
+    (one(U),)
 end
 
-@inline function bsplinebasisall(P::BSplineSpace{1,T}, i::Integer, t::T) where T
+@inline function bsplinebasisall(P::BSplineSpace{1}, i::Integer, t::Real)
     k = knotvector(P)
     B1 = (k[i+2]-t)/(k[i+2]-k[i+1])
     B2 = (t-k[i+1])/(k[i+2]-k[i+1])
     return (B1, B2)
 end
 
-@generated function bsplinebasisall(P::BSplineSpace{p,T}, i::Integer, t::T) where {p, T}
+@generated function bsplinebasisall(P::BSplineSpace{p}, i::Integer, t::Real) where p
     bs = [Symbol(:b,i) for i in 1:p]
     Bs = [Symbol(:B,i) for i in 1:p+1]
     K1s = [:((k[i+$(p+j)]-t)/(k[i+$(p+j)]-k[i+$(j)])) for j in 1:p]


Test patch:
diff --git a/test/test_BSplineBasis.jl b/test/test_BSplineBasis.jl
index 265e6a1d..f1abe9d6 100644
--- a/test/test_BSplineBasis.jl
+++ b/test/test_BSplineBasis.jl
@@ -85,4 +85,13 @@ end
             end
         end
     end
+
+    @testset "Rational" begin
+        k = KnotVector{Int}(1:12)
+        P = BSplineSpace{3}(k)
+        @test k isa KnotVector{Int}
+        @test P isa BSplineSpace{3,Int}
+        @test bsplinebasis(P,1,11//5) isa Rational{Int}
+        @test bsplinebasis(P,1,11//5) === bsplinebasis(P,2,16//5) === 106//375
+    end
 end