Open patrick-kidger opened 4 years ago
My number one desired feature is antithetic sampling as an option for sdeint. It's pretty cumbersome to achieve this without editing the package by changing the BrownianInterval's W.
I've not filled in every detail, but I'd have thought something like this should work:
class AntitheticBrownian(BaseBrownian):
def __init__(self, bm):
self.bm = bm
def __call__(self, ta, tb):
return -self.bm(ta, tb)
bm = BrownianInterval(...)
ys = torchsde(bm=bm, ...)
abm = AntitheticBrownian(bm)
ays = torchsde(bm=abm, ...)
ys = torch.cat([ys, ays])
Does this approach fail / am I missing something / are you trying to achieve something beyond this?
Does work, but it's still much uglier than it needs to be vs sdeint(...,antithetic=True). For innumerable financial applications of this library, this type of option is... priceless ;p Here's a filled in version in case anyone else is following along:
ts = tch.linspace(0,1.,365)
ntraj = 1000
bm = torchsde.BrownianInterval(ts[0], ts[-1], size=(ntraj,sde.brownian_size), levy_area_approximation='space-time')
ys_ = torchsde.sdeint(sde,sde.y0(ntraj=ntraj), ts, bm=bm)
class AntitheticBrownian(torchsde.BrownianInterval):
def __init__(self, t0, t1, size, bm):
super(AntitheticBrownian, self).__init__(t0,t1,size, levy_area_approximation='space-time')
self.bm = bm
def __call__(self, ta, tb=None, return_U=False, return_A=False):
Z = self.bm(ta, tb, return_U, return_A)
if return_U:
if return_A:
return -Z[0], Z[1], Z[2]
else:
return -Z[0], Z[1]
else:
if return_A:
return -Z[0], Z[1]
else:
return -Z
abm = AntitheticBrownian(ts[0], ts[-1], (ntraj,sde.brownian_size), bm)
ays = torchsde.sdeint(sde,sde.y0(ntraj=ntraj), ts, bm=abm)
ys = torch.cat([ys_, ays],1)```
Creating a list of potential features that may be nice to have, but aren't necessarily a priority right now.
f_and_g
function on SDEs, that computes drift+diffusion simultaneously. (#84)Tests:
Maybe?
dg_ga
, if and when batch-vjp ever becomes available.sdeint
,sdeint_adjoint