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.

Reply via email to