Search code examples
pythonpyomo

Initializing Params in Different ways gives me the same Attribute Error


I am trying to use pyomo for solving a quadratic program. My model is below. I will add more constraints and objective at later stages.

from pyomo.environ import *

model = ConcreteModel()
model.IDX1 = range(96)
model.IDX2 = range(192)
model.IDX3 = range(49)

# Variables
model.x = Var(model.IDX1)

b2 = main_power2.iloc[[0]]
b2 = np.append([0], np.asarray(b2))

model.H_py  = Param(model.IDX1, initialize = arrtodict(Hp)) # Hp: 96*96
model.A1_py = Param(model.IDX2, initialize = arrtodict(A1l)) # A1l: 192 * 96
model.b1_py = Param(model.IDX2, initialize = arrtodict(b1)) # 192*1
model.A2_py = Param(model.IDX3, initialize = arrtodict(A2)) # 49 * 96
model.b2_py = Param(model.IDX3, initialize = arrtodict(b2)) # 49,1

def inequality_rule(model,i): # i = IDX2
        return sum(  model.A1_py[i][j] * model.x[j] for j in model.IDX1 ) <= model.b1_py[i]  
model.c1 = Constraint (model.IDX2, rule = inequality_rule )

where arrtodict is a function that converts array (1-D, 2-D)to dictionary and is shown below. The entire point of converting it to dictionary is that the parameter initialization is done using dictionary if I am not mistaken.

def arrtodict(your_array):
    your_array = your_array.tolist()
    dict_data = {key: value for key, value in enumerate(your_array)}

    if type(dict_data[0]) is list: 
        for key, value in dict_data.items():
            dict_data[key] = {k: v for k, v in enumerate(value)}
    elif type(dict_data[0]) is (float or int):
        pass
    else:
        print ('Check Your data')
    return dict_data

For some reason I keep on getting the following error:

 line 3530, in _generate_relational_expression

 if not (rhs.__class__ in native_types or rhs.is_expression_type()):

AttributeError: 'dict' object has no attribute 'is_expression_type'

And the error is exactly same if I try to use list/array to initialize the parameters. The only difference in the error is 'dict' changes to 'list/numpy.ndarray' in error. I am not sure what am I doing wrong.

Additionally, I did look to the question here.That is why converted arrays to dictionary.


Solution

  • As noted by ycx there is a bug in Pyomo. If you pass an object to Param initialize it tries to use it as an expression object instead of iterating through it and using the values to initialize the param.

    What you need to do is change your code to use a function that returns the correct value for the inputs. See the example from the code doc:

    https://github.com/Pyomo/pyomo/blob/master/examples/pyomo/tutorials/param.py

    # A parameter can be constructed with the _initialize_ option, which is a 
    # function that accepts the parameter indices and model and returns the value
    # of that parameter element:
    #
    def W_init(model, i, j):
        #
        # Create the value of model.W[i,j]
        #
        return i*j
    model.W = Param(model.A, model.B, initialize=W_init)