I have the following example where I get different gradient values for forward and backward:
using Random, ChainRulesCore, Zygote, Statistics
function simulate(N, drift, sigma, rng,i)
ChainRulesCore.@ignore_derivatives randn!(rng,N)
return @. sigma * N + drift
end
function simulate_bs(S0, r, T, sigma, d, nsim::Integer, nsteps::Integer, rng)
mu = r - d
zero_dual =ChainRulesCore.@ignore_derivatives 0 * mu * sigma * T
dt = T / nsteps
mu_adj = (mu - sigma^2 / 2) * dt
sigma_adj = sigma * sqrt(dt)
X =zeros(typeof(zero_dual), nsim)
N =Array{Float64}(undef,nsim)
ChainRulesCore.@ignore_derivatives Random.seed!(rng, 1)
for i = 1:nsteps
X += simulate(N, mu_adj, sigma_adj, rng,i)
end
@. S0 * exp(X)
end
function pricer_bs(S0, r, T, sigma, d, nsim::Integer, nsteps::Integer, rng)
X_ = simulate_bs(S0, r, T, sigma, d, nsim, nsteps, rng)
return mean(X_) * exp(-r * T)
end
function pricer_zygote_f(S0, r, T, sigma, d)
Nsim1 = 100_000;
Nstep1 = 3;
rng1 = MersenneTwister()
return pricer_bs(S0, r, T, sigma, d, Nsim1, Nstep1, rng1)
end
const S0 = 100.0;
const r = 0.01;
const T = 1.0;
const d = 0.01;
const sigma = 0.2;
fwd_grad=collect(Zygote.forward_jacobian(x->pricer_zygote_f(x...), [S0,r, T, sigma, d])[2])
rev_grad=collect(Zygote.gradient(pricer_zygote_f, S0,r, T, sigma, d))
@show fwd_grad.-rev_grad
and I get some non negligible mismatching on the derivative on T and sigma.
Do you have any idea of what is going on?