I have the following toy function implementing a backward difference formula (homework):
function newton_iteration{T}(x0::T, F, J; tol=2*eps(), testfun=norm)::T
x = x0 - J(x0) \ F(x0)
while testfun(x) > tol
x -= J(x) \ F(x)
end
x
end
function backdiff2(x0, t0, tf, n::Integer, F, J)
h = (tf - t0) / n
solution_vector = Vector{typeof(x0)}(n+1)
solution_vector[1] = x0
# First step uses Euler.
solution_vector[2] = x0 .+ h.*F(x0,t0)
# The rest of the steps use Newton's method to solve the
# implicit formula.
for i = 3:n+1
t = t0 + (i-1)*h
# f defines the mapping whose root is the next value of x.
f = x -> x .- (4/3).*solution_vector[i-1] .+
(1/3).*solution_vector[i-2] .- (2*h/3).*F(x, t)
# j defines the Jacobian of the above:
j = x -> eye(length(x)) .+ (2*h/3).*J(x,t)
solution_vector[i] = newton_iteration(solution_vector[i-1], f, j)
end
solution_vector
end
When inspected with @code_warntype
it seems that the loop index i
is being boxed, and wherever the uncertainty about i
is coming from, it propagates to t
and indexing operations using i
(if I’m reading the output right). No annotation I tried got rid of the instability. What is the cause?
Sample call that generates the above described output:
using FixedSizeArrays
F(z, t) = Vec(z[2], -z[1])
J(z, t) = Mat{2,2,Float64}((0, 1), (-1, 0))
@code_warntype backdiff2(Vec(1.0, 0.0), 0., 9*pi/4, 100, F, J)
Hopefully no typos in that… I’ll check again when I’m not on the bus.