seems to be a problem/difference in calculating with the new fractions

module when comparing Python 26rc2 and 30rc1

I was

reading the paper " href="http://conference.scipy.org/proceedings/SciPy2008/paper_3/full_text.pdf">Interval

Arithmetic: Python Implementation and Applications" and

thought to try the first example function f(x,y), which needs more

precision than Python floating point provides (on my Windows PC), to

calculate a sensible answer.

Ahah, I thought, lets

try this with Fractions - so I first installed Python 30rc1, typed in

the Function - saw the rubbish result, then used Fractions and got the

'right' result.

I then wondered if fractions had been

back-ported to Python 2.6rc2, found that it had, but got different

results.

As you can see from the table, Python

2.6rc2 has a problem calculating t3 = F(11,2) * y**8 + x/(2*y), where F

is Fraction.

I wonder where the problem

lies?

style="white-space: nowrap; text-align: left; vertical-align: top;">Python 3.0rc1 (r30rc1:66507, Sep 18 2008, 14:47:08) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from fractions import Fraction as F >>> def f(x,y): ... return ( ... (333.75 - x**2)* y**6 + x**2 * ... (11* x**2 * y**2 - 121 * y**4 - 2) ... + 5.5 * y**8 + x/(2*y)) ... >>> f(77617.0, 33096.0) 1.1726039400531787 >>> def f2(x,y): ... return ( ... (333 + F(3,4) - x**2)* y**6 + x**2 * ... (11* x**2 * y**2 - 121 * y**4 - 2) ... + F(11,2) * y**8 + x/(2*y)) ... >>> f2(77617.0, 33096.0) 1.1726039400531787 >>> f2(77617, 33096) -0.82739605994682131 >>> x,y = 77617, 33096 >>> t1 = (333 + F(3,4) - x**2)* y**6 + x**2 >>> t1 Fraction(-7917110903377385049079188231255750815, 1) >>> t2 = (11* x**2 * y**2 - 121 * y**4 - 2) >>> t2 -72586759091903445314 >>> t3 = F(11,2) * y**8 + x/(2*y) >>> t3 7.9171113406689609e+36 >>> | style="white-space: nowrap; text-align: left; vertical-align: top; width: 50%;">Python 2.6rc2 (r26rc2:66507, Sep 18 2008, 14:27:33) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. IDLE 2.6rc2 >>> from fractions import Fraction as F >>> def f(x,y): return ( (333.75 - x**2)* y**6 + x**2 * (11* x**2 * y**2 - 121 * y**4 - 2) + 5.5 * y**8 + x/(2*y)) >>> f(77617.0, 33096.0) 1.1726039400531787 >>> def f2(x,y): return ( (333 + F(3,4) - x**2)* y**6 + x**2 * (11* x**2 * y**2 - 121 * y**4 - 2) + F(11,2) * y**8 + x/(2*y)) >>> f2(77617.0, 33096.0) 1.1726039400531787 >>> f2(77617, 33096) style="background-color: rgb(255, 102, 102); font-weight: bold;">Fraction(-1, 1) >>> x,y = 77617, 33096 >>> t1 = (333 + F(3,4) - x**2)* y**6 + x**2 >>> t1 Fraction(-7917110903377385049079188231255750815, 1) >>> t2 = (11* x**2 * y**2 - 121 * y**4 - 2) >>> t2 -72586759091903445314L >>> t3 = F(11,2) * y**8 + x/(2*y) >>> t3 style="background-color: rgb(255, 102, 102); font-weight: bold;">Fraction(7917111340668961361101134701524942849, 1) >>> |

I suspect the problem is, as often with Python 2.x, the integer division (``1/2 == 0``), which has changed to ``1/2 == 0.5`` in Python 3.

ReplyDeleteTry writing the last factor in f2 as ``x/(2.0*y)``. If the result's still incorrect, please file a bug at http://bugs.python.org/.

Thanks Georg, that was it.

ReplyDeleteIf I add a line

from __future__ import division

to the 2.6 code and re-define f2, all is well.

This comment has been removed by a blog administrator.

ReplyDelete