Skip to content

Commit c675127

Browse files
committed
WIP: evaluation of multi splines at the same time.
1 parent 115d3e8 commit c675127

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

src/csplines.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ function eval_UC_spline_G(a, b, orders, C, S)
4646

4747
end
4848

49+
function eval_UC_multi_spline(a, b, orders, C, S)
50+
51+
d = size(S,2)
52+
N = size(S,1)
53+
K = size(C,1) # number of splines to evaluate
54+
vals = zeros(K,N)
55+
eval_UC_multi_spline!(a, b, orders, C, S, vals, Ad, dAd)
56+
return vals
57+
58+
end
59+
4960
# problem with this approach: the functions don't get cached.
5061

5162
# fun = (create_function(1,"natural"))
@@ -77,3 +88,11 @@ end
7788
fun = (create_function_with_gradient(d,"natural"))
7889
return fun.args[2].args[2]
7990
end
91+
92+
@generated function eval_UC_multi_spline!(a, b, orders, C, S, V, Ad, dAd)
93+
d = C.parameters[2]-1 # first dimension of C indexes the splines
94+
# the speed penalty of extrapolating points when iterating over point
95+
# seems very small so this is the default
96+
fun = (create_function_multi_spline(d,"natural"))
97+
return fun.args[2].args[2]
98+
end

src/macros.jl

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ function create_Phi(d, extrap, diff)
3737
return lines
3838
end
3939

40-
function tensor_prod(symbs, inds)
40+
function tensor_prod(symbs, inds, add_index=false)
4141
if length(symbs)==0
4242
subscripts = [:($(U("i",i))+$(inds[i])) for i=1:length(inds)]
43-
return :(C[$(subscripts...)])
43+
if add_index
44+
return :(C[k,$(subscripts...)])
45+
else
46+
return :(C[$(subscripts...)])
47+
end
4448
else
4549
h = symbs[1]
4650
if length(symbs)>1
@@ -50,14 +54,16 @@ function tensor_prod(symbs, inds)
5054
end
5155
exprs = []
5256
for i = 1:4
53-
e = parse( string(h,"_",i,"*(",tensor_prod(q,cat(1,inds,[i])),")") )
57+
e = parse( string(h,"_",i,"*(",tensor_prod(q,cat(1,inds,[i]),add_index),")") )
5458
push!(exprs,e)
5559
end
5660
return :(+($(exprs...)))
5761
end
5862
end
5963

60-
tensor_prod([], Int64[1,2,3,4]) # C[1,2,3,4]
64+
tensor_prod([], Int64[1,2,3,4],) # C[i1+1,i2+2,i3+3,i4+4]
65+
tensor_prod([], Int64[1,2,3,4], true) # C[k,i1+1,i2+2,i3+3,i4+4]
66+
6167
tensor_prod(["Phi_1"], Int64[]) # Phi_1_1 * C[i1 + 1] + Phi_1_2 * C[i1 + 2] + Phi_1_3 * C[i1 + 3] + Phi_1_4 * C[i1 + 4]
6268
tensor_prod(["Phi_1", "Phi_2"], Int64[]) # Phi_1_1 * (Phi_2_1 * C[i1 + 1,i2 + 1] + Phi_2_2 * C[i1 + 1,i2 + 2] + Phi_2_3 * C[i1 + 1,i2 + 3] + Phi_2_4 * C[i1 + 1,i2 + 4]) + Phi_1_2 * (Phi_2_1 * C[i1 + 2,i2 + 1] + Phi_2_2 * C[i1 + 2,i2 + 2] + Phi_2_3 * C[i1 + 2,i2 + 3] + Phi_2_4 * C[i1 + 2,i2 + 4]) + Phi_1_3 * (Phi_2_1 * C[i1 + 3,i2 + 1] + Phi_2_2 * C[i1 + 3,i2 + 2] + Phi_2_3 * C[i1 + 3,i2 + 3] + Phi_2_4 * C[i1 + 3,i2 + 4]) + Phi_1_4 * (Phi_2_1 * C[i1 + 4,i2 + 1] + Phi_2_2 * C[i1 + 4,i2 + 2] + Phi_2_3 * C[i1 + 4,i2 + 3] + Phi_2_4 * C[i1 + 4,i2 + 4])
6369
tensor_prod(["Phi_1", "dPhi_2"], Int64[]) # Phi_1_1 * (dPhi_2_1 * C[i1 + 1,i2 + 1] + dPhi_2_2 * C[i1 + 1,i2 + 2] + dPhi_2_3 * C[i1 + 1,i2 + 3] + dPhi_2_4 * C[i1 + 1,i2 + 4]) + Phi_1_2 * (dPhi_2_1 * C[i1 + 2,i2 + 1] + dPhi_2_2 * C[i1 + 2,i2 + 2] + dPhi_2_3 * C[i1 + 2,i2 + 3] + dPhi_2_4 * C[i1 + 2,i2 + 4]) + Phi_1_3 * (dPhi_2_1 * C[i1 + 3,i2 + 1] + dPhi_2_2 * C[i1 + 3,i2 + 2] + dPhi_2_3 * C[i1 + 3,i2 + 3] + dPhi_2_4 * C[i1 + 3,i2 + 4]) + Phi_1_4 * (dPhi_2_1 * C[i1 + 4,i2 + 1] + dPhi_2_2 * C[i1 + 4,i2 + 2] + dPhi_2_3 * C[i1 + 4,i2 + 3] + dPhi_2_4 * C[i1 + 4,i2 + 4])
@@ -104,13 +110,13 @@ function create_function(d,extrap="natural")
104110
function $(Symbol(string("eval_UC_spline_",d,"d")))( a, b, orders, C, S, V, Ad, dAd)
105111
$(create_parameters(d)...)
106112
N = size(S,1)
107-
# @simd( # doesn't seem to make any difference
113+
@fastmath @inbounds @simd( # doesn't seem to make any difference
108114
for n=1:N
109115
$(create_local_parameters(d)...)
110116
$(create_Phi(d,extrap,false)...)
111117
V[n] = $( tensor_prod([string("Phi_",i) for i=1:d], Int64[]) )
112118
end
113-
# )
119+
)
114120
end
115121
end
116122
return expr
@@ -131,15 +137,40 @@ function create_function_with_gradient(d,extrap="natural")
131137
function $(Symbol(string("eval_UC_spline_",d,"d")))( a, b, orders, C, S, V, dV, Ad, dAd)
132138
$(create_parameters(d)...)
133139
N = size(S,1)
134-
# @simd( # doesn't seem to make any difference
140+
@fastmath @inbounds @simd( # doesn't seem to make any difference
135141
for n=1:N
136142
$(create_local_parameters(d)...)
137143
$(create_Phi(d,extrap,true)...)
138144
V[n] = $(tensor_prod([string("Phi_",i) for i=1:d], Int64[]))
139145
$([ :( dV[n,$j] = $(tensor_prod(grad_allocs[j], Int64[])) ) for j=1:d]...)
140146
end
147+
)
148+
end
149+
end
150+
return expr
151+
end
152+
153+
function create_function_multi_spline(d,extrap="natural")
154+
expr = quote
155+
function $(Symbol(string("eval_UC_multi_spline_",d,"d")))( a, b, orders, C, S, V, Ad, dAd)
156+
K = size(C,1)
157+
$(create_parameters(d)...)
158+
N = size(S,1)
159+
# @fastmath @inbounds @simd( # doesn't seem to make any difference
160+
for n=1:N
161+
$(create_local_parameters(d)...)
162+
$(create_Phi(d,extrap,false)...)
163+
for k=1:K
164+
V[k,n] = $( tensor_prod([string("Phi_",i) for i=1:d], Int64[], true) )
165+
end
166+
167+
end
141168
# )
142169
end
143170
end
144171
return expr
145172
end
173+
174+
175+
176+
create_function_multi_spline(1)

src/splines.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module splines
22

33
export filter_coeffs, interpolant_cspline
4-
export eval_UC_spline, eval_UC_spline_G
4+
export eval_UC_spline, eval_UC_spline_G, eval_UC_multi_spline
55
include("csplines.jl")
66
include("splines_filter.jl")
77

test/test.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ true_values = f(s)
4747
println("Maximum interpolation error : ", norm(true_values-interp_values,Inf))
4848
toc()
4949

50+
51+
# Test multi splines:
52+
53+
CC = zeros(2,size(coefs,1))
54+
CC[1,:] = coefs # first spline
55+
CC[2,:] = coefs/2 # second spline
56+
interp_multi_values = eval_UC_multi_spline(smin,smax,orders,CC,s)
57+
5058
#using PyPlot
5159
#plot(s,sol)
5260
#plot(s,true_values)

0 commit comments

Comments
 (0)