SciML / SciMLSensitivity.jl

A component of the DiffEq ecosystem for enabling sensitivity analysis for scientific machine learning (SciML). Optimize-then-discretize, discretize-then-optimize, adjoint methods, and more for ODEs, SDEs, DDEs, DAEs, etc.
https://docs.sciml.ai/SciMLSensitivity/stable/
Other
328 stars 71 forks source link

derivatives towards NoiseGrid #755

Open ArnoStrouwen opened 1 year ago

ArnoStrouwen commented 1 year ago

Is it possible to get derivatives if a certain point in the NoiseGrid is perturbed?

using DifferentialEquations
using DiffEqNoiseProcess
using Distributions
using LinearAlgebra

function lotka_volterra!(du, u, p, t)
    # Model parameters.
    α, β, γ, δ = p
    # Current state.
    x, y = u

    # Evaluate differential equations.
    du[1] = (α - β * y) * x # prey
    du[2] = (δ * x - γ) * y # predator

    return nothing
end
function process_noise!(du, u, p, t)
    du[1] = u[1]*0.025
    du[2] = u[2]*0.025
end
u0 = [1.0, 1.0]

t0,tend = 0,10
measurement_freq = 1.0
noise_freq = 0.1
tspan = (t0,tend)
tmeasure = tend/2:measurement_freq:tend
tgrid = t0:noise_freq:tend
p = [1.5, 1.0, 3.0, 1.0]
W = WienerProcess(0.0, zeros(length(u0)))
prob = SDEProblem(lotka_volterra!,process_noise!,u0,tspan,p,saveat=tmeasure,noise=W)
sol = solve(prob,saveat=[],reltol=1e-6,abstol=1e-6)

brownian_noise = rand(MvNormal(zeros(length(u0)*(length(tgrid)-1)),noise_freq*I))
function cost(brownian_noise)
    brownian_noise = reshape(brownian_noise,length(u0),length(tgrid)-1)
    brownian_noise = vcat([zeros(length(u0))], [collect(c) for c in eachcol(brownian_noise)])
    W = NoiseGrid(vcat(tgrid,10.1),vcat(cumsum(brownian_noise),[rand(length(u0))]))
    prob2 = remake(prob,noise=W)
    sol = solve(prob2,saveat=[tend],reltol=1e-6,abstol=1e-6)
    sol[1,1]
end
cost(brownian_noise)
using FiniteDiff
FiniteDiff.finite_difference_gradient(cost,brownian_noise)
#= 0.03444353018797594
0.0069834832055333685
0.033542084995965296
0.009780529179223462
0.032296314940624425
0.012032449860818358
⋮
0.021642466018380616
-0.007096733809517599
0.02209889806930123
-0.0038319467798237274
0.022306522071220965
-0.0011569890755444205 =#
using ForwardDiff
ForwardDiff.gradient(cost,brownian_noise)
#error
using SciMLSensitivity
using Zygote
Zygote.gradient(cost,brownian_noise)
#error
using ReverseDiff
ReverseDiff.gradient(cost,brownian_noise)
#error
ChrisRackauckas commented 1 year ago

This derivative isn't implemented right now.

ArnoStrouwen commented 1 year ago

So HMC for SDE is not yet possible.

ChrisRackauckas commented 1 year ago

Depends on the form. Direct handling of the noise terms, only with ForwardDiff.