Processing math: 100%

First time here? Check out the FAQ!

Ask Your Question
1

Differentiating function with fluctuating number of variables

asked 4 years ago

anonymous user

Anonymous

updated 4 years ago

(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:
        L.append(var)
    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

Trying

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

doesn't work either.

Preview: (hide)

Comments

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 ( 4 years ago )

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

bksadie gravatar imagebksadie ( 4 years ago )

1 Answer

Sort by » oldest newest most voted
3

answered 4 years ago

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.

Preview: (hide)
link

Comments

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 ( 4 years ago )

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 ( 4 years ago )

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

Stats

Asked: 4 years ago

Seen: 444 times

Last updated: Jul 26 '20