mpmath functions with vectors?

1,120 views
Skip to first unread message

ben

unread,
Jan 13, 2010, 9:20:44 PM1/13/10
to mpmath
I'm not seeing this in the documentation. Is it possible to use mpmath
functions with vectors, instead of using loops?
a = [2.0, 3.0]
b = [4.0, 5.0]
c = []
for n in range(len(a)):
c.append(gammainc(a[n],b[n]))
print c
[ mpf('0.091578194443670907'), mpf('0.24930403896616229') ]

replaced with:
a=[2.0, 3.0]
b=[4.0, 5.0]
c = gamminc(a,b)
print c

Thanks,

Ben

Fredrik Johansson

unread,
Jan 14, 2010, 12:54:43 AM1/14/10
to mpmath

No, this is not currently possible. However, a very easy way to do it
for individual functions is to wrap them with numpy.frompyfunc:

>>> from mpmath import gammainc
>>> from numpy import frompyfunc
>>> g = frompyfunc(gammainc, 2, 1)
>>> a = [2, 3]
>>> b = [4, 5]
>>> g(a, b)
array([0.0915781944436709, 0.249304038966162], dtype=object)

Fredrik

Scott

unread,
Feb 1, 2010, 10:56:35 AM2/1/10
to mpmath
Can this approach be extended to list of functions as they relate to
findroot ? This an extension of a question recently posted to the
sympy group.
Given a list of residuals (f1) and a list of degrees of freedom (x)
how can I create a function that will work with mpimath findroot ?

v/r

Scott
import numpy
import sympy, mpmath

sympy.var('x1,x2,a,b')
global a,b
f1=list([a*x1**2 + x2, b*5*x1**2 - 3*x1 + 2*x2 - 3])
x=list([x1,x2])
x0=numpy.array([.5,.5])
f=sympy.lambdify((x+[a,b]),f1)


def F(x):
global a,b #passing as args=a,b preferred
para=list([a,b])
args=x+para
return f(*args)# len(f)=len(x),type float

a=3
b=2
x01=numpy.copy(x0)
mpmath.findroot(F,x0)

How to best relate f1,x and para list is the question?

Scott

unread,
Feb 2, 2010, 1:35:57 PM2/2/10
to mpmath
Below is my fast and dirty approach for making an mpmath friendly
nonlinear system from one configured for scipy.optimize.fsolve.

Thanks for the tips.

import sympy as sy
import numpy

sy.var('x1,x2,a,b')
global a,b
# assume f_list is a "long" list of "functions" generated by another
sympy script
# f_list may contain more than 100 terms
f_list=list([a*x1**2 + x2, b*5*x1**2 - 3*x1 + 2*x2 - 3])
x=list([x1,x2])#degrees of freedom or unknowns
parameters=list([a,b])#knowns
x0=numpy.array([1,1])#
args=x+parameters
b=1
a=2
# make the symbolic functions more 'numerical'
F1=sy.lambdify(args,f_list)
#reshuffle F1 as an fsolve freindly function with global parameters
def F2(x):
global a,b
parameters=list([a,b])
args=tuple(x)+tuple(parameters)
return F1(*args)

#F2(x)-> F3(x1,x2) for mpmath.findroot
f3='def F3(%s):\n\treturn F2(tuple(%s))'%(str(x)[1:-1],str(x))
exec f3

print(sy.mpmath.findroot(F3,list(x0)))


Vinzent Steinberg

unread,
Mar 26, 2010, 12:54:36 PM3/26/10
to mpmath

Sorry for the late reply.

This is because findroot() does not support functions with vectors as
arguments, you need to "flatten" the arguments.

For example:

from mpmath import *
f = lambda x1, x2, a, b: [a*x1**2 + x2, b*5*x1**2 - 3*x1 + 2*x2 - 3]
myf = lambda x1, x2: f(x1, x2, 3, 2)
x0 = (0.5, 0.5)
print findroot(myf, x0)

Or in your case:

import sympy
import sympy.mpmath as mpmath

sympy.var('x1,x2,a,b')
f1 = [a*x1**2 + x2, b*5*x1**2 - 3*x1 + 2*x2 - 3]
x = [x1, x2]
x0 = [.5, .5]
f = sympy.lambdify((x + [a, b]),f1)

def F(x1, x2):
global a, b # passing as args=a,b preferred
return f(x1, x2, a, b)

a = 3
b = 2
print mpmath.findroot(F, x0)

I don't understand how 'args=a,b' could work, but I agree that using
globals is ugly. Alternatives are:

1. hardcode the parameters in a new function (like in my first
code listing)
2. create a simple class with a __call__ method that use the
parameters as attributes (so you can change them later without
redefining the function)

Hope this helps.

Vinzent

Vinzent Steinberg

unread,
Mar 26, 2010, 12:54:42 PM3/26/10
to mpmath
On Feb 1, 4:56 pm, Scott <scotta_2...@yahoo.com> wrote:

Sorry for the late reply.

Vinzent Steinberg

unread,
Mar 26, 2010, 12:57:12 PM3/26/10
to mpmath

Sorry, I missed this post for some reason, you already got the
solution. :)

Vinzent

Diogo

unread,
Dec 23, 2019, 4:24:24 PM12/23/19
to mpmath
I don't know if there is some difference, but I tested with the numpy.vectorize function and it works like the numpy.frompyfunc function.

>>> from numpy import vectorize
>>> from mpmath import gammainc
>>> a = [2.0, 3.0]
>>> b = [4.0, 5.0]
>>> c = vectorize(gammainc)
>>> c(a,b)
array([mpf('0.091578194443670907'), mpf('0.24930403896616229')], dtype=object)
Reply all
Reply to author
Forward
0 new messages