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.Thu, 10 Mar 2016 08:33:28 -0600substitute() raises exception where python does nothttp://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/ In my usual workflow, I derive symbolic equations and then substitute their arguments by values stored in dictionaries to obtain numerical solutions. Now I found out that the substitute() command raises division by zero exception where standard python does not. This is a bit of a problem, as these exceptions prevent my code from evaluating all data sets once such an exception occurs and I don't want to wrap each line of code in a try-except construct. Does anyone know how the exception could be avoided? Here is an example:
var('y a x')
eq_y = y == a/x
vdict = {}
vdict[a] = 1.
vdict[x] = 0.
vdict[a]/vdict[x]
+infinity
However, if I substitute vdict into eq_y, I get an exception:
eq_y.subs(vdict)
Traceback (click to the left of this block for traceback)
...
ValueError: power::eval(): division by zero
Wed, 09 Mar 2016 08:23:25 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/Comment by vdelecroix for <p>In my usual workflow, I derive symbolic equations and then substitute their arguments by values stored in dictionaries to obtain numerical solutions. Now I found out that the substitute() command raises division by zero exception where standard python does not. This is a bit of a problem, as these exceptions prevent my code from evaluating all data sets once such an exception occurs and I don't want to wrap each line of code in a try-except construct. Does anyone know how the exception could be avoided? Here is an example:</p>
<pre><code>var('y a x')
eq_y = y == a/x
vdict = {}
vdict[a] = 1.
vdict[x] = 0.
vdict[a]/vdict[x]
+infinity
</code></pre>
<p>However, if I substitute vdict into eq_y, I get an exception:</p>
<pre><code>eq_y.subs(vdict)
Traceback (click to the left of this block for traceback)
...
ValueError: power::eval(): division by zero
</code></pre>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32749#post-id-32749You forgot to declare 'y' as a variable...Wed, 09 Mar 2016 09:08:14 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32749#post-id-32749Answer by vdelecroix for <p>In my usual workflow, I derive symbolic equations and then substitute their arguments by values stored in dictionaries to obtain numerical solutions. Now I found out that the substitute() command raises division by zero exception where standard python does not. This is a bit of a problem, as these exceptions prevent my code from evaluating all data sets once such an exception occurs and I don't want to wrap each line of code in a try-except construct. Does anyone know how the exception could be avoided? Here is an example:</p>
<pre><code>var('y a x')
eq_y = y == a/x
vdict = {}
vdict[a] = 1.
vdict[x] = 0.
vdict[a]/vdict[x]
+infinity
</code></pre>
<p>However, if I substitute vdict into eq_y, I get an exception:</p>
<pre><code>eq_y.subs(vdict)
Traceback (click to the left of this block for traceback)
...
ValueError: power::eval(): division by zero
</code></pre>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32751#post-id-32751Hello,
The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely
sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
I opened a discussion. But I think that the second example should raise the same error as the first one. See [this sage-devel thread](https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw).Wed, 09 Mar 2016 09:17:27 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32751#post-id-32751Comment by kcrisman for <p>Hello,</p>
<p>The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely</p>
<pre><code>sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
</code></pre>
<p>I opened a discussion. But I think that the second example should raise the same error as the first one. See <a href="https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw">this sage-devel thread</a>.</p>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32772#post-id-32772@vdelecroix - your example is what I was trying to show, `float(1.0)` gives native Python floats as in your example. Not sure why Python doesn't conform to IEEE, despite reading several sources. I believe Numpy behaves "correctly" in this case, see http://www.walkingrandomly.com/?p=5152#comment-667796Thu, 10 Mar 2016 08:33:28 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32772#post-id-32772Comment by stan for <p>Hello,</p>
<p>The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely</p>
<pre><code>sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
</code></pre>
<p>I opened a discussion. But I think that the second example should raise the same error as the first one. See <a href="https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw">this sage-devel thread</a>.</p>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32758#post-id-32758OK, thanks, I didn't realise that this is an inconsistency in sage (not throwing an exception for 1./0.). I agree that it should throw an exception, as it is not clear whether it should be +Infinity or -Infinity, since 0 is neither positive nor negative.Wed, 09 Mar 2016 09:44:13 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32758#post-id-32758Comment by vdelecroix for <p>Hello,</p>
<p>The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely</p>
<pre><code>sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
</code></pre>
<p>I opened a discussion. But I think that the second example should raise the same error as the first one. See <a href="https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw">this sage-devel thread</a>.</p>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32756#post-id-32756It is also Python choice
$ python -c "1. / 0."
Traceback (most recent call last):
File "<string>", line 1, in <module>
ZeroDivisionError: float division by zeroWed, 09 Mar 2016 09:27:40 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32756#post-id-32756Comment by kcrisman for <p>Hello,</p>
<p>The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely</p>
<pre><code>sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
</code></pre>
<p>I opened a discussion. But I think that the second example should raise the same error as the first one. See <a href="https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw">this sage-devel thread</a>.</p>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32755#post-id-32755Of course, http://www.walkingrandomly.com/?p=5152 points this out: `sage: float(1.0)/float(0.0)` so I don't know what we should do... I'd go with IEEE on this, since I assume the MPFR people know what they are doing - ?Wed, 09 Mar 2016 09:27:10 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32755#post-id-32755Comment by kcrisman for <p>Hello,</p>
<p>The problem comes from the fact that Sage floating point number behave differently than other numbers with respect to division by zero. Namely</p>
<pre><code>sage: 1 / 0
Traceback (most recent call last):
...
ZeroDivisionError: rational division by zero
sage: 1. / 0.
+infinity
</code></pre>
<p>I opened a discussion. But I think that the second example should raise the same error as the first one. See <a href="https://groups.google.com/forum/#!topic/sage-devel/8E64UHTLIRw">this sage-devel thread</a>.</p>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32754#post-id-32754Incorrect, at least not if we want to stay sort of close to IEEE specs for floating point stuff. See e.g. http://stackoverflow.com/questions/14682005/why-does-division-by-zero-in-ieee754-standard-results-in-infinite-valueWed, 09 Mar 2016 09:25:19 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32754#post-id-32754Answer by nbruin for <p>In my usual workflow, I derive symbolic equations and then substitute their arguments by values stored in dictionaries to obtain numerical solutions. Now I found out that the substitute() command raises division by zero exception where standard python does not. This is a bit of a problem, as these exceptions prevent my code from evaluating all data sets once such an exception occurs and I don't want to wrap each line of code in a try-except construct. Does anyone know how the exception could be avoided? Here is an example:</p>
<pre><code>var('y a x')
eq_y = y == a/x
vdict = {}
vdict[a] = 1.
vdict[x] = 0.
vdict[a]/vdict[x]
+infinity
</code></pre>
<p>However, if I substitute vdict into eq_y, I get an exception:</p>
<pre><code>eq_y.subs(vdict)
Traceback (click to the left of this block for traceback)
...
ValueError: power::eval(): division by zero
</code></pre>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32766#post-id-32766You can use `fast_callable` to compile a symbolic expression into something that evaluates more in the way of a python expression:
sage: fc=fast_callable(eq_y.rhs(),vars=[x,a])
sage: fc(0.0,1.0)
+infinity
Wed, 09 Mar 2016 16:44:51 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32766#post-id-32766Answer by kcrisman for <p>In my usual workflow, I derive symbolic equations and then substitute their arguments by values stored in dictionaries to obtain numerical solutions. Now I found out that the substitute() command raises division by zero exception where standard python does not. This is a bit of a problem, as these exceptions prevent my code from evaluating all data sets once such an exception occurs and I don't want to wrap each line of code in a try-except construct. Does anyone know how the exception could be avoided? Here is an example:</p>
<pre><code>var('y a x')
eq_y = y == a/x
vdict = {}
vdict[a] = 1.
vdict[x] = 0.
vdict[a]/vdict[x]
+infinity
</code></pre>
<p>However, if I substitute vdict into eq_y, I get an exception:</p>
<pre><code>eq_y.subs(vdict)
Traceback (click to the left of this block for traceback)
...
ValueError: power::eval(): division by zero
</code></pre>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32753#post-id-32753I see. You are using a *symbolic* equation in the latter case, which will definitely barf at dividing by zero, but the things you are putting in are "real literals".
sage: type(a)
<type 'sage.symbolic.expression.Expression'>
sage: type(vdict[a])
<type 'sage.rings.real_mpfr.RealLiteral'>
As such, they obey 'usual' division rules for floating-point things like
sage: vdict[x]/vdict[x]
NaN
So if you don't want mathematically correct behavior, I suggest not using a symbolic variable!
sage: eq_y = y == z
sage: def mysubs(a=.1,x=0.,eq=eq_y):
....: t = a/x
....: return eq.subs(z=t)
....:
sage: mysubs()
y == +infinity
sage: mysubs(.0,.0)
y == NaN
Indeed, we get
sage: vdict = {}
sage: vdict['a'] = 0.
sage: vdict['x'] = 0.
sage: mysubs(**vdict)
y == NaN
Wed, 09 Mar 2016 09:23:53 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?answer=32753#post-id-32753Comment by stan for <p>I see. You are using a <em>symbolic</em> equation in the latter case, which will definitely barf at dividing by zero, but the things you are putting in are "real literals".</p>
<pre><code>sage: type(a)
<type 'sage.symbolic.expression.Expression'>
sage: type(vdict[a])
<type 'sage.rings.real_mpfr.RealLiteral'>
</code></pre>
<p>As such, they obey 'usual' division rules for floating-point things like</p>
<pre><code>sage: vdict[x]/vdict[x]
NaN
</code></pre>
<p>So if you don't want mathematically correct behavior, I suggest not using a symbolic variable!</p>
<pre><code>sage: eq_y = y == z
sage: def mysubs(a=.1,x=0.,eq=eq_y):
....: t = a/x
....: return eq.subs(z=t)
....:
sage: mysubs()
y == +infinity
sage: mysubs(.0,.0)
y == NaN
</code></pre>
<p>Indeed, we get</p>
<pre><code>sage: vdict = {}
sage: vdict['a'] = 0.
sage: vdict['x'] = 0.
sage: mysubs(**vdict)
y == NaN
</code></pre>
http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32759#post-id-32759Thanks for this, but this involves re-writing the original symbolic equation inside the function, so it defeats my purpose of using a symbolic equation in the first place. Anyway, the explanations given above will help me formulate the real problem, which is how to catch such exceptions in a code while continuing with the evaluation. I'll post it shortly.Wed, 09 Mar 2016 09:51:33 -0600http://ask.sagemath.org/question/32744/substitute-raises-exception-where-python-does-not/?comment=32759#post-id-32759