@@ -30,10 +30,10 @@ export
30
30
# scaling/scaling.jl
31
31
32
32
using LinearAlgebra, SparseArrays
33
- using WoodburyMatrices, Ratios, AxisAlgorithms, OffsetArrays
33
+ using StaticArrays, WoodburyMatrices, Ratios, AxisAlgorithms, OffsetArrays
34
34
35
- import Base: convert, size, axes, getindex, promote_rule,
36
- ndims, eltype, checkbounds
35
+ using Base: @propagate_inbounds
36
+ import Base : convert, size, axes, promote_rule, ndims, eltype, checkbounds
37
37
38
38
abstract type Flag end
39
39
abstract type InterpolationType <: Flag end
@@ -48,57 +48,183 @@ abstract type AbstractInterpolation{T,N,IT<:DimSpec{InterpolationType},GT<:DimSp
48
48
abstract type AbstractInterpolationWrapper{T,N,ITPT,IT,GT} <: AbstractInterpolation{T,N,IT,GT} end
49
49
abstract type AbstractExtrapolation{T,N,ITPT,IT,GT} <: AbstractInterpolationWrapper{T,N,ITPT,IT,GT} end
50
50
51
- struct Throw <: Flag end
52
- struct Flat <: Flag end
53
- struct Line <: Flag end
54
- struct Free <: Flag end
55
- struct Periodic <: Flag end
56
- struct Reflect <: Flag end
57
- struct InPlace <: Flag end
51
+ """
52
+ BoundaryCondition
53
+
54
+ An abstract type with one of the following values (see the help for each for details):
55
+
56
+ - `Throw()`
57
+ - `Flat()`
58
+ - `Line()`
59
+ - `Free()`
60
+ - `Periodic()`
61
+ - `Reflect()`
62
+ - `InPlace()`
63
+ - `InPlaceQ()`
64
+ """
65
+ abstract type BoundaryCondition <: Flag end
66
+ struct Throw <: BoundaryCondition end
67
+ struct Flat <: BoundaryCondition end
68
+ struct Line <: BoundaryCondition end
69
+ struct Free <: BoundaryCondition end
70
+ struct Periodic <: BoundaryCondition end
71
+ struct Reflect <: BoundaryCondition end
72
+ struct InPlace <: BoundaryCondition end
58
73
# InPlaceQ is exact for an underlying quadratic. This is nice for ground-truth testing
59
74
# of in-place (unpadded) interpolation.
60
- struct InPlaceQ <: Flag end
75
+ struct InPlaceQ <: BoundaryCondition end
61
76
const Natural = Line
62
77
63
- @generated size (itp:: AbstractInterpolation{T,N} ) where {T, N} = Expr (:tuple , [:(size (itp, $ i)) for i in 1 : N]. .. )
64
- size (exp:: AbstractExtrapolation , d) = size (exp. itp, d)
65
- bounds (itp:: AbstractInterpolation{T,N} ) where {T,N} = tuple (zip (lbounds (itp), ubounds (itp))... )
66
- bounds (itp:: AbstractInterpolation{T,N} , d) where {T,N} = (lbound (itp,d),ubound (itp,d))
67
- @generated lbounds (itp:: AbstractInterpolation{T,N} ) where {T,N} = Expr (:tuple , [:(lbound (itp, $ i)) for i in 1 : N]. .. )
68
- @generated ubounds (itp:: AbstractInterpolation{T,N} ) where {T,N} = Expr (:tuple , [:(ubound (itp, $ i)) for i in 1 : N]. .. )
69
- lbound (itp:: AbstractInterpolation{T,N} , d) where {T,N} = 1
70
- ubound (itp:: AbstractInterpolation{T,N} , d) where {T,N} = size (itp, d)
78
+ Base. IndexStyle (:: Type{<:AbstractInterpolation} ) = IndexCartesian ()
79
+
80
+ size (itp:: AbstractInterpolation ) = map (length, itp. parentaxes)
81
+ size (exp:: AbstractExtrapolation ) = size (exp. itp)
82
+ axes (itp:: AbstractInterpolation ) = itp. parentaxes
83
+ axes (exp:: AbstractExtrapolation ) = axes (exp. itp)
84
+
85
+ bounds (itp:: AbstractInterpolation ) = map (twotuple, lbounds (itp), ubounds (itp))
86
+ twotuple (r:: AbstractUnitRange ) = (first (r), last (r))
87
+ twotuple (x, y) = (x, y)
88
+ bounds (itp:: AbstractInterpolation , d) = bounds (itp)[d]
89
+ lbounds (itp:: AbstractInterpolation ) = _lbounds (itp. parentaxes, itpflag (itp), gridflag (itp))
90
+ ubounds (itp:: AbstractInterpolation ) = _ubounds (itp. parentaxes, itpflag (itp), gridflag (itp))
91
+ _lbounds (axs:: NTuple{N,Any} , itp, gt) where N = ntuple (d-> lbound (axs[d], iextract (itp,d), iextract (gt,d)), Val (N))
92
+ _ubounds (axs:: NTuple{N,Any} , itp, gt) where N = ntuple (d-> ubound (axs[d], iextract (itp,d), iextract (gt,d)), Val (N))
93
+
71
94
itptype (:: Type{AbstractInterpolation{T,N,IT,GT}} ) where {T,N,IT<: DimSpec{InterpolationType} ,GT<: DimSpec{GridType} } = IT
72
95
itptype (:: Type{ITP} ) where {ITP<: AbstractInterpolation } = itptype (supertype (ITP))
73
- itptype (itp:: AbstractInterpolation ) = itptype (typeof (itp))
96
+ itptype (itp:: AbstractInterpolation ) = itptype (typeof (itp))
97
+ itpflag (itp:: AbstractInterpolation ) = itp. it
74
98
gridtype (:: Type{AbstractInterpolation{T,N,IT,GT}} ) where {T,N,IT<: DimSpec{InterpolationType} ,GT<: DimSpec{GridType} } = GT
75
99
gridtype (:: Type{ITP} ) where {ITP<: AbstractInterpolation } = gridtype (supertype (ITP))
76
100
gridtype (itp:: AbstractInterpolation ) = gridtype (typeof (itp))
101
+ gridflag (itp:: AbstractInterpolation ) = itp. gt
77
102
ndims (:: Type{AbstractInterpolation{T,N,IT,GT}} ) where {T,N,IT<: DimSpec{InterpolationType} ,GT<: DimSpec{GridType} } = N
78
103
ndims (:: Type{ITP} ) where {ITP<: AbstractInterpolation } = ndims (supertype (ITP))
79
104
ndims (itp:: AbstractInterpolation ) = ndims (typeof (itp))
80
105
eltype (:: Type{AbstractInterpolation{T,N,IT,GT}} ) where {T,N,IT<: DimSpec{InterpolationType} ,GT<: DimSpec{GridType} } = T
81
106
eltype (:: Type{ITP} ) where {ITP<: AbstractInterpolation } = eltype (supertype (ITP))
82
107
eltype (itp:: AbstractInterpolation ) = eltype (typeof (itp))
83
- count_interp_dims (:: Type{T} , N) where {T<: AbstractInterpolation } = N
84
108
85
- # Generic indexing methods (fixes #183)
86
- Base. to_index (:: AbstractInterpolation , i:: Real ) = i
109
+ """
110
+ n = count_interp_dims(ITP)
111
+
112
+ Count the number of dimensions along which type `ITP` is interpolating.
113
+ `NoInterp` dimensions do not contribute to the sum.
114
+ """
115
+ count_interp_dims (:: Type{ITP} ) where {ITP<: AbstractInterpolation } = count_interp_dims (itptype (ITP), ndims (ITP))
116
+ count_interp_dims (:: Type{IT} , n) where {IT<: InterpolationType } = n * count_interp_dims (IT)
117
+ count_interp_dims (it:: Type{IT} , n) where IT<: Tuple{Vararg{InterpolationType,N}} where N =
118
+ _count_interp_dims (0 , it... )
119
+ @inline _count_interp_dims (c, :: IT1 , args... ) where IT1 =
120
+ _count_interp_dims (c + count_interp_dims (IT1), args... )
121
+ _count_interp_dims (c) = c
122
+
123
+ """
124
+ w = value_weights(degree, δx)
125
+
126
+ Compute the weights for interpolation of the value at an offset `δx` from the "base" position.
127
+ `degree` describes the interpolation scheme.
128
+
129
+ # Example
130
+
131
+ ```jldoctest
132
+ julia> Interpolations.value_weights(Linear(), 0.2)
133
+ (0.8, 0.2)
134
+ ```
135
+
136
+ This corresponds to the fact that linear interpolation at `x + 0.2` is `0.8*y[x] + 0.2*y[x+1]`.
137
+ """
138
+ function value_weights end
139
+
140
+ """
141
+ w = gradient_weights(degree, δx)
142
+
143
+ Compute the weights for interpolation of the gradient at an offset `δx` from the "base" position.
144
+ `degree` describes the interpolation scheme.
145
+
146
+ # Example
147
+
148
+ ```jldoctest
149
+ julia> Interpolations.gradient_weights(Linear(), 0.2)
150
+ (-1.0, 1.0)
151
+ ```
152
+
153
+ This defines the gradient of a linear interpolation at 3.2 as `y[4] - y[3]`.
154
+ """
155
+ function gradient_weights end
156
+
157
+ """
158
+ w = hessian_weights(degree, δx)
159
+
160
+ Compute the weights for interpolation of the hessian at an offset `δx` from the "base" position.
161
+ `degree` describes the interpolation scheme.
87
162
88
- @inline function Base. _getindex (:: IndexCartesian , A:: AbstractInterpolation{T,N} , I:: Vararg{Int,N} ) where {T,N} # ambiguity resolution
89
- @inbounds r = getindex (A, I... )
90
- r
163
+ # Example
164
+
165
+ ```jldoctest
166
+ julia> Interpolations.hessian_weights(Linear(), 0.2)
167
+ (0.0, 0.0)
168
+ ```
169
+
170
+ Linear interpolation uses straight line segments, so the second derivative is zero.
171
+ """
172
+ function hessian_weights end
173
+
174
+
175
+ gradient1 (itp:: AbstractInterpolation{T,1} , x) where {T} = gradient (itp, x)[1 ]
176
+ hessian1 (itp:: AbstractInterpolation{T,1} , x) where {T} = hessian (itp, x)[1 ]
177
+
178
+ # ## Supporting expansion of CartesianIndex
179
+
180
+ const UnexpandedIndexTypes = Union{Number, AbstractVector, CartesianIndex}
181
+ const ExpandedIndexTypes = Union{Number, AbstractVector}
182
+
183
+ Base. to_index (:: AbstractInterpolation , x:: Number ) = x
184
+
185
+ # Commented out because you can't add methods to an abstract type.
186
+ # @inline function (itp::AbstractInterpolation)(x::Vararg{UnexpandedIndexTypes})
187
+ # itp(to_indices(itp, x))
188
+ # end
189
+ function gradient (itp:: AbstractInterpolation , x:: Vararg{UnexpandedIndexTypes} )
190
+ gradient (itp, to_indices (itp, x))
91
191
end
92
- @inline function Base. _getindex (:: IndexCartesian , A:: AbstractInterpolation{T,N} , I:: Vararg{Real,N} ) where {T,N}
93
- @inbounds r = getindex (A, I... )
94
- r
192
+ function gradient! (dest, itp:: AbstractInterpolation , x:: Vararg{UnexpandedIndexTypes} )
193
+ gradient! (dest, itp, to_indices (itp, x))
95
194
end
195
+ function hessian (itp:: AbstractInterpolation , x:: Vararg{UnexpandedIndexTypes} )
196
+ hessian (itp, to_indices (itp, x))
197
+ end
198
+ function hessian! (dest, itp:: AbstractInterpolation , x:: Vararg{UnexpandedIndexTypes} )
199
+ hessian! (dest, itp, to_indices (itp, x))
200
+ end
201
+
202
+ # @inline function (itp::AbstractInterpolation)(x::Vararg{ExpandedIndexTypes})
203
+ # itp.(Iterators.product(x...))
204
+ # end
205
+ function gradient (itp:: AbstractInterpolation , x:: Vararg{ExpandedIndexTypes} )
206
+ map (y-> gradient (itp, y), Iterators. product (x... ))
207
+ end
208
+ function hessian (itp:: AbstractInterpolation , x:: Vararg{ExpandedIndexTypes} )
209
+ map (y-> hessian (itp, y), Iterators. product (x... ))
210
+ end
211
+
212
+ # getindex is supported only for Integer indices (deliberately)
213
+ import Base: getindex
214
+ @propagate_inbounds getindex (itp:: AbstractInterpolation{T,N} , i:: Vararg{Integer,N} ) where {T,N} = itp (i... )
215
+ @inline function getindex (itp:: AbstractInterpolation{T,1} , i:: Integer , j:: Integer ) where T
216
+ @boundscheck (j == 1 || Base. throw_boundserror (itp, (i, j)))
217
+ @inbounds itp (i)
218
+ end
219
+
220
+ # deprecate getindex for other numeric indices
221
+ @deprecate getindex (itp:: AbstractInterpolation{T,N} , i:: Vararg{Number,N} ) where {T,N} itp (i... )
96
222
97
223
include (" nointerp/nointerp.jl" )
98
224
include (" b-splines/b-splines.jl" )
99
- include (" gridded/gridded.jl" )
100
- include (" extrapolation/extrapolation.jl" )
101
- include (" scaling/scaling.jl" )
225
+ # include("gridded/gridded.jl")
226
+ # include("extrapolation/extrapolation.jl")
227
+ # include("scaling/scaling.jl")
102
228
include (" utils.jl" )
103
229
include (" io.jl" )
104
230
include (" convenience-constructors.jl" )
0 commit comments