Loading [MathJax]/jax/output/HTML-CSS/jax.js

First time here? Check out the FAQ!

Ask Your Question
1

Use vector as variable for diff but as values for calculation

asked 4 years ago

Spirit gravatar image

updated 4 years ago

I am implementing the Squared Exponential kernel in SageMath, for now let's say it's defined as follows:

f(xi,xk)=σ2exp(122qj=1(xi,jxk,j)2)

With xi and xk vectors of variable, but equal, length, σ and l constant. (In the future l might be vector valued as well, I hope this can be handled then).

The function f must be differentiable in xi and xk (not its entries!).
An example implementation might look as follows:

n = 8
x1 = vector(list(var('v1_%d' % i) for i in range(1, n+1)))
x2 = vector(list(var('v2_%d' % i) for i in range(1, n+1)))
sigma,l = var('sigma, l')
f = sigma*e^(
    sum(vector([(n - m)^2 for n, m in zip(x1.coefficients(), x2.coefficients())]))
    *(-1/(2*length_scale)))

But what I actually want is this:

f(x1, x2) = sigma*e^(sum((x1[i]-x2[i])^2, i, 0, n))*(-1/(2*length_scale)))

So that, hopefully, I can do f.diff(x1) and it considers the sum etc. properly. The problem is that sum needs a variable, but x1[i] demands that i is an integer, so it can grab the elements from the vector.

Is there any obvious method I have missed, or is it not implemented in sage yet? -> If there is no such method, what would be good starting points for me to implement that myself?

Notes: For later processing I need the function to be a differentiable SageMath expression instead of e.g. a Python-function call. Further, it would be great (but not 100% required) to pass variable length vectors to f instead of specifying the length beforehand.

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
1

answered 4 years ago

Emmanuel Charpentier gravatar image

One possibility:

def f(a, b, sigma=1, l=1): return sigma^2*exp(-1/(l^2)*sum(map(lambda u,v:(u-v)^2, a, b)))

Example of use :

sage: q=4
sage: X=vector([var("x_{}".format(u)) for u in range(q)])
sage: Y=vector([var("y_{}".format(u)) for u in range(q)])
sage: f(X,Y)
e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2)
sage: f(X,Y).diff(x_1)
-2*(x_1 - y_1)*e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2)
# Gradient of f(X,Y) as a function of X
sage: vector([f(X,Y).diff(u) for u in X])
(-2*(x_0 - y_0)*e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2), -2*(x_1 - y_1)*e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2), -2*(x_2 - y_2)*e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2), -2*(x_3 - y_3)*e^(-(x_0 - y_0)^2 - (x_1 - y_1)^2 - (x_2 - y_2)^2 - (x_3 - y_3)^2))

Is that what you seek ?

A "real-world" use might check for equality of lengths of a and b and raise a convenient exception if not satisfied...

Preview: (hide)
link

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 4 years ago

Seen: 593 times

Last updated: Feb 01 '21