Files
2022-06-12 11:16:58 -04:00

42 lines
1.2 KiB
Python

import torch
from gpytorch.kernels import Kernel
def CumTrapz(y, x):
dx = x[..., 1] - x[..., 0]
dx = dx if x.ndim == 1 else dx.unsqueeze(-1)
wghts = dx * torch.ones_like(x)
wghts[..., 0] *= 0.5
wghts[..., -1] *= 0.5
return torch.cumsum(wghts * y, -1)
class VolatilityKernel(Kernel):
has_lengthscale = False
def __init__(self, **kwargs):
super().__init__(**kwargs)
def forward(self, x, vol_path, diag=False, **params):
if x.shape[-1] == 1:
x = x.squeeze()
if vol_path.shape[-1] == 1:
vol_path = vol_path.squeeze()
last_dim_is_batch = params.get("last_dim_is_batch", False)
if last_dim_is_batch:
vol_path = vol_path.transpose(-1, -2)
vol_int = CumTrapz(vol_path * vol_path, x)
idx = torch.arange(x.shape[-1])
idx1, idx2 = torch.meshgrid(idx, idx)
idx = torch.minimum(idx1, idx2)
res = vol_int[..., idx]
# TODO: check this
if last_dim_is_batch:
res = res.permute(1, 2, 0)
if diag:
return torch.diagonal(res, dim1=-2, dim2=-1)
else:
return res