ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Sun, 26 Jul 2020 22:29:40 +0200Differentiating function with fluctuating number of variableshttps://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/(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.Fri, 19 Jun 2020 02:08:35 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/Comment by Florentin Jaffredo for <p>(Edit: I've changed the question somewhat - upon editing the code the problem seems to lie elsewhere.)</p>
<p>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.</p>
<p>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.</p>
<p>So I would write something like</p>
<pre><code>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()
</code></pre>
<p>(which is clearly bad and going nowhere) but attempting something like this, diff(f) throws an error:</p>
<pre><code>unable to convert <function f at 0x7f2b046c5b90> to a symbolic expression
</code></pre>
<p>Trying </p>
<pre><code>f(*v) = (M*vector(v)).norm()
</code></pre>
<p>doesn't work either.</p>
https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52094#post-id-52094I can't replicate it, can you provide your code ? Or at least a working example that produces the issue.Fri, 19 Jun 2020 16:12:35 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52094#post-id-52094Comment by bksadie for <p>(Edit: I've changed the question somewhat - upon editing the code the problem seems to lie elsewhere.)</p>
<p>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.</p>
<p>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.</p>
<p>So I would write something like</p>
<pre><code>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()
</code></pre>
<p>(which is clearly bad and going nowhere) but attempting something like this, diff(f) throws an error:</p>
<pre><code>unable to convert <function f at 0x7f2b046c5b90> to a symbolic expression
</code></pre>
<p>Trying </p>
<pre><code>f(*v) = (M*vector(v)).norm()
</code></pre>
<p>doesn't work either.</p>
https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52097#post-id-52097Oops, I've changed the question - thank you very much.Fri, 19 Jun 2020 17:18:47 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52097#post-id-52097Answer by Florentin Jaffredo for <p>(Edit: I've changed the question somewhat - upon editing the code the problem seems to lie elsewhere.)</p>
<p>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.</p>
<p>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.</p>
<p>So I would write something like</p>
<pre><code>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()
</code></pre>
<p>(which is clearly bad and going nowhere) but attempting something like this, diff(f) throws an error:</p>
<pre><code>unable to convert <function f at 0x7f2b046c5b90> to a symbolic expression
</code></pre>
<p>Trying </p>
<pre><code>f(*v) = (M*vector(v)).norm()
</code></pre>
<p>doesn't work either.</p>
https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?answer=52122#post-id-52122``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.
Sat, 20 Jun 2020 14:01:37 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?answer=52122#post-id-52122Comment by Florentin Jaffredo for <p><code>diff</code> only works on symbolic expression (elements of the symbolic ring <code>SR</code>), not on python objects like functions. But you are in luck because <code>f(*v)</code> is precisely an element of <code>SR</code>. So the correct syntax is <code>f(*v).diff(v[i])</code>.</p>
<p>As a side remark, <code>f</code> can be simplified a lot, by defining <code>f = (M*vector(v)).norm()</code>. In this case, <code>f</code> is a symbolic expression.</p>
<p>Here is a code that computes all the partial derivatives for some matrix M:</p>
<pre><code>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]
</code></pre>
<p>The output is:</p>
<pre><code>[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)]
</code></pre>
<p>Of course you can take the dot product of this list with any tangent vector.</p>
https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52703#post-id-52703Once 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))Sun, 26 Jul 2020 22:29:40 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52703#post-id-52703Comment by bksadie for <p><code>diff</code> only works on symbolic expression (elements of the symbolic ring <code>SR</code>), not on python objects like functions. But you are in luck because <code>f(*v)</code> is precisely an element of <code>SR</code>. So the correct syntax is <code>f(*v).diff(v[i])</code>.</p>
<p>As a side remark, <code>f</code> can be simplified a lot, by defining <code>f = (M*vector(v)).norm()</code>. In this case, <code>f</code> is a symbolic expression.</p>
<p>Here is a code that computes all the partial derivatives for some matrix M:</p>
<pre><code>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]
</code></pre>
<p>The output is:</p>
<pre><code>[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)]
</code></pre>
<p>Of course you can take the dot product of this list with any tangent vector.</p>
https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52680#post-id-52680Thanks 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?Sun, 26 Jul 2020 02:50:50 +0200https://ask.sagemath.org/question/52075/differentiating-function-with-fluctuating-number-of-variables/?comment=52680#post-id-52680