@@ -81,6 +81,56 @@ function coefficients{C<:Cubic}(::Type{BSpline{C}}, N, d)
8181 end
8282end
8383
84+ """
85+ In this function we assume that `fx_d = x-ix_d` and we produce `cX_d` for
86+ `X ⋹ {m, _, p, pp}` such that
87+
88+ cm_d = p'(fx_d)
89+ c_d = q'(fx_d)
90+ cp_d = q'(1-fx_d)
91+ cpp_d = p'(1-fx_d)
92+
93+ where `p` and `q` are defined in the docstring for `Cubic`.
94+ """
95+ function gradient_coefficients {C<:Cubic} (:: Type{BSpline{C}} , d)
96+ symm, sym, symp, sympp = symbol (" cm_" ,d), symbol (" c_" ,d), symbol (" cp_" ,d), symbol (" cpp_" ,d)
97+ symfx = symbol (" fx_" ,d)
98+ symfx_sqr = symbol (" fx_sqr_" , d)
99+ sym_1m_fx_sqr = symbol (" one_m_fx_sqr_" , d)
100+ quote
101+ $ symfx_sqr = sqr ($ symfx)
102+ $ sym_1m_fx_sqr = sqr (1 - $ symfx)
103+
104+ $ symm = - SimpleRatio (1 ,2 ) * $ sym_1m_fx_sqr
105+ $ sym = SimpleRatio (3 ,2 ) * $ symfx_sqr - 2 * $ symfx
106+ $ symp = - SimpleRatio (3 ,2 ) * $ sym_1m_fx_sqr + 2 * (1 - $ symfx)
107+ $ sympp = SimpleRatio (1 ,2 ) * $ symfx_sqr
108+ end
109+ end
110+
111+ """
112+ In `hessian_coefficients` for a cubic b-spline we assume that `fx_d = x-ix_d`
113+ and we define `cX_d` for `X ⋹ {m, _, p, pp}` such that
114+
115+ cm_d = p''(fx_d)
116+ c_d = q''(fx_d)
117+ cp_d = q''(1-fx_d)
118+ cpp_d = p''(1-fx_d)
119+
120+ where `p` and `q` are defined in the docstring entry for `Cubic`, and
121+ `fx_d` in the docstring entry for `define_indices_d`.
122+ """
123+ function hessian_coefficients {C<:Cubic} (:: Type{BSpline{C}} , d)
124+ symm, sym, symp, sympp = symbol (" cm_" ,d), symbol (" c_" ,d), symbol (" cp_" ,d), symbol (" cpp_" ,d)
125+ symfx = symbol (" fx_" ,d)
126+ quote
127+ $ symm = 1 - $ symfx
128+ $ sym = 3 * $ symfx - 2
129+ $ symp = 1 - 3 * $ symfx
130+ $ sympp = $ symfx
131+ end
132+ end
133+
84134function index_gen {C<:Cubic,IT<:DimSpec{BSpline}} (:: Type{BSpline{C}} , :: Type{IT} , N:: Integer , offsets... )
85135 if length (offsets) < N
86136 d = length (offsets)+ 1
@@ -155,7 +205,7 @@ condition gives:
155205"""
156206function prefiltering_system {T,TC} (:: Type{T} , :: Type{TC} , n:: Int ,
157207 :: Type{Cubic{Line}} , :: Type{OnCell} )
158- dl,d,du = inner_system_diags (T,n,Cubic{Flat })
208+ dl,d,du = inner_system_diags (T,n,Cubic{Line })
159209 d[1 ] = d[end ] = 3
160210 du[1 ] = dl[end ] = - 7
161211
@@ -181,18 +231,29 @@ condition gives:
181231This is the same system as `Quadratic{Line}`, `OnGrid` so we reuse the
182232implementation
183233"""
184- function prefiltering_system {T,TC,GT<:GridType} (:: Type{T} , :: Type{TC} , n:: Int ,
185- :: Type{Cubic{Line}} , :: Type{GT} )
186- prefiltering_system (T, TC, n, Quadratic{Line}, OnGrid)
234+ function prefiltering_system {T,TC} (:: Type{T} , :: Type{TC} , n:: Int ,
235+ :: Type{Cubic{Line}} , :: Type{OnGrid} )
236+ dl,d,du = inner_system_diags (T,n,Cubic{Line})
237+ d[1 ] = d[end ] = 1
238+ du[1 ] = dl[end ] = - 2
239+
240+ # now need Woodbury correction to set :
241+ # - [1, 3] and [n, n-2] ==> 1
242+ specs = _build_woodbury_specs (T, n,
243+ (1 , 3 , one (T)),
244+ (n, n- 2 , one (T)),
245+ )
246+
247+ Woodbury (lufact! (Tridiagonal (dl, d, du), Val{false }), specs... ), zeros (TC, n)
187248end
188249
189250function prefiltering_system {T,TC,GT<:GridType} (:: Type{T} , :: Type{TC} , n:: Int ,
190251 :: Type{Cubic{Periodic}} , :: Type{GT} )
191252 dl, d, du = inner_system_diags (T,n,Cubic{Periodic})
192253
193254 specs = _build_woodbury_specs (T, n,
194- (1 , n, SimpleRatio ( 1 , 6 ) ),
195- (n, 1 , SimpleRatio ( 1 , 6 ) )
255+ (1 , n, du[ 1 ] ),
256+ (n, 1 , dl[ end ] )
196257 )
197258
198259 Woodbury (lufact! (Tridiagonal (dl, d, du), Val{false }), specs... ), zeros (TC, n)
@@ -210,38 +271,12 @@ This is the same system as `Quadratic{Free}` so we reuse the implementation
210271"""
211272function prefiltering_system {T,TC,GT<:GridType} (:: Type{T} , :: Type{TC} , n:: Int ,
212273 :: Type{Cubic{Free}} , :: Type{GT} )
213- prefiltering_system (T, TC, n, Quadratic{Free}, GT)
214- end
215-
216- @inline cub (x) = x* x* x
217-
218- """
219- Build `rowspec`, `valspec`, `colspec` such that the product
220-
221- `out = rowspec * valspec * colspec` will be equivalent to:
222-
223- ```julia
224- out = zeros(n, n)
225-
226- for (i, j, v) in args
227- out[i, j] = v
228- end
229- ```
230-
231- """
232- function _build_woodbury_specs {T} (:: Type{T} , n:: Int , args:: Tuple{Int, Int, Any} ...)
233- m = length (args)
234- rowspec = spzeros (T, n, m)
235- colspec = spzeros (T, m, n)
236- valspec = zeros (T, m, m)
274+ dl, d, du = inner_system_diags (T,n,Cubic{Periodic})
237275
238- ix = 1
239- for (i, (row, col, val)) in enumerate (args)
240- rowspec[row, ix] = 1
241- colspec[ix, col] = 1
242- valspec[ix, ix] = val
243- ix += 1
244- end
276+ specs = _build_woodbury_specs (T, n,
277+ (1 , n, du[1 ]),
278+ (n, 1 , dl[end ])
279+ )
245280
246- rowspec, valspec, colspec
281+ Woodbury ( lufact! ( Tridiagonal (dl, d, du), Val{ false }), specs ... ), zeros (TC, n)
247282end
0 commit comments