-
-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do the autodiff options have any meaning when the Jacobi matrix is provided? #773
Do the autodiff options have any meaning when the Jacobi matrix is provided? #773
Comments
Rosenbrock methods don't just need the Jacobian, they also need a gradient w.r.t. time. |
Yes, thanks a lot. I did not notice, that these options do also influence the time derivative. |
What do you mean? Do you have an example? |
My application is rather complex, but I will try to construct an example. |
This is my example: 0 = y^2 -1/t^4, y(1)=-1 with solution y(t) = -1/t^2. For f(y)=y^2 and h>0 the FD Approximation f'(y) = (f(y+h)-f(y))/h leads to a singular Jacobian latest at time t = sqrt(2/h).
using DifferentialEquations
function fcn(du,u,p,t)
du[1] = u[1]^2 - 1/t^4;
end
function f_jac(J,y,P,t)
#-- numerical Jac by FD
y_thres = P;
del = sqrt(eps(1.0)); n = length(y);
f0 = similar(y); f1 = similar(y); fcn(f0,y,P,t);
for i=1:n
del_1 = del*max(abs(y[i]),y_thres);
y1 = copy(y); y1[i] = y1[i] + del_1;
fcn(f1,y1,P,t)
J[:,i] = (f1-f0)/del_1;
end
end
tspan = (1.0, 1.0e3); M = zeros(1,1);
println("--- AD ---")
f = ODEFunction(fcn,mass_matrix=M)
problem = ODEProblem(f,[-1.0], tspan);
sol = solve(problem,Rodas4P2(),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats)
println("--- FD central ---")
sol = solve(problem,Rodas4P2(autodiff=false,diff_type=Val{:central}),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats)
println("--- FD forward ---")
sol = solve(problem,Rodas4P2(autodiff=false,diff_type=Val{:forward}),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats)
println("--- FD forward, y_thres = 1 ---")
y_thres = 1.0;
f = ODEFunction(fcn,mass_matrix=M,jac=f_jac)
problem = ODEProblem(f,[-1.0], tspan,y_thres);
sol = solve(problem,Rodas4P2(autodiff=false,diff_type=Val{:forward}),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats)
println("--- FD forward, y_thres = 1.0e-5 ---")
y_thres = 1.0e-5;
f = ODEFunction(fcn,mass_matrix=M,jac=f_jac)
problem = ODEProblem(f,[-1.0], tspan,y_thres);
sol = solve(problem,Rodas4P2(autodiff=false,diff_type=Val{:forward}),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats)
println("--- FD forward, y_thres = sqrt(eps) ---")
y_thres = sqrt(eps(1.0));
f = ODEFunction(fcn,mass_matrix=M,jac=f_jac)
problem = ODEProblem(f,[-1.0], tspan,y_thres);
sol = solve(problem,Rodas4P2(autodiff=false,diff_type=Val{:forward}),maxiters=Int(1e7),reltol=1.0e-12,abstol=1.0e-12);
println(sol.destats) Output--- AD --- --- FD central --- --- FD forward --- --- FD forward, y_thres = 1 --- --- FD forward, y_thres = 1.0e-5 -- --- FD forward, y_thres = sqrt(eps) --- |
Yeah it looks like a more optimal eps could be chosen here. |
The problem for the failure of (autodiff=false,diff_type=Val{:forward}) is within function calc_rosenbrock_differentiation! (see derivative_utils.jl). Here linsolve_tmp changes it's value, but should not. This is a workaround, but sure not the final solution.: function calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, W_transform) Best regards Gerd |
Isn't it only used for the temporary inside that calculation? Is there a reason that buffer needs to remain unchanged later? If so, we probably need to add another cache vector, or use a different one somewhere. |
cache.linsolve_tmp holds the result from calc_tederivative! and is required in rosenbrock_perform_step. |
So the |
Yes, thats the most simple possibility. |
When I provide the Jacobian
f = ODEFunction(fcn,mass_matrix=M,jac=f_jac)
why do I get different results (number of time steps,...) when I use different options for autodiff:
or
or
In my opinion, these options should not play a role then.
Moreover, usage of a simple numerical f_jac
function f_jac(J,y,P,t)
#--
del = sqrt(eps(1.0)); n = length(y);
f0 = similar(y); f1 = similar(y); fcn(f0,y,P,t);
for i=1:n
del_1 = max(abs(y[i])*del,del);
if y[i]<0.0 del_1 = -del_1; end
y1 = copy(y); y1[i] = y1[i] + del_1;
fcn(f1,y1,P,t)
J[:,i] = (f1-f0)/del_1;
end
end
leads to 864 accepted steps compared to 4813 steps without providing the Jacobian and autodiff=false,diff_type=Val{:forward} option. The diff_type=Val{:central} option is similar to 860 steps.
The text was updated successfully, but these errors were encountered: