Ask Your Question

Differentiating function with fluctuating number of variables

asked 2020-06-19 02:08:35 +0200

anonymous user


updated 2020-07-26 02:54:44 +0200

(Edit: I've changed the question somewhat - upon editing the code the problem seems to lie elsewhere.)

Let's say I have a vector space V of dimension n (which is variable) and a matrix M (also depending on n and other input), and I want to understand the derivative of the function v -> ||M*v|| at some vector v in V, and then evaluate it at tangent vectors.

As far as I can tell, the easiest way to do this is to use a symbolic vector v, then calculate ||M*v||, then take diff(), and then I can plug in a tangent vector.

So I would write something like

v = list(var('v_%d' % i) for i in range(1,n+1))
def f(*arg):
    L = []
    for var in arg:
    return (M*vector(L)).norm()

(which is clearly bad and going nowhere) but attempting something like this, diff(f) throws an error:

unable to convert <function f at 0x7f2b046c5b90> to a symbolic expression


f(*v) = (M*vector(v)).norm()

doesn't work either.

edit retag flag offensive close merge delete


I can't replicate it, can you provide your code ? Or at least a working example that produces the issue.

Florentin Jaffredo gravatar imageFlorentin Jaffredo ( 2020-06-19 16:12:35 +0200 )edit

Oops, I've changed the question - thank you very much.

bksadie gravatar imagebksadie ( 2020-06-19 17:18:47 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2020-06-20 14:01:37 +0200

Florentin Jaffredo gravatar image

diff only works on symbolic expression (elements of the symbolic ring SR), not on python objects like functions. But you are in luck because f(*v) is precisely an element of SR. So the correct syntax is f(*v).diff(v[i]).

As a side remark, f can be simplified a lot, by defining f = (M*vector(v)).norm(). In this case, f is a symbolic expression.

Here is a code that computes all the partial derivatives for some matrix M:

n = 3
v = list(var('v_%d' % i) for i in range(1, n+1))

M = Matrix([[1, 0, 0],
            [0, 1, 0],
            [0, 0, 1]])

f = (M*vector(v)).norm()

[diff(f, vi) for vi in v]

The output is:

[1/2*(v_1 + conjugate(v_1))/sqrt(abs(v_1)^2 + abs(v_2)^2 + abs(v_3)^2),
 1/2*(v_2 + conjugate(v_2))/sqrt(abs(v_1)^2 + abs(v_2)^2 + abs(v_3)^2),
 1/2*(v_3 + conjugate(v_3))/sqrt(abs(v_1)^2 + abs(v_2)^2 + abs(v_3)^2)]

Of course you can take the dot product of this list with any tangent vector.

edit flag offensive delete link more


Thanks so much; I'm struggling with the last step. If I set

v_1 = 1
v_2 = 2
v_3 = 3

Then how do I turn

[diff(f, vi) for vi in v]

into a list of numbers?

bksadie gravatar imagebksadie ( 2020-07-26 02:50:50 +0200 )edit

Once the list is transformed into a vector you can use substitute, which is called like this:

sage: v = vector([diff(f, vi) for vi in v])
sage: v.substitute({v_1: 1, v_2: 2, v_3: 3})
(1/14*sqrt(14), 1/7*sqrt(14), 3/14*sqrt(14))
Florentin Jaffredo gravatar imageFlorentin Jaffredo ( 2020-07-26 22:29:40 +0200 )edit

Your Answer

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

Add Answer

Question Tools

1 follower


Asked: 2020-06-19 02:08:35 +0200

Seen: 374 times

Last updated: Jul 26 '20