Comment #6 on issue 3250 by [email protected]: simplify() results in loss of
precision
http://code.google.com/p/sympy/issues/detail?id=3250
It appears that mpf has a limit to what it accepts but make_mpf can be used
to create an mpf for an arbitrarily large number:
See how the _mpf_ of each of these is the same
mpf(pi.n(100))._mpf_
(0, 884279719003555L, -48, 50)
mpf(pi.n(70))._mpf_
(0, 884279719003555L, -48, 50)
but this one is smaller
mpf(pi.n(10))._mpf_
(0, 26986075409L, -33, 35)
Now see how _to_mpmath, which uses make_mpf behaves:
n=pi.n(10); prec = n._mpf_[-1]; n._to_mpmath(prec)._mpf_
(0, 26986075409L, -33, 35)
n=pi.n(70);n._to_mpmath(n._mpf_[-1])._mpf_
(0,
86729902480069714613016830152924028075550407726381404390042341022000049L,
-234, 236)
So if that function, rather than mpf is used when possible, and the
conversion back to sympy uses the prec='' option for Float then it will be
possible to recover the extended precision of the original number.
I can't quite work out how to make the change, however. Here's what I have.
I can define a function named MPmatRealType that produces the desired mpf:
from sympy.mpmath import mpf
def MPmathRealType(a):
... if hasattr(a, '_mpf_'):
... prec = a._mpf_[-1]
... else:
... prec = 1
... if hasattr(a, '_to_mpmath'):
... return a._to_mpmath(prec)
... else:
... return mpf(a)
f=MPmathRealType
f(1) # non-sympy input
mpf('1.0')
f(Float(3.2)) # sympy Float
mpf('3.2000000000000002')
f(pi.n(2))
mpf('3.140625')
f(pi.n(100))
mpf('3.1415926535897932')
If you unpack with Float, you only get 15 digits
Float(_)
3.14159265358979
But if you unpack with the prec='' option you can keep all the digits
f(pi.n(100))
mpf('3.1415926535897932')
Float(_,'')
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
BUT....when I put it in place I can't figure out why it gives the error
that it does.
simplify(pi.n(10)*x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "sympy/simplify/simplify.py", line 3019, in simplify
expr1 = cancel(expr0)
File "sympy/polys/polytools.py", line 5670, in cancel
(F, G), opt = parallel_poly_from_expr((p, q), *gens, **args)
File "sympy/polys/polytools.py", line 3836, in parallel_poly_from_expr
return _parallel_poly_from_expr(exprs, opt)
File "sympy/polys/polytools.py", line 3908, in _parallel_poly_from_expr
domain, coeffs_list = construct_domain(coeffs_list, opt=opt)
File "sympy/polys/constructor.py", line 217, in construct_domain
result = _construct_simple(coeffs, opt)
File "sympy/polys/constructor.py", line 55, in _construct_simple
result.append(domain.from_sympy(coeff))
File "sympy/polys/domains/realdomain.py", line 132, in from_sympy
return self.dtype(b)
TypeError: MPmathRealType() takes exactly 1 argument (2 given)
Whereas MPmathRealType was formerly defined in groundtypes.py as
from sympy.mpmath import mpf as MPmathRealType
now it is defined as the function above in that same file. I don't get what
I'm doing wrong. mpf is a function that takes a single argument; the new
function I defined takes a single argument. Can anyone help? This is in my
3250 branch, the last commit.
--
You received this message because you are subscribed to the Google Groups
"sympy-issues" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy-issues?hl=en.