@@ -13,6 +13,16 @@ function gradient_coefficients{IT<:DimSpec{BSpline}}(::Type{IT}, N, dim)
1313 coefficients (iextract (IT, d), N, d) for d = 1 : N]
1414 Expr (:block , exs... )
1515end
16+ function hessian_coefficients {IT<:DimSpec{BSpline}} (:: Type{IT} , N, dim1, dim2)
17+ exs = if dim1 == dim2
18+ Expr[d== dim1== dim2 ? hessian_coefficients (iextract (IT, dim), d) :
19+ coefficients (iextract (IT, d), N, d) for d in 1 : N]
20+ else
21+ Expr[d== dim1 || d== dim2 ? gradient_coefficients (iextract (IT, dim), d) :
22+ coefficients (iextract (IT, d), N, d) for d in 1 : N]
23+ end
24+ Expr (:block , exs... )
25+ end
1626
1727index_gen {IT} (:: Type{IT} , N:: Integer , offsets... ) = index_gen (iextract (IT, min (length (offsets)+ 1 , N)), IT, N, offsets... )
1828
8898 :(gradient! (g, itp, $ (args... )))
8999end
90100
101+ @generated function gradient {T,N} (itp:: AbstractInterpolation{T,N} , xs... )
102+ n = count_interp_dims (itp, N)
103+ Tg = promote_type (T, [x <: AbstractArray ? eltype (x) : x for x in xs]. .. )
104+ xargs = [:(xs[$ d]) for d in 1 : length (xs)]
105+ :(gradient! (Array ($ Tg,$ n), itp, $ (xargs... )))
106+ end
107+
108+ gradient1 {T} (itp:: AbstractInterpolation{T,1} , x) = gradient (itp, x)[1 ]
109+
110+ function hessian_impl {T,N,TCoefs,IT<:DimSpec{BSpline},GT<:DimSpec{GridType},Pad} (itp:: Type{BSplineInterpolation{T,N,TCoefs,IT,GT,Pad}} )
111+ meta = Expr (:meta , :inline )
112+ # For each component of the hessian, alternately calculate
113+ # coefficients and set component
114+ n = count_interp_dims (IT, N)
115+ exs = Expr[]
116+ cntr = 0
117+ for d1 in 1 : N, d2 in 1 : N
118+ if count_interp_dims (iextract (IT,d1), 1 ) > 0 && count_interp_dims (iextract (IT,d2),1 ) > 0
119+ cntr += 1
120+ push! (exs, hessian_coefficients (IT, N, d1, d2))
121+ push! (exs, :(@inbounds H[$ cntr] = $ (index_gen (IT, N))))
122+ end
123+ end
124+ hessian_exprs = Expr (:block , exs... )
125+
126+ quote
127+ $ meta
128+ size (H) == ($ n,$ n) || throw (ArgumentError (string (" The size of the provided Hessian matrix wasn't a square matrix of size " , size (H))))
129+ @nexprs $ N d-> (x_d = xs[d])
130+
131+ $ (define_indices (IT, N, Pad))
132+
133+ $ hessian_exprs
134+
135+ H
136+ end
137+ end
138+
139+ @generated function hessian! {T,N} (H:: AbstractMatrix , itp:: BSplineInterpolation{T,N} , xs:: Number... )
140+ length (xs) == N || throw (ArgumentError (" Can only be called with $N indexes" ))
141+ hessian_impl (itp)
142+ end
143+
144+ @generated function hessian! {T,N} (H:: AbstractMatrix , itp:: BSplineInterpolation{T,N} , index:: CartesianIndex{N} )
145+ args = [:(index[$ d]) for d in 1 : N]
146+ :(hessian! (H, itp, $ (args... )))
147+ end
148+
149+ @generated function hessian {T,N} (itp:: AbstractInterpolation{T,N} , xs... )
150+ n = count_interp_dims (itp,N)
151+ TH = promote_type (T, [x <: AbstractArray ? eltype (x) : x for x in xs]. .. )
152+ xargs = [:(xs[$ d]) for d in 1 : length (xs)]
153+ :(hessian! (Array ($ TH,$ n,$ n), itp, $ (xargs... )))
154+ end
155+
156+ hessian1 {T} (itp:: AbstractInterpolation{T,1} , x) = hessian (itp, x)[1 ,1 ]
157+
91158offsetsym (off, d) = off == - 1 ? symbol (" ixm_" , d) :
92159 off == 0 ? symbol (" ix_" , d) :
93160 off == 1 ? symbol (" ixp_" , d) :
0 commit comments