Skip to content

Commit 2b08f41

Browse files
committed
push in the right direction
1 parent 1cbba16 commit 2b08f41

File tree

2 files changed

+47
-31
lines changed

2 files changed

+47
-31
lines changed

src/systems/diffeqs/sdesystem.jl

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ function generate_diffusion_function(sys::SDESystem, dvs = states(sys),
153153
return build_function(get_noiseeqs(sys),
154154
map(x -> time_varying_as_func(value(x), sys), dvs),
155155
map(x -> time_varying_as_func(value(x), sys), ps),
156-
get_iv(sys); kwargs...)
156+
get_iv(sys); kwargs...)
157157
end
158158

159159
"""
@@ -210,13 +210,15 @@ end
210210
$(TYPEDSIGNATURES)
211211
212212
Measure transformation method that allows for a reduction in the variance of an estimator `Exp(g(X_t))`.
213-
Input: Original SDE system and symbolic function `u(t,x)` with scalar output that defines the
214-
adjustable parameters `d` in the Girsanov transformation.
215-
Output: Modified SDESystem with additional component `θ_t` and initial value `θ0`,
216-
such that the estimator `Exp(g(X_t)θ_t/θ0)` has a smaller variance.
217-
218-
Reference:
219-
Kloeden, P. E., Platen, E., & Schurz, H. (2012). Numerical solution of SDE through computer
213+
Input: Original SDE system and symbolic function `u(t,x)` with scalar output that
214+
defines the adjustable parameters `d` in the Girsanov transformation. Optional: initial
215+
condition for `θ0`.
216+
Output: Modified SDESystem with additional component `θ_t` and initial value `θ0`, as well as
217+
the weight `θ_t/θ0` as observed equation, such that the estimator `Exp(g(X_t)θ_t/θ0)`
218+
has a smaller variance.
219+
220+
Reference:
221+
Kloeden, P. E., Platen, E., & Schurz, H. (2012). Numerical solution of SDE through computer
220222
experiments. Springer Science & Business Media.
221223
222224
# Example
@@ -234,22 +236,40 @@ noiseeqs = [β*x]
234236
@named de = SDESystem(eqs,noiseeqs,t,[x],[α,β])
235237
236238
# define u (user choice)
237-
u = x
238-
demod = ModelingToolkit.Girsanov_transform(de, u)
239+
u = x
240+
θ0 = 0.1
241+
g(x) = x[1]^2
242+
demod = ModelingToolkit.Girsanov_transform(de, u; θ0=0.1)
243+
244+
u0modmap = [
245+
x => x0
246+
]
247+
248+
parammap = [
249+
α => 1.5,
250+
β => 1.0
251+
]
252+
253+
probmod = SDEProblem(demod,u0modmap,(0.0,1.0),parammap)
254+
ensemble_probmod = EnsembleProblem(probmod;
255+
output_func = (sol,i) -> (g(sol[x,end])*sol[weight,end],false),
256+
)
257+
258+
simmod = solve(ensemble_probmod,EM(),dt=dt,trajectories=numtraj)
239259
```
240260
241261
"""
242-
function Girsanov_transform(sys::SDESystem, u)
262+
function Girsanov_transform(sys::SDESystem, u; θ0=1.0)
243263
name = nameof(sys)
244264

245265
# register new varible θ corresponding to 1D correction process θ(t)
246266
t = get_iv(sys)
247-
@variables θ(t)
248267
D = Differential(t)
249-
268+
@variables θ(t), weight(t)
269+
250270
# determine the adjustable parameters `d` given `u`
251-
# gradient of u with respect to states
252-
grad = Symbolics.gradient(u,states(sys))
271+
# gradient of u with respect to states
272+
grad = Symbolics.gradient(u,states(sys))
253273

254274
noiseeqs = get_noiseeqs(sys)
255275
if typeof(noiseeqs) <: Vector
@@ -288,7 +308,9 @@ function Girsanov_transform(sys::SDESystem, u)
288308
state = [states(sys);θ]
289309

290310
# return modified SDE System
291-
SDESystem(deqs, noiseeqs, get_iv(sys), state, parameters(sys), name = name, checks = false)
311+
SDESystem(deqs, noiseeqs, get_iv(sys), state, parameters(sys);
312+
defaults = Dict=> θ0), observed = [weight ~ θ/θ0],
313+
name=name, checks=false)
292314
end
293315

294316
"""

test/sdesystem.jl

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,11 @@ end
528528

529529
@named de = SDESystem(eqs,noiseeqs,t,[x],[α,β])
530530

531-
h(x) = x[1]^2
531+
g(x) = x[2]^2
532532
dt = 1 //2 ^(7)
533533
x0 = 0.1
534534

535-
## Standard approach
535+
## Standard approach
536536
# EM with 1`000 trajectories for stepsize 2^-7
537537
u0map = [
538538
x => x0
@@ -554,7 +554,7 @@ end
554554
seeds = rand(UInt, numtraj)
555555

556556
ensemble_prob = EnsembleProblem(prob;
557-
output_func = (sol,i) -> (h(sol[end]),false),
557+
output_func = (sol,i) -> (g(sol[end]),false),
558558
prob_func = prob_func
559559
)
560560

@@ -563,28 +563,22 @@ end
563563
σ = std(sim)/sqrt(numtraj)
564564

565565
## Variance reduction method
566-
u = x
567-
demod = ModelingToolkit.Girsanov_transform(de, u)
568-
@variables θ(t)
569-
θ0 = 0.1
570-
u0modmap = [
571-
x => x0
572-
θ => θ0
573-
]
566+
u = x
567+
demod = ModelingToolkit.Girsanov_transform(de, u; θ0=0.1)
574568

575-
probmod = SDEProblem(demod,u0modmap,(0.0,1.0),parammap)
569+
probmod = SDEProblem(demod,u0map,(0.0,1.0),parammap)
576570

577571
ensemble_probmod = EnsembleProblem(probmod;
578-
output_func = (sol,i) -> (h(sol[x,end])*sol[θ,end]/θ0,false),
572+
output_func = (sol,i) -> (g(sol[x,end])*sol[weight,end],false),
579573
prob_func = prob_func
580574
)
581575

582576
simmod = solve(ensemble_probmod,EM(),dt=dt,trajectories=numtraj)
583577
μmod = mean(simmod)
584578
σmod = std(simmod)/sqrt(numtraj)
585579

586-
display("μ = $(round(μ, digits=2)) ± $(round(σ, digits=2))")
587-
display("μmod = $(round(μmod, digits=2)) ± $(round(σmod, digits=2))")
580+
display("μ = $(round(μ, digits=2)) ± $(round(σ, digits=2))")
581+
display("μmod = $(round(μmod, digits=2)) ± $(round(σmod, digits=2))")
588582

589583
@test μ μmod atol = 2σ
590584
@test σ > σmod

0 commit comments

Comments
 (0)