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.Thu, 06 Sep 2012 13:37:42 +0200Limits with dictionarieshttps://ask.sagemath.org/question/9301/limits-with-dictionaries/Suppose I have a dictionary that is the result of a `solve` command, for example, `D={n1:2}`
I also have an expression stored, for example, `expr1 = 3*n1^2`
In this example, I want to find the limit of `expr1` as `n1 -> 2`.
How can I do this given some expression and some dictionary in general?
I haven't figured it out with `sage_eval` yet.
(I know that if it were just substitution, I could use `expr1.subs_expr(D)` but I have cases where I believe I need to use limits instead of substitution.)
Thanks!Thu, 06 Sep 2012 13:12:00 +0200https://ask.sagemath.org/question/9301/limits-with-dictionaries/Answer by DSM for <p>Suppose I have a dictionary that is the result of a <code>solve</code> command, for example, <code>D={n1:2}</code></p>
<p>I also have an expression stored, for example, <code>expr1 = 3*n1^2</code></p>
<p>In this example, I want to find the limit of <code>expr1</code> as <code>n1 -> 2</code>.</p>
<p>How can I do this given some expression and some dictionary in general?
I haven't figured it out with <code>sage_eval</code> yet.</p>
<p>(I know that if it were just substitution, I could use <code>expr1.subs_expr(D)</code> but I have cases where I believe I need to use limits instead of substitution.)</p>
<p>Thanks!</p>
https://ask.sagemath.org/question/9301/limits-with-dictionaries/?answer=14010#post-id-14010Hmm, this is kind of fun! First the setup:
sage: n1 = var("n1")
sage: sols = solve(n1*2 == 4, n1, solution_dict=True)
sage: sols
[{n1: 2}]
sage: d = sols[0]
sage: d
{n1: 2}
sage: expr1 = 3*n1^2
In general, you can turn a dictionary into extra keyword arguments by using the `**` operator, for example:
sage: def f(*args, **kwargs):
....: print args, kwargs
....:
sage: f(2,3,4,fred=97)
(2, 3, 4) {'fred': 97}
sage: fdict = {'fred': 13, 'bob': 28}
sage: f(**fdict)
() {'bob': 28, 'fred': 13}
So at first I thought this would work:
sage: limit(expr1, **d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/mcneil/m2/<ipython console> in <module>()
TypeError: limit() keywords must be strings
but it needs variable *names*, not the variables themselves. Well, we can do that too, using a dict comprehension to build a temporary dictionary:
sage: d_named = {str(variable): value for variable, value in d.iteritems()}
sage: d_named
{'n1': 2}
sage: limit(expr1, **d_named)
12
Thu, 06 Sep 2012 13:28:40 +0200https://ask.sagemath.org/question/9301/limits-with-dictionaries/?answer=14010#post-id-14010Comment by kcrisman for <p>Hmm, this is kind of fun! First the setup:</p>
<pre><code>sage: n1 = var("n1")
sage: sols = solve(n1*2 == 4, n1, solution_dict=True)
sage: sols
[{n1: 2}]
sage: d = sols[0]
sage: d
{n1: 2}
sage: expr1 = 3*n1^2
</code></pre>
<p>In general, you can turn a dictionary into extra keyword arguments by using the <code>**</code> operator, for example:</p>
<pre><code>sage: def f(*args, **kwargs):
....: print args, kwargs
....:
sage: f(2,3,4,fred=97)
(2, 3, 4) {'fred': 97}
sage: fdict = {'fred': 13, 'bob': 28}
sage: f(**fdict)
() {'bob': 28, 'fred': 13}
</code></pre>
<p>So at first I thought this would work:</p>
<pre><code>sage: limit(expr1, **d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/mcneil/m2/<ipython console> in <module>()
TypeError: limit() keywords must be strings
</code></pre>
<p>but it needs variable <em>names</em>, not the variables themselves. Well, we can do that too, using a dict comprehension to build a temporary dictionary:</p>
<pre><code>sage: d_named = {str(variable): value for variable, value in d.iteritems()}
sage: d_named
{'n1': 2}
sage: limit(expr1, **d_named)
12
</code></pre>
https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19103#post-id-19103BTW, you two should meet someday at a Sage Days or something. I've think you've both worked on some of the same tickets in special functions!Thu, 06 Sep 2012 13:34:17 +0200https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19103#post-id-19103Comment by DSM for <p>Hmm, this is kind of fun! First the setup:</p>
<pre><code>sage: n1 = var("n1")
sage: sols = solve(n1*2 == 4, n1, solution_dict=True)
sage: sols
[{n1: 2}]
sage: d = sols[0]
sage: d
{n1: 2}
sage: expr1 = 3*n1^2
</code></pre>
<p>In general, you can turn a dictionary into extra keyword arguments by using the <code>**</code> operator, for example:</p>
<pre><code>sage: def f(*args, **kwargs):
....: print args, kwargs
....:
sage: f(2,3,4,fred=97)
(2, 3, 4) {'fred': 97}
sage: fdict = {'fred': 13, 'bob': 28}
sage: f(**fdict)
() {'bob': 28, 'fred': 13}
</code></pre>
<p>So at first I thought this would work:</p>
<pre><code>sage: limit(expr1, **d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/mcneil/m2/<ipython console> in <module>()
TypeError: limit() keywords must be strings
</code></pre>
<p>but it needs variable <em>names</em>, not the variables themselves. Well, we can do that too, using a dict comprehension to build a temporary dictionary:</p>
<pre><code>sage: d_named = {str(variable): value for variable, value in d.iteritems()}
sage: d_named
{'n1': 2}
sage: limit(expr1, **d_named)
12
</code></pre>
https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19101#post-id-19101@kcrisman: it might be a limitation that we don't have a way to pass a dictionary, but it's not a bug pe se. Functions can only have strings as argument names, not general objects, which makes sense in retrospect.Thu, 06 Sep 2012 13:37:42 +0200https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19101#post-id-19101Comment by kcrisman for <p>Hmm, this is kind of fun! First the setup:</p>
<pre><code>sage: n1 = var("n1")
sage: sols = solve(n1*2 == 4, n1, solution_dict=True)
sage: sols
[{n1: 2}]
sage: d = sols[0]
sage: d
{n1: 2}
sage: expr1 = 3*n1^2
</code></pre>
<p>In general, you can turn a dictionary into extra keyword arguments by using the <code>**</code> operator, for example:</p>
<pre><code>sage: def f(*args, **kwargs):
....: print args, kwargs
....:
sage: f(2,3,4,fred=97)
(2, 3, 4) {'fred': 97}
sage: fdict = {'fred': 13, 'bob': 28}
sage: f(**fdict)
() {'bob': 28, 'fred': 13}
</code></pre>
<p>So at first I thought this would work:</p>
<pre><code>sage: limit(expr1, **d)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/mcneil/m2/<ipython console> in <module>()
TypeError: limit() keywords must be strings
</code></pre>
<p>but it needs variable <em>names</em>, not the variables themselves. Well, we can do that too, using a dict comprehension to build a temporary dictionary:</p>
<pre><code>sage: d_named = {str(variable): value for variable, value in d.iteritems()}
sage: d_named
{'n1': 2}
sage: limit(expr1, **d_named)
12
</code></pre>
https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19104#post-id-19104Hmm, nice answer. Is this a bug, perhaps? I also note that `sage: limit(expr1,sols[0].items[0][0]=sols[0].items[0][1])` doesn't work.Thu, 06 Sep 2012 13:33:41 +0200https://ask.sagemath.org/question/9301/limits-with-dictionaries/?comment=19104#post-id-19104