I'm working on an optimization problem for a refrigeration system using the Gekko Python package, and I'm facing issues with integrating Gekko Linear Regression models (Gekko_LinearRegression_Modified) into my optimization model. Specifically, I encounter an error related to the definition of intermediate variables without equality expressions when I try to update costs based on predictions and set constraints based on the model's predictions. Below is a simplified version of my code:
from gekko import GEKKO
from gekko import ML
from gekko.ML import Gekko_GPR, Gekko_SVR, Gekko_LinearRegression
# Initialize Gekko model
m = GEKKO(remote=False) # 'remote=False' for local execution
price_vec_list = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 1, 1, 1] # Price vector
# Create a Gekko array of parameters
price_vec_gekko = m.Array(m.Param, len(price_vec_list))
for i, val in enumerate(price_vec_list):
price_vec_gekko[i].value = val
coolLoad = m.Const(3) # Cooling load
Q_Spc = m.Const(5) # Storage size
n = len(price_vec_gekko) # Directly use the length of the price vector
T_brine_in = m.Array(m.Param, n) # Brine inlet temperature
for i in range(n):
T_brine_in[i].VALUE = 25
ST_V = m.Array(m.MV, n) # Compressor control variable
for i in range(n):
ST_V[i].VALUE = 0.5
ST_V[i].LOWER = 0.43 # Correct property for lower limit
ST_V[i].UPPER = 1 # Correct property for upper limit
ST_V[i].status = 1 # Allow the solver to optimize this variable
coolLoad_sum_min = np.cumsum(np.full(n, coolLoad))
coolLoad_sum_max = coolLoad_sum_min + Q_Spc # Cold water storage cap
costs = m.Var(value=0) # Initialize cost variable as a Gekko variable`
# Modify the Gekko_LinearRegression class initialization to handle scalar intercepts and coefficients
class Gekko_LinearRegression_Modified(Gekko_LinearRegression):
def __init__(self, model, m):
self.m = m
# Check if coef_ is an array and handle accordingly
if hasattr(model.coef_, "__len__"):
self.coef = model.coef_[0] if len(model.coef_) > 1 else model.coef_
else:
self.coef = model.coef_
# Check if intercept_ is a scalar and handle accordingly
self.intercept = model.intercept_ if np.isscalar(model.intercept_) else model.intercept_[0]
# Using the modified class for predictions directly in equations
for i in range(n):
# Directly use the prediction in the equation, avoid intermediate if not necessary
costs_increment = Gekko_LinearRegression_Modified(MLA_LR_P, m).predict([ST_V[i], T_brine_in[i]]) / 1000 * price_vec_gekko[i]
Qo_constraint = Gekko_LinearRegression_Modified(MLA_LR_Q, m).predict([ST_V[i], T_brine_in[i]]) / 1000
# Update costs based on predictions and prices
m.Equation(costs == costs + costs_increment)
# Constraints based on Qo_Gekko_Model, ensure these are properly defined as equations
m.Equation(Qo_constraint < coolLoad_sum_max[i])
m.Equation(Qo_constraint > coolLoad_sum_min[i])
m.Minimize(costs) # Minimize
m.options.SOLVER = 1 # APOPT Solver
m.options.IMODE = 1
# Solve model
m.solve(disp=True)
The error message is:
APMonitor, Version 1.0.0
APMonitor Optimization Suite
@error: Intermediate Definition
Error: Intermediate variable with no equality (=) expression
(((p25)*(2487.122166666668))-766.6071363636368)]
STOPPING...
Exception Traceback (most recent call last)
Cell In[14], line 81
79 m.options.IMODE = 1
80 # Solve model
---> 81 m.solve(disp=True)
83 # Output results
84 print(f'Optimized ST_V: {ST_V.VALUE[0]}')
File ~\anaconda3\lib\site-packages\gekko\gekko.py:2140, in GEKKO.solve(self, disp, debug, GUI, **kwargs)
2138 print("Error:", errs)
2139 if (debug >= 1) and record_error:
-> 2140 raise Exception(apm_error)
2142 else: #solve on APM server
2143 def send_if_exists(extension):
Exception: @error: Intermediate Definition
Error: Intermediate variable with no equality (=) expression
(((p25)*(2487.122166666668))-766.6071363636368)]
STOPPING...
If I don't use the class Gekko_LinearRegression_Modified, then I get this error
IndexError Traceback (most recent call last)
Cell In[15], line 64
35 # Assuming MLA_LR_P and MLA_LR_Q are already defined and trained linear regression models
36 #for i in range(n):
37 # Pel_Gekko_Model = Gekko_LinearRegression(MLA_LR_P, m).predict([ST_V[i], T_brine_in[i]])
(...)
60
61 # Using the modified class for predictions directly in equations
62 for i in range(n):
63 # Directly use the prediction in the equation, avoid intermediate if not necessary
---> 64 costs_increment = Gekko_LinearRegression(MLA_LR_P, m).predict([ST_V[i], T_brine_in[i]]) / 1000 * price_vec_gekko[i]
65 Qo_constraint = Gekko_LinearRegression(MLA_LR_Q, m).predict([ST_V[i], T_brine_in[i]]) / 1000
67 # Update costs based on predictions and prices
File ~\anaconda3\lib\site-packages\gekko\ML.py:838, in Gekko_LinearRegression.__init__(self, model, m)
836 self.m = m
837 self.coef = model.coef_[0]
--> 838 self.intercept = model.intercept_[0]
IndexError: invalid index to scalar variable.
Sorry to hear that you are having trouble with the LinearRegression model. The original code was not robust enough, and will be updated soon. I have created a slim down and modified version of your code that runs (with a placeholder model) the model prediction. I fixed one line in your modified linear regression class; it was only saving one coefficient even if there were multiple.