[SciPy-User] optimize.leastsq - Value Error: The truth value of an array with more than one element is ambiguous

Zhe Wang 3njoywind at gmail.com
Sat May 15 21:58:37 EDT 2010


v is calender years e.g

(1+p)**1984

May be you could help me with this simple example:

I have a function defined like this(a0 is a parameter):
------------------------------------
def f(x):
    if x > 4:
        return x + a0
    else:
        return x - a0
------------------------------------

I generated the data when I let a0=2 :
--------------------------------------
X = np.array([1,2,3,4,5,6,7,8,9])
Y = np.array([-1, 0, 1, 2,7,8,9,10,11])
--------------------------------------

How can I use leastsq() to fit f(x)? I have wrote some code like this:
--------------------------------------
def func(p, x, y):
    a = p
    sum = np.array([0,0,0,0,0,0,0,0,0])
    for i in range(0, len(x)):
        if x[i] > 4:
            sum[i] = x[i] + a
        else:
            sum[i] = x[i] - a
    return sum - y
r = leastsq(func,1,args=(X,Y))
print r[0]
--------------------------------------

the output is 1.0000000149, much different like 2.
I doubt whether leastsq() is suitable for this kind of problem. Maybe I
should try another way?

Zhe

On Sun, May 16, 2010 at 12:34 AM, <josef.pktd at gmail.com> wrote:

> On Sat, May 15, 2010 at 11:06 AM, Zhe Wang <3njoywind at gmail.com> wrote:
> > Josef:
> > Thanks,
> > my example is just for test, it is not always have a fixed start, e.g
> >>>> T = np.array([1995,1996,1997,1998,1999])
> >>>> E = np.array([14,12,11,15,12])
> >>>> T-E
> > array([1981, 1984, 1986, 1983, 1987])
> > so, if I define the function:
> > def func(x):
> >     #....
> >     v = np.arange(...)
> >     Y = np.cumsum((a*(1+p)**v)*I(v))
> >     return Y
> > when I call leastsq(func, [1,0]), v should change as the element of T
> > change, e.g.
> > when t(one element of T) is 1995,v = np.arange(1981, 1995)
> > when t is 1996, v = np.arange(1984, 1996)
>
> are you sure v is supposed to be calender years and not number of
> years accumulated?  i.e
>
> (1+p)**1984
> or
> (1+p)**(1996-1984)
>
> The most efficient would be to use the formula for the sum of a finite
> geometric series, which would also avoid the sum.
>
> Josef
>
>
> > ......
> > this troubles me so much.
> > Zhe Wang
> >
> >
> > On Sat, May 15, 2010 at 9:08 PM, <josef.pktd at gmail.com> wrote:
> >>
> >> On Sat, May 15, 2010 at 8:49 AM, Zhe Wang <3njoywind at gmail.com> wrote:
> >> > Josef:
> >> > Thanks for your reply:)
> >> > Actually I want to fit this equation:
> >> > Y(t) = sigma(v=t-e(t), t)[(a*(1+p)**v)*I(v)]
> >> > I got {t} and {Y(t)} and a, p are parameters. e(t) and I(v) can be
> >> > calculated by e() and I().
> >>
> >> Do you always have a fixed start date as in your example
> >>
> >> >>> T = np.array([1995,1996,1997,1998,1999])
> >> >>> E = np.array([10,11,12,13,14])
> >> >>> T-E
> >> array([1985, 1985, 1985, 1985, 1985])
> >>
> >> so that always v =range(T0, T+1)     with fixed T0=1985
> >>
> >> this would make it easier to work forwards than backwards, e.g.
> something
> >> like
> >> v = np.arange(...)
> >> Y = np.cusum((a*(1+p)**v)*I(v))
> >>
> >> Josef
> >>
> >>
> >>
> >>
> >> > I rewrote my code like this:
> >> >
> >> >
> ----------------------------------------------------------------------------------------------
> >> > from scipy.optimize import leastsq
> >> > import numpy as np
> >> > def Iv(t):
> >> >     return 4
> >> > def Yt(x, et):
> >> >     a, pa = x
> >> >     sum = np.array([0,0,0,0,0])
> >> >     for i in range(0, len(et)):
> >> >         for j in range(0, et[i]):
> >> >             v = T[i] - et[i] + j
> >> >             sum[i] += a*(1+pa)**(v)*Iv(v)
> >> >     return sum - Y
> >> > T = np.array([1995,1996,1997,1998,1999])
> >> > Y =
> >> >
> >> >
> np.array([639300.36866,664872.383407,691467.278743,719125.969893,747891.008688])
> >> > E = np.array([10,11,12,13,14])
> >> > r = leastsq(Yt, [1,0], args = (E), maxfev=10000000)
> >> > A, Pa = r[0]
> >> > print "A=",A,"Pa=",Pa
> >> >
> >> >
> ----------------------------------------------------------------------------------------------
> >> > the output is:
> >> > A= 1.0 Pa = 0.0
> >> >
> >> >
> ----------------------------------------------------------------------------------------------
> >> > I don't think it is correct. Hope for your guidence.
> >> > On Sat, May 15, 2010 at 7:02 PM, <josef.pktd at gmail.com> wrote:
> >> >>
> >> >> On Sat, May 15, 2010 at 5:25 AM, Zhe Wang <3njoywind at gmail.com>
> wrote:
> >> >> > Traceback (most recent call last):
> >> >> >   File "D:\Yt.py", line 31, in <module>
> >> >> >     r = leastsq(residuals, [1,0], args=(Y,T), maxfev=10000000)
> >> >> >   File "D:\Python26\lib\site-packages\scipy\optimize\minpack.py",
> >> >> > line
> >> >> > 266,
> >> >> > in leastsq
> >> >> >     m = check_func(func,x0,args,n)[0]
> >> >> >   File "D:\Python26\lib\site-packages\scipy\optimize\minpack.py",
> >> >> > line
> >> >> > 12,
> >> >> > in check_func
> >> >> >     res = atleast_1d(thefunc(*((x0[:numinputs],)+args)))
> >> >> >   File "D:\Yt.py", line 26, in residuals
> >> >> >     return y - Yt(x, p)
> >> >> >   File "D:\Yt.py", line 20, in Yt
> >> >> >     for i in range(0, Et(x)):
> >> >> >   File "D:\Yt.py", line 11, in Et
> >> >> >     if t == 1995:
> >> >> > ValueError: The truth value of an array with more than one element
> is
> >> >> > ambiguous. Use a.any() or a.all()
> >> >> >
> >> >> >
> >> >> >
> ---------------------------------------------------------------------------------------------------------
> >> >> >
> >> >> > When running the following code:
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> --------------------------------------------------------------------------------------------
> >> >> >
> >> >> > from scipy.optimize import leastsq
> >> >> > import numpy as np
> >> >> >
> >> >> > def Iv(t):
> >> >> >     if t == 1995:
> >> >> >         return t + 2
> >> >> >     else:
> >> >> >         return t
> >> >> >
> >> >> > def Et(t):
> >> >> >     if t == 1995:
> >> >> >         return t + 2
> >> >> >     else:
> >> >> >         return t
> >> >> >
> >> >> > def Yt(x, p):
> >> >> >     a, pa = p
> >> >> >     sum = 0
> >> >> >
> >> >> >     for i in range(0, Et(x)):
> >> >> >         v = x - et + i
> >> >> >         sum += a*(1+p)**(v)*Iv(v)
> >> >> >     return sum
> >> >> >
> >> >> > def residuals(p, y, x):
> >> >> >     return y - Yt(x, p)
> >> >> >
> >> >> > T = np.array([1995,1996,1997,1998,1999])
> >> >> > Y =
> >> >> >
> >> >> >
> >> >> >
> np.array([639300.36866,664872.383407,691467.278743,719125.969893,747891.008688])
> >> >> >
> >> >> > r = leastsq(residuals, [1,0], args=(Y,T), maxfev=10000000)
> >> >> > A, Pa = r[0]
> >> >> > print "A=",A,"Pa=",Pa
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> ----------------------------------------------------------------------------------------------
> >> >> >
> >> >> > I know the error occurs when I compare t like: "if t == 1995",but I
> >> >> > have
> >> >> > no
> >> >> > idea how to handle it correctly.
> >> >>
> >> >> try the vectorized version of a conditional assignment, e.g.
> >> >> np.where(t == 1995, t, t+2)
> >> >>
> >> >> I didn't read enough of your example, to tell whether your Yt loop
> can
> >> >> be vectorized with a single sum, but I guess so.
> >> >>
> >> >> optimize leastsq expects an array, so residuals (and Yt) need to
> >> >> return an array not a single value, maybe np.cusum and conditional or
> >> >> data dependent slicing/indexing works
> >> >>
> >> >> Josef
> >> >>
> >> >>
> >> >> >
> >> >> > Any help would be greatly appreciated.
> >> >> >
> >> >> > Zhe Wang
> >> >> >
> >> >> > _______________________________________________
> >> >> > SciPy-User mailing list
> >> >> > SciPy-User at scipy.org
> >> >> > http://mail.scipy.org/mailman/listinfo/scipy-user
> >> >> >
> >> >> >
> >> >> _______________________________________________
> >> >> SciPy-User mailing list
> >> >> SciPy-User at scipy.org
> >> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >> >
> >> >
> >> > _______________________________________________
> >> > SciPy-User mailing list
> >> > SciPy-User at scipy.org
> >> > http://mail.scipy.org/mailman/listinfo/scipy-user
> >> >
> >> >
> >> _______________________________________________
> >> SciPy-User mailing list
> >> SciPy-User at scipy.org
> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> > _______________________________________________
> > SciPy-User mailing list
> > SciPy-User at scipy.org
> > http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> _______________________________________________
> SciPy-User mailing list
> SciPy-User at scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20100516/7a68f7a9/attachment.html>


More information about the SciPy-User mailing list