high-precision numerical solver

76 views
Skip to first unread message

Colin Macdonald

unread,
Jan 13, 2015, 6:00:10 AM1/13/15
to sy...@googlegroups.com
I'd like to solve SymPy expressions to high (arbitrary) precision.  I tried `nsolve` with `mpmath.mp.dps = 128`, and filed #8564,
as nsolve is currently limited to double precision.

My current idea is to convert my expression to an lambda involving only mpmath objects.  Then call `mpmath.mp.findroot`.  This is essentially what nsolve does anyway (except for the part about "only mpmath" objects).

How do I do that?  `lambdify(x, expr, module=mpmath)` is limited to double-precision (filed #8818, but not sure if this is by design or a bug).

`mpmath.mpmathify` works for individual floats...

Best I have so far is something like:

````
d = 128    %  precision desired.
g = sqrt(2) - x   % I want to solve g == 0 for x

% here's my approach
h = g.evalf(d)
f = lambda meh: h.subs(x, meh)   % yuck

q = mpmath.mp.findroot(f, 1.0)

q*q   % should be 2 to 128 digits, looks good:
% mpf('2.000000000000000000000000000000000000000000000000000000000000000038')
````

thanks,
Colin

Aaron Meurer

unread,
Jan 29, 2015, 4:12:27 PM1/29/15
to sy...@googlegroups.com
I'd say nsolve and lambdify should be able to do it. Especially for lambdify, I don't see the point of using mpmath if you aren't going to support arbitrary precision.

Aaron Meurer

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/bd276484-1f37-4d29-b9b4-2cfbbee3fb5c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Colin Macdonald

unread,
Jan 29, 2015, 7:46:13 PM1/29/15
to sy...@googlegroups.com
On 29/01/15 13:12, Aaron Meurer wrote:
> I'd say nsolve and lambdify should be able to do it. Especially for
> lambdify, I don't see the point of using mpmath if you aren't going to
> support arbitrary precision.

Yes nsolve definitely should work with arbitrary precision (#8564)

I was unsure about lambdify, I don't really understand precisely what it
is supposed to do. So thanks for your comment. Presumably speed is
important: perhaps it should do different things depending on whether
the inputs have more than 15 digits precision.

@moorepants in #8818 suggests some refactoring, but I'm not sure when
I'll get to any of this :( I worked around it in octsympy, by avoiding
nsolve (and lambdify), and working with mpmath.mp.findroot directly.

Colin


signature.asc

Aaron Meurer

unread,
Jan 29, 2015, 11:43:02 PM1/29/15
to sy...@googlegroups.com
On Thu, Jan 29, 2015 at 6:46 PM, Colin Macdonald <macd...@maths.ox.ac.uk> wrote:
On 29/01/15 13:12, Aaron Meurer wrote:
> I'd say nsolve and lambdify should be able to do it. Especially for
> lambdify, I don't see the point of using mpmath if you aren't going to
> support arbitrary precision.

Yes nsolve definitely should work with arbitrary precision (#8564)

I was unsure about lambdify, I don't really understand precisely what it
is supposed to do.  So thanks for your comment.  Presumably speed is
important: perhaps it should do different things depending on whether
the inputs have more than 15 digits precision.

lambdify just creates a lambda function in the namespace of the given module. So lambdify(x, sympy.sin(x), 'mpmath') creates effectively lambda x: mpmath.sin(x). Editing the mpmath precision should affect the output (does it not?). Note that pure mpmath uses a global precision, which is a little harder to work with than Float. 

Aaron Meurer


@moorepants in #8818 suggests some refactoring, but I'm not sure when
I'll get to any of this :(  I worked around it in octsympy, by avoiding
nsolve (and lambdify), and working with mpmath.mp.findroot directly.

Colin


--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
Reply all
Reply to author
Forward
0 new messages