0

I need help on minimizing function in python using three variable constraints.

I have posted the code which is giving me error. If you would like I can post the entire code to to show the mathematical calculation.:

# the time-series data.
coeff = [0.2, 0.3, 0.4]

x =[146, 96, 59, 133, 192, 127, 79, 186, 272, 155, 98, 219]
test = y(x,coeff)
print("x : ", x)
print("y : ",test)

result = minimize(mape, coeff, (x,), bounds =[(0,1),(0,1), (0,1)], method='SLSQP')

opt = result.x
print("opt : ", result.x)

This is my code:

from __future__ import division
import numpy as np
from scipy.optimize import minimize



#coeffList[0] = alpha
#coeffList[1] = beta
#coeffList[2] =gamma

def mape(x, coeffList):
    diff = abs(y(x,coeffList)-x)
    print("np.mean(diff/x) : ", np.mean(diff/x))
    return np.mean(diff/x)


#Holt Winters-Multiplicative



def y(x, coeffList , debug=True):

    c =4 
    #Compute initial b and intercept using the first two complete c periods.
    xlen =len(x)
    print("xlen : ", xlen)
    #if xlen % c !=0:
    #    return None
    fc =float(c)
    xbar2 =sum([x[i] for i in range(c, 2 * c)])/ fc
    print("xbar2 : ",xbar2)

    xbar1 =sum([x[i] for i in range(c)]) / fc


    print("xbar1 : ", xbar1)
    b0 =(xbar2 - xbar1) / fc
    if debug: print ("b0 = ", b0)

    #Compute for the level estimate a0 using b0 above.
    tbar  =sum(i for i in range(1, c+1)) / fc
    print("tbar : ",tbar)
    a0 =xbar1  - b0 * tbar
    if debug: print ("a0 = ", a0)

    #Compute for initial indices - seasonality
    I =[x[i] / (a0 + (i+1) * b0) for i in range(0, xlen)]
    if debug: print ("Initial indices = ", I)

    S=[0] * (xlen+ c)
    for i in range(c):
        S[i] =(I[i] + I[i+c]) / 2.0
        print ("S[",i,"]=", S[i])

    #Normalize so S[i] for i in [0, c)  will add to c.
    tS =c / sum([S[i] for i in range(c)])
    print("tS : ", tS)
    for i in range(c):
        S[i] *=tS
        if debug: print ("Normalized S[",i,"]=", S[i])

    # Holt - winters proper ...
    if debug: print( "Use Holt Winters formulae")


    At =a0
    Bt =b0
    #y =[0] * (xlen) 
    y = np.empty(len(x),float)
    for i in range(xlen):
        Atm1 =At
        Btm1 =Bt
        At =coeffList[0] * x[i] / S[i] + (1.0-coeffList[0]) * (Atm1 + Btm1)
        Bt =coeffList[1] * (At - Atm1) + (1- coeffList[1]) * Btm1
        S[i+c] =coeffList[2] * x[i] / At + (1.0 - coeffList[2]) * S[i]
        y[i]=(a0 + b0 * (i+1)) * S[i]
        #print ("i=", i+1, "y=", y[i], "S=", S[i], "(level)Atm1=", Atm1, "(trend)Btm1=",Btm1, "(level)At=", At, "Bt=", Bt, "S[i+c]=", S[i+c], "y[i]=", y[i])
        print ("i=", i+1, "y=", y[i], "S=", S[i], "(level)At=", At, "Bt=", Bt, "y[i]=", y[i])
#coeffList[0] = alpha
#coeffList[1] = beta
#coeffList[2] =gamma

    return y

        #print (i,y[i],  F[i])
    #Forecast for next c periods:
    #for m in range(c):
        #print( "forecast:", (At + Bt* (m+1))* S[ylen + m])

    # the time-series data.
coeff = [0.2, 0.3, 0.4]

x =[146, 96, 59, 133, 192, 127, 79, 186, 272, 155, 98, 219]
bnds = ((0,1), (0,1), (0,1))
coeff = [0.2, 0.3, 0.4]
test = y(x,coeff)
print("x : ", x)
print("y : ",test)
#cons = ({'type' :'alpha', 'fun' :lambda x: np.array(x[0]<=1 and x[0]>=0)})
result = minimize(mape, coeff, (x,), method ="L-BFGS-B", bounds =bnds)

opt = result.x(0)
print("opt : ", result.x)

This is the error message. The function without minimization function works just fine.

Traceback (most recent call last):
  File "C:\Users\gelalmp\Desktop\Bibha Gelal_SD\testing_Optimization_HWM.py", line 100, in <module>
    result = minimize(mape, coeff, (x,), method ="L-BFGS-B", bounds =bnds)
  File "C:\Python27\lib\site-packages\scipy\optimize\_minimize.py", line 380, in minimize
    callback=callback, **options)
  File "C:\Python27\lib\site-packages\scipy\optimize\lbfgsb.py", line 314, in _minimize_lbfgsb
    f, g = func_and_grad(x)
  File "C:\Python27\lib\site-packages\scipy\optimize\lbfgsb.py", line 258, in func_and_grad
    f = fun(x, *args)
  File "C:\Users\gelalmp\Desktop\Bibha Gelal_SD\testing_Optimization_HWM.py", line 12, in mape
    diff = abs(y(x,coeffList)-x)
  File "C:\Users\gelalmp\Desktop\Bibha Gelal_SD\testing_Optimization_HWM.py", line 30, in y
    xbar2 =sum([x[i] for i in range(c, 2 * c)])/ fc
IndexError: index out of bounds
CT Zhu
  • 52,648
  • 17
  • 120
  • 133
Nina
  • 13
  • 6
  • Please show the code of functions `y()` and `mape()`, as well as the error message. – CT Zhu Mar 16 '14 at 00:07
  • @CTZhu I have posted the code of the function as well as the error message. Thank you for your help – Nina Mar 16 '14 at 01:13

1 Answers1

1

Change your last 4 lines to:

M=lambda p1, p2: mape(p2, p1)
result = minimize(M, coeff, (x,), method ="L-BFGS-B", bounds =bnds)

opt = result['x']
print("opt : ", result['x'])

And it should work now, need explanations? I get the optimization result ('opt : ', array([ 0.45330204, 0.26761714, 0. ]))

The lambda function reverses the order of how the parameters are supplied to mape. As you are attempting to find the coeff that minimize the mape() given a fixed x, the target function should take coeff first and x second, which is not the case for mape.

To your comment question: I thought you are using L-BFGS-B in your code. The difference are explained here: http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html#tutorial-sqlsp. I have to admit I don't too much detailed of SLSQP as that was long time ago in graduate school. BFGS is more common and every textbook explains it. L-BFGS-B supports bound constrained minimization. SLSQP supports bounds, as well as equality and inequality constraints. So, SLSQP can function when L-BFGS-B can't. See, http://scipy-lectures.github.io/advanced/mathematical_optimization/index.html?utm_source=twitterfeed&utm_medium=twitter.

CT Zhu
  • 52,648
  • 17
  • 120
  • 133
  • what does the lambda function do? What's the difference between SLSQP and L-BFGS-B method? – Nina Mar 16 '14 at 01:54
  • See edit. If you are asking when to use BFGS and when to use SLSQP when both are applicable, I don't have an answer for it. Use whatever works, and works faster. – CT Zhu Mar 16 '14 at 02:16