Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directional Cross Derivatives #295

Open
daseyb opened this issue Jul 1, 2023 · 1 comment
Open

Directional Cross Derivatives #295

daseyb opened this issue Jul 1, 2023 · 1 comment

Comments

@daseyb
Copy link

daseyb commented Jul 1, 2023

I'm working with Gaussian processes where the kernel $k(x, y)$ is a function of two position vectors. I would like to take "directional cross derivatives" with respect to each position. That is, I want to compute something like $D_{v_y} D_{v_x} k(x,y) = D^2_{v_x,v_y} k(x,y)$ where $D_{v_*} k(x,y)$ is the directional derivative of $k(x,y)$ with respect to the change of $*$ in direction $v_*$.

I at first naively did something like
autodiff::derivatives( k(x, y), autodiff::along(dirX, dirY), at(x, y))[2]
but that's subtly different as far as I can tell (i.e. the second derivative along the combined direction $[v_x, v_y]$, instead of the cross derivative).

Is there something built in that would allow me to do this reasonably efficiently?
Thanks!

@daseyb
Copy link
Author

daseyb commented Jul 1, 2023

Update: I did some working out by hand and found that I can do this relatively cleanly (though a bit wastefully) using the hessian.

$$ D^2_{v_x,v_y} k(x,y) = \sum_{j=1}^d ( \sum_{i=1}^d ( \frac{\partial^2 k(x,y)}{\partial x_i \partial y_j} \cdot v_{x_i} ) \cdot v_{y_j} ) \\ = v_x^T H_{k(x,y)}^{d:2d, 0:d} v_y $$

Where $H_{k(x,y)}^{d:2d, 0:d}$ is the off-diagonal dxd "block" of the full 2dx2d hessian matrix, which is where the "actual" (across the x and y vectors, instead of within) cross derivatives are.

In code, this looks pretty neat, but of course, requires dual2nd instead of real2nd:

Eigen::Matrix3d hess = autodiff::hessian(k(x, y), wrt(x, y), at(x, y)).block(3, 0, 3, 3);
double res = dirX.transpose() * hess * dirY;

The only thing that makes this not 100% satisfying is that I'm throwing away a quarter of the hessian, so there might be a more efficient way to compute the required cross derivatives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant