multidimensional rootfinding

26 views
Skip to first unread message

Vincent

unread,
Jul 19, 2009, 4:44:27 PM7/19/09
to mpmath
I would like to find a root of a function f.
This function computes its result as a sympy.Matrix, and then takes a
slice of it and compare it with a numpy.array, which yields a (1
dimensional) array of sympy.core.numbers.Real .

But as it is not an mpmath.matrix (nor a tuple nor a list), findroot()
fails to recognize it a multidimensional. I worked around it by
"tuplifying" the result. Wouldn't there be a more "foolproof" way,
such as testing for the result to be iterable ?

Symmetrically, findroot only accepts functions having explicitely
several variables. Wouldn't there be a simple way to accept also
vector functions ?


But now I have strange errors I still have to figure out. Can there be
a problem with mpmath failing to convert sympy.core.numbers.Real to
mpmath.mpf ?

I put a traceback here in the hope someone recognizes a known problem,
but don't loose your time on it. I will further investigate when I
have the time to.



In [60]: findroot(f1,(0.99,2.2),multidimensional=True)
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (95, 0))

---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)

/home/v/python/<ipython console> in <module>()

/usr/lib/python2.5/site-packages/mpmath/mptypes.pyc in g(*args,
**kwargs)
66 return +v
67 else:
---> 68 return f(*args, **kwargs)
69 finally:
70 self.mp.prec = orig

/usr/lib/python2.5/site-packages/mpmath/optimization.pyc in findroot
(f, x0, solver, tol, verbose, verify, force_type, **kwargs)
942 maxsteps = iterations.maxsteps
943 i = 0
--> 944 for x, error in iterations:
945 if verbose:
946 print 'x: ', x

/usr/lib/python2.5/site-packages/mpmath/optimization.pyc in __iter__
(self)
657 cancel = True
658 break
--> 659 fx = matrix(f(*x1))
660 newnorm = norm(fx)
661 if newnorm < fxnorm:

/usr/lib/python2.5/site-packages/mpmath/matrices.pyc in __init__(self,
*args, **kwargs)
312 self.__cols = 1
313 for i, e in enumerate(v):
--> 314 self[i, 0] = e
315 elif isinstance(args[0], int):
316 # create empty matrix of given dimensions

/usr/lib/python2.5/site-packages/mpmath/matrices.pyc in __setitem__
(self, key, value)
430 raise IndexError('matrix index out of range')
431 if self.force_type: # and not isinstance(value,
self.force_type):
--> 432 value = self.force_type(value)
433 if value: # only store non-zeros
434 self.__data[key] = value

/usr/lib/python2.5/site-packages/mpmath/mptypes.pyc in convert(ctx, x,
strings)
361 if hasattr(x, '_mpmath_'):
362 return ctx.convert(x._mpmath_(*prec_rounding))
--> 363 raise TypeError("cannot create mpf from " + repr(x))
364
365 def isnan(ctx, x):

Vinzent Steinberg

unread,
Jul 23, 2009, 8:28:06 AM7/23/09
to mpmath
On Jul 19, 10:44 pm, Vincent <vin....@gmx.net> wrote:
> I would like to find a root of a function f.
> This function computes its result as a sympy.Matrix, and then takes a
> slice of it and compare it with a numpy.array, which yields a (1
> dimensional) array of sympy.core.numbers.Real .
>
> But as it is not an mpmath.matrix (nor a tuple nor a list), findroot()
> fails to recognize it a multidimensional. I worked around it by
> "tuplifying" the result. Wouldn't there be a more "foolproof" way,
> such as testing for the result to be iterable ?

Currently findroot only expects mpmath types, use nsolve() in sympy if
you are using sympy types.

>
> Symmetrically, findroot only accepts functions having explicitely
> several variables. Wouldn't there be a simple way to accept also
> vector functions ?

It also accepts vector functions, if the docstring is not clear about
this, it's a bug.

>
> But now I have strange errors I still have to figure out. Can there be
> a problem with mpmath failing to convert sympy.core.numbers.Real to
> mpmath.mpf ?
>

Feel free to creat an issue for this. :-)

> I put a traceback here in the hope someone recognizes a known problem,
> but don't loose your time on it. I will further investigate when I
> have the time to.
>
> In [60]: findroot(f1,(0.99,2.2),multidimensional=True)

This keyword does not exist.
I'll have a closer look when I'm back.

Vinzent

Vinzent Steinberg

unread,
Jul 30, 2009, 7:20:22 PM7/30/09
to mpmath
On Jul 23, 2:28 pm, Vinzent Steinberg
<vinzent.steinb...@googlemail.com> wrote:
> On Jul 19, 10:44 pm, Vincent <vin....@gmx.net> wrote:
>
> > I would like to find a root of a function f.
> > This function computes its result as a sympy.Matrix, and then takes a
> > slice of it and compare it with a numpy.array, which yields a (1
> > dimensional) array of sympy.core.numbers.Real .
>
> > But as it is not an mpmath.matrix (nor a tuple nor a list), findroot()
> > fails to recognize it a multidimensional. I worked around it by
> > "tuplifying" the result. Wouldn't there be a more "foolproof" way,
> > such as testing for the result to be iterable ?

Internally mpmath.matrix tries to call .tolist() (actually that what
you call "tuplifying"), so it should be able to convert numpy and
sympy matrices. mpmathify() is possibly not clever about this, and it
fails anyway on the scalar part.

>
> Currently findroot only expects mpmath types, use nsolve() in sympy if
> you are using sympy types.
>
>
>
> > Symmetrically, findroot only accepts functions having explicitely
> > several variables. Wouldn't there be a simple way to accept also
> > vector functions ?
>
> It also accepts vector functions, if the docstring is not clear about
> this, it's a bug.
>
>
>
> > But now I have strange errors I still have to figure out. Can there be
> > a problem with mpmath failing to convert sympy.core.numbers.Real to
> > mpmath.mpf ?
>
> Feel free to creat an issue for this. :-)

I did so, see http://code.google.com/p/mpmath/issues/detail?id=154. A
workaround for integers and floats is to convert them to strings. (In
this case, convert the sympy matrix to a list, then convert all sympy
numbers in the nested lists to strings.)

>
> > I put a traceback here in the hope someone recognizes a known problem,
> > but don't loose your time on it. I will further investigate when I
> > have the time to.
>
> > In [60]: findroot(f1,(0.99,2.2),multidimensional=True)
>
> This keyword does not exist.

Actually it does, sorry, I should know my own code better. However, it
should not be necessary to specify it (you can use it to force a
multidimensional solver for the onedimensional case). The problem is
the communication between sympy and mpmath, like you said, and this is
what the traceback is indicating.

Vinzent

Vinzent Steinberg

unread,
Aug 14, 2009, 5:13:04 AM8/14/09
to mpmath
I spent some work on communication between sympy and mpmath. I had to
fix the conversion of sympy's Rational and Integer to mpf, however
Real was already working. mpmathify() recognizes matrices in current
svn mpmath, but you can just use mpmath.matrix, it recognizes matrices
in older versions too.

Complex sympy numbers are not yet recognized by mpmath, but until it's
fixed you can easily work around this writing your own function for
conversion.

> Symmetrically, findroot only accepts functions having explicitely
> several variables. Wouldn't there be a simple way to accept also
> vector functions ?

Is this what you want? (Taken from the docstring.)

>>> def f(x1, x2):
... return x1**2 + x2, 5*x1**2 - 3*x1 + 2*x2 - 3
...
>>> findroot(f, (0, 0))
matrix(
[['-0.618033988749895'],
['-0.381966011250105']])

If not, please tell me how the syntax could be made more general.

> Wouldn't there be a more "foolproof" way,
> such as testing for the result to be iterable

Testing which result?

Please post your function, so I can debug the traceback.

Vinzent
Reply all
Reply to author
Forward
0 new messages