[SciPy-user] problem with fmin_cobyla

dmitrey openopt at ukr.net
Fri Sep 7 04:46:05 EDT 2007


So what's wrong with your example?
According to my results obtained from the one (1st py-file), max 
constraint violation is 2.37501074363e-10
Don't you forget that fmin_cobyla uses c(x)>=0 constraints? (As for me 
it's one more reason to use universal frameworks that cut down such 
edges of solvers, no needs to study each one deeply).
Regards, D.


Josh Gottlieb wrote:
> Hey,
> A bit of a newbie to this, but I have a problem which
> requires a dynamic set of constraints (some of which
> are non-linear) and I tried two versions using
> fmin_cobyla (both examples attached)-- 
> one generates these constraints using lambda
> functions, but fmin seems to violate them (example in
> code).
> Then I tried generating them on the fly using exec on
> strings of functions, which observed the constraints,
> but failed to find the most optimal solution. (the
> third permutation should be higher)
> Can anyone help?
> Could not find any examples online which were more
> than trivial, and the docs dont seem very good.
> (apologies for the cryptic coding, I tried to minimize
> a real-world example into a shorter script)
>
> Thanx in advance,
> Josh
>
>
>        
> ____________________________________________________________________________________
> Pinpoint customers who are looking for what you sell. 
> http://searchmarketing.yahoo.com/
> ------------------------------------------------------------------------
>
> import calendar
> import datetime
> import numpy
> from scipy.optimize import fmin_cobyla
>
> def Solve():
>     maxS = 17000000
>     dates = [datetime.date(2008,4,1),datetime.date(2008,5,1), datetime.date(2008,6,1)]
>     vals =  [.024925574678, .128886905103,.0447355248121]
>     # this is a set of date lists, each one corresponding to one of the vals above and one of the unknown vars to solve for
>     permutes = [[dates[1],dates[0]],[dates[2],dates[0]],[dates[2],dates[1]]]
>     # daily limits (in the constraints, we use these at a monthly level)
>     upLim = [114033,114033,114033]
>     dnLim = [159646,159646,159646]
>
>     allCons = genCons( dates,permutes,0,maxS,upLim,dnLim )
>     k = fmin_cobyla(minFunc, [5000000 for x in permutes], allCons, args=(permutes, vals),consargs=(),rhobeg=10000,rhoend=500,iprint=3,maxfun=100000)
>     print permutes, vals
>     # change to max and print
>     print -1 * minFunc(k,permutes,vals)
>     return k
>
> def minFunc( x, permutes, vals ):
>     # we really need max, so we multiply by -1
>     return sum([-1*x[k]*vals[k] for k in xrange(len(permutes))])
>
> def genCons( dates, permutes, initial, maxS, upLim, dnLim ):
>     # generate constraints dynamically since normally we dont know how many dates there are
>     maxSet = []
>     minSet = []
>     iSet = []
>     wSet  = []
>     signSet = []
>     upperSet = []
>     lowerSet = []
>     fullRelList = []
>     fullSignList = []
>     for i,d in enumerate( dates ):
>         iLimit = upLim[i] * ( calendar.mdays[d.month] + ( calendar.isleap(d.year) and d.month == 2 ) )
>         wLimit  = dnLim[i]  * ( calendar.mdays[d.month] + ( calendar.isleap(d.year) and d.month == 2 ) )
>         relList  = [ n for n,t in enumerate( permutes ) if d in t ]
>         signList = [ (t[0] == d and -1) or (t[1] == d and 1) for t in permutes if d in t ]
>         #print iLimit,wLimit
>         fullRelList.append(relList)
>         fullSignList.append(signList)
>         #print signList, relList
>         iFn = lambda x: iLimit-sum([x[k]*signList[t] for t,k in enumerate(relList)])
>         # violated constraint!!!
>         print iFn([6500000, 4949026, 0])
>         iSet.append(iFn)
>         wFn = lambda x: sum([x[k]*signList[t] for t,k in enumerate(relList)])+wLimit
>         wSet.append(wFn)
>         maxFn = lambda x: maxS-initial-sum(numpy.concatenate([[x[k]*fullSignList[j][t] for t,k in enumerate(fullRelList[j])] for j in xrange(len(fullRelList))]))
>         maxSet.append(maxFn)
>         minFn = lambda x: sum(numpy.concatenate([[x[k]*fullSignList[j][t] for t,k in enumerate(fullRelList[j])] for j in xrange(len(fullRelList))]))-(0-initial)
>         minSet.append(minFn)
>         signPairs = numpy.concatenate( [ [ (x,y,relList.index(x),relList.index(y)) for y in relList if y!=x ] for x in relList ] ).tolist()
>         for j,pair in enumerate( signPairs ):
>             signFn = lambda x: x[pair[0]]*signList[pair[2]]*x[pair[1]]*signList[pair[3]]
>             signSet.append(signFn)
>     for j,item in enumerate( permutes ):
>         iLimit = upLim[dates.index(item[0])] * (calendar.mdays[item[0].month]+(calendar.isleap(item[0].year) and item[0].month==2))
>         wLimit  = dnLim[dates.index(item[1])] * (calendar.mdays[item[1].month]+(calendar.isleap(item[1].year) and item[1].month==2))
>         upperFn = lambda x: max(iLimit,wLimit) - x[j]
>         lowerFn = lambda x: x[j]
>         upperSet.append(upperFn)
>         lowerSet.append(lowerFn)
>     fullSet = iSet+wSet+maxSet+minSet+signSet+upperSet+lowerSet
>     #print fullSet, len(fullSet)
>     return fullSet 
>   
> ------------------------------------------------------------------------
>
> import calendar
> import datetime
> import numpy
> from scipy.optimize import fmin_cobyla
>
> def Solve():
>     maxS = 17000000
>     dates = [datetime.date(2008,4,1),datetime.date(2008,5,1), datetime.date(2008,6,1)]
>     vals =  [.024925574678, .128886905103,.0447355248121]
>     # this is a set of date lists, each one corresponding to one of the vals above and one of the unknown vars to solve for
>     permutes = [[dates[1],dates[0]],[dates[2],dates[0]],[dates[2],dates[1]]]
>     # daily limits (in the constraints, we use these at a monthly level)
>     upLim = [114033,114033,114033]
>     dnLim = [159646,159646,159646]
>
>     allCons = genCons( dates,permutes,0,maxS,upLim,dnLim )
>     k = fmin_cobyla(minFunc, [5000000 for x in permutes], allCons, args=(permutes, vals),consargs=(),rhobeg=10000,rhoend=500,iprint=3,maxfun=100000)
>     print permutes, vals
>     # change to max and print
>     print -1 * minFunc(k,permutes,vals)
>     return k
>
> def minFunc( x, permutes, vals ):
>     # we really need max, so we multiply by -1
>     return sum([-1*x[k]*vals[k] for k in xrange(len(permutes))])
>
> def genCons( dates, permutes, initial, maxS, upLim, dnLim ):
>     # generate constraints dynamically since normally we dont know how many dates there are
>     maxSet = []
>     minSet = []
>     iSet = []
>     wSet  = []
>     signSet = []
>     upperSet = []
>     lowerSet = []
>     fullRelList = []
>     fullSignList = []
>     for i,d in enumerate( dates ):
>         iLimit = upLim[i] * ( calendar.mdays[d.month] + ( calendar.isleap(d.year) and d.month == 2 ) )
>         wLimit  = dnLim[i]  * ( calendar.mdays[d.month] + ( calendar.isleap(d.year) and d.month == 2 ) )
>         relList  = [ n for n,t in enumerate( permutes ) if d in t ]
>         signList = [ (t[0] == d and -1) or (t[1] == d and 1) for t in permutes if d in t ]
>         #print iLimit,wLimit
>         fullRelList.append(relList)
>         fullSignList.append(signList)
>         #print signList, relList
>         iFn = lambda x: iLimit-sum([x[k]*signList[t] for t,k in enumerate(relList)])
>         # violated constraint!!!
>         print iFn([6500000, 4949026, 0])
>         iSet.append(iFn)
>         wFn = lambda x: sum([x[k]*signList[t] for t,k in enumerate(relList)])+wLimit
>         wSet.append(wFn)
>         maxFn = lambda x: maxS-initial-sum(numpy.concatenate([[x[k]*fullSignList[j][t] for t,k in enumerate(fullRelList[j])] for j in xrange(len(fullRelList))]))
>         maxSet.append(maxFn)
>         minFn = lambda x: sum(numpy.concatenate([[x[k]*fullSignList[j][t] for t,k in enumerate(fullRelList[j])] for j in xrange(len(fullRelList))]))-(0-initial)
>         minSet.append(minFn)
>         signPairs = numpy.concatenate( [ [ (x,y,relList.index(x),relList.index(y)) for y in relList if y!=x ] for x in relList ] ).tolist()
>         for j,pair in enumerate( signPairs ):
>             signFn = lambda x: x[pair[0]]*signList[pair[2]]*x[pair[1]]*signList[pair[3]]
>             signSet.append(signFn)
>     for j,item in enumerate( permutes ):
>         iLimit = upLim[dates.index(item[0])] * (calendar.mdays[item[0].month]+(calendar.isleap(item[0].year) and item[0].month==2))
>         wLimit  = dnLim[dates.index(item[1])] * (calendar.mdays[item[1].month]+(calendar.isleap(item[1].year) and item[1].month==2))
>         upperFn = lambda x: max(iLimit,wLimit) - x[j]
>         lowerFn = lambda x: x[j]
>         upperSet.append(upperFn)
>         lowerSet.append(lowerFn)
>     fullSet = iSet+wSet+maxSet+minSet+signSet+upperSet+lowerSet
>     #print fullSet, len(fullSet)
>     return fullSet 
>
> def main():
>     return Solve()
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> SciPy-user mailing list
> SciPy-user at scipy.org
> http://projects.scipy.org/mailman/listinfo/scipy-user
>   




More information about the SciPy-User mailing list