[SciPy-user] error at optimize.fmin

Gabriel Gellner ggellner at uoguelph.ca
Wed Jun 18 09:12:55 EDT 2008


On Wed, Jun 18, 2008 at 02:30:21AM -0700, Jose Lopez wrote:
>    Hi, my code is the next and i  have a error, but i not know what i do:
> 
>    from pylab import *
>    from scipy import *
> 
>    def func(b,Hder):
>        return (Hder[0]-(b[0]-b[1]))**2 + (Hder[1]-(b[1]-b[2]))**2+
>    (Hder[2]-(b[2]-b[3]))**2+ (Hder[3]-(b[3]-100.0))**2
> 
> 
>    b0=[0.0,0.0,0.0,0.0]
>    H0=[0.0,-50.0,20.0,-20.0]
> 
>    xopt =optimize.fmin_l_bfgs_b(func
>    ,b0,args=(H0))
> 
>    error is
> 
>    Traceback (most recent call last):
>      File "C:/Users/Valeria2/JL-MAESTRIA/programas 3
>    avance/resultado2/pruebafmin_l.py", line 13, in <module>
>        xopt =optimize.fmin_l_bfgs_b(funcion,b0,args=(H0))
>      File "C:\Python25\Lib\site-packages\scipy\optimize\lbfgsb.py", line 205,
>    in fmin_l_bfgs_b
>        f, g = func_and_grad(x)
>      File "C:\Python25\Lib\site-packages\scipy\optimize\lbfgsb.py", line 156,
>    in func_and_grad
>        f, g = func(x, *args)
>    TypeError: funcion() takes exactly 2 arguments (5 given)
> 
>    thanks
> 
You have a couple problems.

the error is because you are passing a single item, H0, in parenthesis, which
is not the same as a tuple (as parenthesis are also used as grouping
specifiers), instead you need to do args=(H0,). If you add this you will get a
new traceback:

Traceback (most recent call last):
  File "opt_error.py", line 15, in <module>
    xopt = optimize.fmin_l_bfgs_b(func, b0, args=(H0,))
  File "/usr/lib/python2.5/site-packages/scipy/optimize/lbfgsb.py", line 205,
in fmin_l_bfgs_b
    f, g = func_and_grad(x)
  File "/usr/lib/python2.5/site-packages/scipy/optimize/lbfgsb.py", line 156,
in func_and_grad
    f, g = func(x, *args)
TypeError: 'numpy.float64' object is not iterable

Which is a cryptic way of noting that you are using the range bounded version
of bfgs, but you haven't provided bounds. If you meant to have the problem be
unconstrained, then you should have

xopt = optimize.fmin_bfgs(func, b0, args=(H0,))

And all will work. Otherwise provide bounds.

Okay so the problem is fixed, but to give another way of passing arguments,
which I find nicer (and is also the preferred way in modern matlab, using
function handles) . . .

Instead of using the args keyword for fmin_bfgs, make another function that
calls func with Hder bound to H0, like so:

def obj(b):
    return func(b, H0)

now just pass obj to fmin_bfgs. So the code would be:

from pylab import *
from scipy import *

def func(b,Hder):
    return (Hder[0]-(b[0]-b[1]))**2 +
(Hder[1]-(b[1]-b[2]))**2+(Hder[2]-(b[2]-b[3]))**2+ (Hder[3]-(b[3]-100.0))**2


b0=[0.0,0.0,0.0,0.0]
H0=[0.0,-50.0,20.0,-20.0]

def obj(b):
    return func(b, H0)

xopt=optimize.fmin_bfgs(obj, b0)

I find this prettier, you can also do it more concisely using lambda functions
(which makes it even closer to the matlab way), if you want to know how, send
me a message.

Gabriel



More information about the SciPy-User mailing list