Error evaluating 'statsmodels' function in pyomo objective function expression

13 views
Skip to first unread message

Kedar Kulkarni

unread,
Oct 20, 2021, 8:44:56 AM10/20/21
to Pyomo Forum
Hi all,

I'm trying to solve a textbook example for inventory optimization using pyomo / ipopt, with the following code:
----------------------------------------------------------------------------------------------------------------------------------
from pyomo.environ import *
from pyomo.opt import SolverFactory
from scipy import stats

# pyomo
model = ConcreteModel()

# Cost parameters
A = 3.20 # $/order
D = 700 # units/year
v = 12 # $/unit
r = 0.24 # /year
h = v * r # holding-costs
sigmaL = 30 # units
B1 = 32 # $/occasion

model.k = Var(within=NonNegativeReals, bounds=(0.0, 3.0), initialize=0.5)
model.Q = Var(within=NonNegativeReals, bounds=(0.0, None), initialize=50)

k = model.k
Q = model.Q

model.obj = Objective(expr=A * (D / Q) + ((Q / 2) + k * sigmaL) * h + B1 * (D / Q) * (1 - stats.norm.cdf(k)), sense=minimize)
opt = SolverFactory('ipopt')
opt.solve(model)

model.pprint()
print('\n---------------------------------------------------------------------')
print('k=', value(model.k))
print('Q=', value(model.Q))
print('Obj=', value(model.obj))
----------------------------------------------------------------------------------------------------------------------------------

But, I get the following error:

Traceback (most recent call last):
  File "/Users/kedar/Desktop/2915/MRO IO/github code/FastsQ_ipopt.py", line 26, in <module>
    model.obj = Objective(expr=A * (D / Q) + ((Q / 2) + k * sigmaL) * h + B1 * (D / Q) * (1 - stats.norm.cdf(k)), sense=minimize)
  File "/Users/kedar/opt/anaconda3/lib/python3.8/site-packages/scipy/stats/_distn_infrastructure.py", line 1846, in cdf
    cond1 = self._open_support_mask(x, *args) & (scale > 0)
  File "/Users/kedar/opt/anaconda3/lib/python3.8/site-packages/scipy/stats/_distn_infrastructure.py", line 913, in _open_support_mask
    return (a < x) & (x < b)
  File "pyomo/core/expr/logical_expr.pyx", line 183, in pyomo.core.expr.logical_expr.InequalityExpression.__bool__
pyomo.common.errors.PyomoException: Cannot convert non-constant expression to bool. This error is usually caused by using an expression in a boolean context such as an if statement. For example, 
    m.x = Var()
    if m.x <= 0:
        ...
would cause this exception.
----------------------------------------------------------------------------------------------------------------------------------
I notice that I'm able to get a solution when I drop the stats.norm.cdf(k) term in the objective function. So, it seems to me that the way I'm currently defining / calling the objective function, does not allow for functions from other Py packages to be evaluated within an objective function expression in pyomo.

Can someone please help me do exactly that: i.e. how to pass (say) numpy or statsmodels functions into objective function expressions in pyomo? 

Thanks in advance!

regards,
-kedar.




Reply all
Reply to author
Forward
0 new messages