8
8
Cubic
9
9
10
10
abstract type Degree{N} <: Flag end
11
+ abstract type DegreeBC{N} <: Degree{N} end # degree type supporting a BoundaryCondition
11
12
12
- struct BSpline{D<: Degree } <: InterpolationType end
13
- BSpline (:: D ) where {D<: Degree } = BSpline {D} ()
13
+ struct BSpline{D<: Degree } <: InterpolationType
14
+ degree:: D
15
+ end
14
16
15
17
bsplinetype (:: Type{BSpline{D}} ) where {D<: Degree } = D
16
18
bsplinetype (:: BS ) where {BS<: BSpline } = bsplinetype (BS)
17
19
18
- degree (:: BSpline{D} ) where D <: Degree = D ()
20
+ degree (mode :: BSpline ) = mode . degree
19
21
degree (:: NoInterp ) = NoInterp ()
20
22
21
- struct BSplineInterpolation{T,N,TCoefs<: AbstractArray ,IT<: DimSpec{BSpline} ,GT<: DimSpec{GridType} ,Axs<: Tuple{Vararg{AbstractUnitRange,N}} } <: AbstractInterpolation{T,N,IT,GT}
23
+ iscomplete (mode:: BSpline ) = iscomplete (degree (mode))
24
+ iscomplete (deg:: DegreeBC ) = _iscomplete (deg. bc. gt)
25
+ iscomplete (deg:: Degree ) = true
26
+ _iscomplete (:: Nothing ) = false
27
+ _iscomplete (:: GridType ) = true
28
+
29
+ function Base. show (io:: IO , bs:: BSpline )
30
+ print (io, " BSpline(" )
31
+ show (io, degree (bs))
32
+ print (io, ' )' )
33
+ end
34
+
35
+ function Base. show (io:: IO , deg:: DegreeBC )
36
+ print (io, nameof (typeof (deg)), ' (' )
37
+ show (io, deg. bc)
38
+ print (io, ' )' )
39
+ end
40
+
41
+ struct BSplineInterpolation{T,N,TCoefs<: AbstractArray ,IT<: DimSpec{BSpline} ,Axs<: Tuple{Vararg{AbstractUnitRange,N}} } <: AbstractInterpolation{T,N,IT}
22
42
coefs:: TCoefs
23
43
parentaxes:: Axs
24
44
it:: IT
25
- gt:: GT
26
45
end
27
- function BSplineInterpolation (:: Type{TWeights} , A:: AbstractArray{Tel,N} , it:: IT , gt :: GT , axs) where {N,Tel,TWeights<: Real ,IT<: DimSpec{BSpline} ,GT <: DimSpec{GridType } }
46
+ function BSplineInterpolation (:: Type{TWeights} , A:: AbstractArray{Tel,N} , it:: IT , axs) where {N,Tel,TWeights<: Real ,IT<: DimSpec{BSpline} }
28
47
# String interpolation causes allocation, noinline avoids that unless they get called
29
48
@noinline err_concrete (IT) = error (" The b-spline type must be a concrete type (was $IT )" )
30
49
@noinline warn_concrete (A) = @warn (" For performance reasons, consider using an array of a concrete type (typeof(A) == $(typeof (A)) )" )
50
+ @noinline err_incomplete (it) = error (" OnGrid/OnCell is not supplied for some of the interpolation modes in $it " )
31
51
32
52
isconcretetype (IT) || err_concrete (IT)
33
53
isconcretetype (typeof (A)) || warn_concrete (A)
54
+ iscomplete (it) || err_incomplete (it)
34
55
35
56
# Compute the output element type when positions have type TWeights
36
57
if isempty (A)
37
58
T = Base. promote_op (* , TWeights, eltype (A))
38
59
else
39
60
T = typeof (zero (TWeights) * first (A))
40
61
end
41
- BSplineInterpolation {T,N,typeof(A),IT,GT, typeof(axs)} (A, fix_axis .(axs), it, gt )
62
+ BSplineInterpolation {T,N,typeof(A),IT,typeof(axs)} (A, fix_axis .(axs), it)
42
63
end
43
64
65
+ iscomplete (its:: Tuple ) = all (iscomplete, its)
66
+
44
67
coefficients (itp:: BSplineInterpolation ) = itp. coefs
45
68
interpdegree (itp:: BSplineInterpolation ) = interpdegree (itpflag (itp))
46
69
interpdegree (:: BSpline{T} ) where T = T ()
47
70
interpdegree (it:: Tuple{Vararg{Union{BSpline,NoInterp},N}} ) where N = interpdegree .(it)
48
71
itpflag (itp:: BSplineInterpolation ) = itp. it
49
- gridflag (itp:: BSplineInterpolation ) = itp. gt
50
72
51
73
size (itp:: BSplineInterpolation ) = map (length, itp. parentaxes)
52
74
axes (itp:: BSplineInterpolation ) = itp. parentaxes
53
75
54
- lbounds (itp:: BSplineInterpolation ) = _lbounds (itp. parentaxes, itpflag (itp), gridflag (itp))
55
- ubounds (itp:: BSplineInterpolation ) = _ubounds (itp. parentaxes, itpflag (itp), gridflag (itp))
56
- _lbounds (axs, itp, gt) = (lbound (axs[1 ], getfirst (itp), getfirst (gt)), _lbounds (Base. tail (axs), getrest (itp), getrest (gt))... )
57
- _ubounds (axs, itp, gt) = (ubound (axs[1 ], getfirst (itp), getfirst (gt)), _ubounds (Base. tail (axs), getrest (itp), getrest (gt))... )
58
- _lbounds (:: Tuple{} , itp, gt) = ()
59
- _ubounds (:: Tuple{} , itp, gt) = ()
60
-
61
- # The unpadded defaults
62
- lbound (ax:: AbstractUnitRange , :: BSpline , :: OnCell ) = first (ax) - 0.5
63
- ubound (ax:: AbstractUnitRange , :: BSpline , :: OnCell ) = last (ax) + 0.5
64
- lbound (ax:: AbstractUnitRange , :: BSpline , :: OnGrid ) = first (ax)
65
- ubound (ax:: AbstractUnitRange , :: BSpline , :: OnGrid ) = last (ax)
76
+ lbounds (itp:: BSplineInterpolation ) = _lbounds (itp. parentaxes, itpflag (itp))
77
+ ubounds (itp:: BSplineInterpolation ) = _ubounds (itp. parentaxes, itpflag (itp))
78
+ _lbounds (axs, itp) = (lbound (axs[1 ], getfirst (itp)), _lbounds (Base. tail (axs), getrest (itp))... )
79
+ _ubounds (axs, itp) = (ubound (axs[1 ], getfirst (itp)), _ubounds (Base. tail (axs), getrest (itp))... )
80
+ _lbounds (:: Tuple{} , itp) = ()
81
+ _ubounds (:: Tuple{} , itp) = ()
82
+
83
+ lbound (ax:: AbstractUnitRange , bs:: BSpline ) = lbound (ax, degree (bs))
84
+ lbound (ax:: AbstractUnitRange , deg:: Degree ) = first (ax)
85
+ lbound (ax:: AbstractUnitRange , deg:: DegreeBC ) = lbound (ax, deg, deg. bc. gt)
86
+ ubound (ax:: AbstractUnitRange , bs:: BSpline ) = ubound (ax, degree (bs))
87
+ ubound (ax:: AbstractUnitRange , deg:: Degree ) = last (ax)
88
+ ubound (ax:: AbstractUnitRange , deg:: DegreeBC ) = ubound (ax, deg, deg. bc. gt)
89
+
90
+ lbound (ax:: AbstractUnitRange , :: DegreeBC , :: OnCell ) = first (ax) - 0.5
91
+ ubound (ax:: AbstractUnitRange , :: DegreeBC , :: OnCell ) = last (ax) + 0.5
92
+ lbound (ax:: AbstractUnitRange , :: DegreeBC , :: OnGrid ) = first (ax)
93
+ ubound (ax:: AbstractUnitRange , :: DegreeBC , :: OnGrid ) = last (ax)
66
94
67
95
fix_axis (r:: Base.OneTo ) = r
68
96
fix_axis (r:: Base.Slice ) = r
@@ -71,9 +99,9 @@ fix_axis(r::AbstractUnitRange) = fix_axis(UnitRange(r))
71
99
72
100
count_interp_dims (:: Type{BSI} , n) where BSI<: BSplineInterpolation = count_interp_dims (itptype (BSI), n)
73
101
74
- function interpolate (:: Type{TWeights} , :: Type{TC} , A, it:: IT , gt :: GT ) where {TWeights,TC,IT<: DimSpec{BSpline} ,GT <: DimSpec{GridType } }
75
- Apad = prefilter (TWeights, TC, A, it, gt )
76
- BSplineInterpolation (TWeights, Apad, it, gt, axes (A))
102
+ function interpolate (:: Type{TWeights} , :: Type{TC} , A, it:: IT ) where {TWeights,TC,IT<: DimSpec{BSpline} }
103
+ Apad = prefilter (TWeights, TC, A, it)
104
+ BSplineInterpolation (TWeights, Apad, it, axes (A))
77
105
end
78
106
79
107
"""
@@ -91,8 +119,8 @@ It may also be a tuple of such values, if you want to use different interpolatio
91
119
92
120
`gridstyle` should be one of `OnGrid()` or `OnCell()`.
93
121
"""
94
- function interpolate (A:: AbstractArray , it:: IT , gt :: GT ) where {IT<: DimSpec{BSpline} ,GT <: DimSpec{GridType } }
95
- interpolate (tweight (A), tcoef (A), A, it, gt )
122
+ function interpolate (A:: AbstractArray , it:: IT ) where {IT<: DimSpec{BSpline} }
123
+ interpolate (tweight (A), tcoef (A), A, it)
96
124
end
97
125
98
126
# We can't just return a tuple-of-types due to julia #12500
@@ -106,14 +134,14 @@ tcoef(A::AbstractArray{Float32}) = Float32
106
134
tcoef (A:: AbstractArray{Rational{Int}} ) = Rational{Int}
107
135
tcoef (A:: AbstractArray{T} ) where {T<: Integer } = typeof (float (zero (T)))
108
136
109
- function interpolate! (:: Type{TWeights} , A, it :: IT , gt :: GT ) where {TWeights,IT<: DimSpec{BSpline} ,GT <: DimSpec{GridType } }
137
+ function interpolate! (:: Type{TWeights} , A:: AbstractArray , it :: IT ) where {TWeights,IT<: DimSpec{BSpline} }
110
138
# Set the bounds of the interpolant inward, if necessary
111
139
axsA = axes (A)
112
140
axspad = padded_axes (axsA, it)
113
- BSplineInterpolation (TWeights, prefilter! (TWeights, A, it, gt ), it, gt , fix_axis .(padinset .(axsA, axspad)))
141
+ BSplineInterpolation (TWeights, prefilter! (TWeights, A, it), it, fix_axis .(padinset .(axsA, axspad)))
114
142
end
115
- function interpolate! (A:: AbstractArray , it:: IT , gt :: GT ) where {IT<: DimSpec{BSpline} ,GT <: DimSpec{GridType } }
116
- interpolate! (tweight (A), A, it, gt )
143
+ function interpolate! (A:: AbstractArray , it:: IT ) where {IT<: DimSpec{BSpline} }
144
+ interpolate! (tweight (A), A, it)
117
145
end
118
146
119
147
lut! (dl, d, du) = lu! (Tridiagonal (dl, d, du), Val (false ))
0 commit comments