ASKSAGE: Sage Q&A Forum - Individual question feedhttp://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 01 Feb 2012 16:10:02 -0600generate_plot_points fails to evaluate points, while plot imaginary part of expressionhttp://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/Hello,
I solve cubic equation and try to plot imaginary part of its solutions (to find out,
at which intervals roots are purely real).
The code is something like this
var('a, b, P, E')
P_sols = solve(a*P + b*P**3 - E, P)
P1 = lambda E_: P_sols[0].rhs().subs({a:-5, b:5, E:E_}).n().imag()
plot(P1, [-10, 10])
Plot function (actually, generate_plot_command) fails to evaluate at points, where
image part is nearly zero (range approximately between -2 and 2).
verbose 0 (4190: plot.py, generate_plot_points) WARNING: When plotting,
failed to evaluate function at 39 points.
verbose 0 (4190: plot.py, generate_plot_points) Last error message:
'negative number cannot be raised to a fractional power'
But if I try to
evaluate this function directly
P1(0) # OK
P1(float(0)) # OK
it works OK.
I've found on ask-sage ([here](http://ask.sagemath.org/question/823/fast-numerical-plot-command-that-always-works)), that to create callables it is better to use fast_callable, but I still wonder, why I can call function directly, but plot() function cannot. I've looked into code of generate_plot_points and find there only
call line (x, f(x)), so I cannot understand, why it do not work.
I've already solved my practical issue with fast_callable(), but I'm still curious
about this behavior.
Thanks.Wed, 01 Feb 2012 10:09:50 -0600http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/Answer by DSM for <p>Hello,</p>
<p>I solve cubic equation and try to plot imaginary part of its solutions (to find out,
at which intervals roots are purely real).</p>
<p>The code is something like this</p>
<pre><code>var('a, b, P, E')
P_sols = solve(a*P + b*P**3 - E, P)
P1 = lambda E_: P_sols[0].rhs().subs({a:-5, b:5, E:E_}).n().imag()
plot(P1, [-10, 10])
</code></pre>
<p>Plot function (actually, generate_plot_command) fails to evaluate at points, where
image part is nearly zero (range approximately between -2 and 2). </p>
<pre><code>verbose 0 (4190: plot.py, generate_plot_points) WARNING: When plotting,
failed to evaluate function at 39 points.
verbose 0 (4190: plot.py, generate_plot_points) Last error message:
'negative number cannot be raised to a fractional power'
</code></pre>
<p>But if I try to
evaluate this function directly</p>
<pre><code>P1(0) # OK
P1(float(0)) # OK
</code></pre>
<p>it works OK.</p>
<p>I've found on ask-sage (<a href="http://ask.sagemath.org/question/823/fast-numerical-plot-command-that-always-works">here</a>), that to create callables it is better to use fast_callable, but I still wonder, why I can call function directly, but plot() function cannot. I've looked into code of generate_plot_points and find there only
call line (x, f(x)), so I cannot understand, why it do not work.</p>
<p>I've already solved my practical issue with fast_callable(), but I'm still curious
about this behavior.</p>
<p>Thanks.</p>
http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?answer=13224#post-id-13224While it's true that P1(float(0)) works, P1(float(-1)) doesn't:
sage: P1(float(-1))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: negative number cannot be raised to a fractional power
I'm not sure what the best way to avoid this problem would be. Probably we could get away with coercing the function argument to RDF instead of float before it's called-- making that one change in generate_plot_points got the function to plot without difficulty. It's already done in lots of places in plot.py, so maybe a few more wouldn't be a bad idea.
Wed, 01 Feb 2012 11:43:30 -0600http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?answer=13224#post-id-13224Comment by kcrisman for <p>While it's true that P1(float(0)) works, P1(float(-1)) doesn't:</p>
<pre><code>sage: P1(float(-1))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: negative number cannot be raised to a fractional power
</code></pre>
<p>I'm not sure what the best way to avoid this problem would be. Probably we could get away with coercing the function argument to RDF instead of float before it's called-- making that one change in generate_plot_points got the function to plot without difficulty. It's already done in lots of places in plot.py, so maybe a few more wouldn't be a bad idea.</p>
http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?comment=20365#post-id-20365It would be worth opening a ticket to at least try timings. If it doesn't slow anything down... so did it not get turned into a fast_callable because it was a lambda?Wed, 01 Feb 2012 16:10:02 -0600http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?comment=20365#post-id-20365Answer by Jason Grout for <p>Hello,</p>
<p>I solve cubic equation and try to plot imaginary part of its solutions (to find out,
at which intervals roots are purely real).</p>
<p>The code is something like this</p>
<pre><code>var('a, b, P, E')
P_sols = solve(a*P + b*P**3 - E, P)
P1 = lambda E_: P_sols[0].rhs().subs({a:-5, b:5, E:E_}).n().imag()
plot(P1, [-10, 10])
</code></pre>
<p>Plot function (actually, generate_plot_command) fails to evaluate at points, where
image part is nearly zero (range approximately between -2 and 2). </p>
<pre><code>verbose 0 (4190: plot.py, generate_plot_points) WARNING: When plotting,
failed to evaluate function at 39 points.
verbose 0 (4190: plot.py, generate_plot_points) Last error message:
'negative number cannot be raised to a fractional power'
</code></pre>
<p>But if I try to
evaluate this function directly</p>
<pre><code>P1(0) # OK
P1(float(0)) # OK
</code></pre>
<p>it works OK.</p>
<p>I've found on ask-sage (<a href="http://ask.sagemath.org/question/823/fast-numerical-plot-command-that-always-works">here</a>), that to create callables it is better to use fast_callable, but I still wonder, why I can call function directly, but plot() function cannot. I've looked into code of generate_plot_points and find there only
call line (x, f(x)), so I cannot understand, why it do not work.</p>
<p>I've already solved my practical issue with fast_callable(), but I'm still curious
about this behavior.</p>
<p>Thanks.</p>
http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?answer=13225#post-id-13225Interesting:
sage: float(-1)^(1/3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/Users/grout/projects/HLA2/<ipython console> in <module>()
/Users/grout/sage-trees/sage-5.0.beta1/local/lib/python2.7/site-packages/sage/rings/rational.so in sage.rings.rational.Rational.__pow__ (sage/rings/rational.c:17026)()
ValueError: negative number cannot be raised to a fractional power
sage: RDF(-1)^(1/3)
NaN
In other words, having an RDF just doesn't give the error.
Wed, 01 Feb 2012 15:45:15 -0600http://ask.sagemath.org/question/8686/generate_plot_points-fails-to-evaluate-points-while-plot-imaginary-part-of-expression/?answer=13225#post-id-13225