Changeset 1959


Ignore:
Timestamp:
Dec 4, 2009 2:43:06 PM (11 years ago)
Author:
wehart
Message:

Extended the constraint generation logic to evaluate whether the constraint
expression contains constant values. This extension allows the following
types of constraints to be specified:

def f(model)

return 0 < model.x

def g(model)

return model.x == model.y

def h(model)

return model.y > model.z

However, it's pretty clear now that the following cannot be supported in Python:

def j(model)

return 0 < model.x < 1

To add upper and lower bounds, a user will need to return a tuple value:

def j(model)

return (0, model.x, 1)

or return an expression that is generated incrementally:

def j(model)

e = 0 < model.x
return e < 1

Location:
coopr.pyomo/trunk/coopr/pyomo
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • coopr.pyomo/trunk/coopr/pyomo/base/constraint.py

    r1944 r1959  
    340340            _expr_args0 = expr._args[0]
    341341            _expr_args1 = expr._args[1]
     342
     343            #_expr_args0.pprint()
     344            #print "HERE", is_constant(_expr_args0)
     345            #_expr_args1.pprint()
     346            #print "HERE", is_constant(_expr_args1)
    342347        #
    343348        # If the constructor rule returns an equality expression, then
     
    346351        if isinstance(expr,_EqualToExpression):
    347352            _self_data[val]._equality = True
    348             if isinstance(_expr_args0,Expression) or\
    349                     isinstance(_expr_args0,Var) or\
    350                     isinstance(_expr_args0,_VarValue):
     353            if is_constant(_expr_args1):
    351354                tpl = [ _expr_args1,_expr_args0,_expr_args1 ]
     355            elif is_constant(_expr_args1):
     356                tpl = [ _expr_args0,_expr_args1,_expr_args0 ]
    352357            else:
    353                 tpl = [ _expr_args0,_expr_args1,_expr_args0 ]
     358                tpl = [ 0.0 , _expr_args0 - _expr_args1, 0.0 ]
    354359        #
    355360        # If the constructor rule returns a greater-than expression, then
     
    361366            if isinstance(_expr_args0,_GreaterThanExpression) or\
    362367                    isinstance(_expr_args0,_GreaterThanOrEqualExpression):
    363                 tpl = [ _expr_args0._args[0],_expr_args0._args[1],_expr_args1 ]
     368                tpl = [ _expr_args1, _expr_args0._args[1], _expr_args0._args[0] ]
    364369
    365370            elif isinstance(_expr_args0,_LessThanExpression) or\
    366371                    isinstance(_expr_args0,_LessThanOrEqualExpression):
    367                 tpl = [ _expr_args0._args[1],_expr_args0._args[0],_expr_args1 ]
     372                tpl = [ _expr_args1, _expr_args0._args[0], _expr_args0._args[1] ]
    368373
    369374            elif isinstance(_expr_args1,_GreaterThanExpression) or\
    370375                    isinstance(_expr_args1,_GreaterThanOrEqualExpression):
    371                 tpl = [ _expr_args0,_expr_args1._args[0],_expr_args1._args[1] ]
     376                tpl = [ _expr_args1._args[1], _expr_args1._args[0], _expr_args0 ]
    372377
    373378            elif isinstance(_expr_args1,_LessThanExpression) or\
    374379                    isinstance(_expr_args1,_LessThanOrEqualExpression):
    375                 tpl = [ _expr_args0,_expr_args1._args[1],_expr_args1._args[0] ]
     380                tpl = [ _expr_args1._args[0], _expr_args1._args[1], _expr_args0 ]
    376381
    377382            elif isinstance(_expr_args0,_EqualToExpression) or\
     
    379384                raise ValueError, "Bound error: > expression used with an = expression."
    380385
    381             elif isinstance(_expr_args0,Expression) or\
    382                     isinstance(_expr_args0,_VarValue) or\
    383                     isinstance(_expr_args0,Var):
    384                 tpl = [ None,_expr_args0,_expr_args1 ]
    385 
     386            elif _expr_args0.is_constant():
     387                tpl = [ None, _expr_args1, _expr_args0 ]
     388            elif _expr_args1.is_constant():
     389                tpl = [ _expr_args1, _expr_args0, None ]
    386390            else:
    387                 tpl = [ _expr_args0,_expr_args1,None ]
     391                tpl = [ 0.0, _expr_args0-_expr_args1, None ]
     392
    388393        #
    389394        # If the constructor rule returns a less-than expression, then
     
    413418                raise ValueError, "Bound error: < expression used with an = expression."+str(expr)+str(expr._args)
    414419
    415             elif isinstance(_expr_args0,Expression) or\
    416                     isinstance(_expr_args0,_VarValue) or\
    417                     isinstance(_expr_args0,Var):
    418                 tpl = [ None,_expr_args0,_expr_args1 ]
    419 
     420            elif _expr_args0.is_constant():
     421                tpl = [ _expr_args0, _expr_args1, None ]
     422            elif _expr_args1.is_constant():
     423                tpl = [ None, _expr_args0, _expr_args1 ]
    420424            else:
    421                 tpl = [ _expr_args0,_expr_args1,None ]
     425                tpl = [ 0.0, _expr_args1 - _expr_args0, None ]
    422426        #
    423427        # If the constructor rule returns a tuple or list, then convert
     
    435439            if len(expr) == 2:
    436440                _self_data[val]._equality = True
    437                 if isinstance(expr[0],Expression) or\
    438                         isinstance(expr[0],Var) or\
    439                         isinstance(expr[0],_VarValue):
     441                if is_constant(expr[1]):
    440442                    tpl = [ expr[1],expr[0],expr[1] ]
    441443                else:
  • coopr.pyomo/trunk/coopr/pyomo/base/expr.py

    r1835 r1959  
    7373            if (isinstance(arg,_ParamBase) or isinstance(arg,_VarBase)) and arg.dim() > 0:
    7474                raise ValueError, "Argument for expression "+self.name+" is an n-ary numeric value: "+arg.name
     75
     76    #
     77    # this method contrast with the fixed_value() method.
     78    # the fixed_value() method returns true iff the value is
     79    # an atomic constant.
     80    # this method returns true iff all composite arguments
     81    # in this sum expression are constant, i.e., numeric
     82    # constants or parametrs. the parameter values can of
     83    # course change over time, but at any point in time,
     84    # they are constant. hence, the name.
     85    #
     86    def is_constant(self):
     87        for arg in self._args:
     88            if not arg.is_constant():
     89                return False
     90        return True
    7591
    7692    def simplify(self, model):
     
    412428        tmp._const = self._const
    413429        return tmp
    414     #
    415     # this method contrast with the fixed_value() method.
    416     # the fixed_value() method returns true iff the value is
    417     # an atomic constant.
    418     # this method returns true iff all composite arguments
    419     # in this sum expression are constant, i.e., numeric
    420     # constants or parametrs. the parameter values can of
    421     # course change over time, but at any point in time,
    422     # they are constant. hence, the name.
    423     #
    424     def evaluates_to_constant(self):
    425         for arg in self._args:
    426             if arg.fixed_value() is False:
    427                 return False
    428         return True
    429430
    430431    def scale(self, val):
  • coopr.pyomo/trunk/coopr/pyomo/base/numvalue.py

    r1768 r1959  
    99#  _________________________________________________________________________
    1010
    11 __all__ = ['value', 'NumericValue', 'as_numeric', 'NumericConstant', 'ZeroConstant', 'OneConstant']
     11__all__ = ['value', 'NumericValue', 'as_numeric', 'NumericConstant', 'ZeroConstant', 'OneConstant', 'is_constant']
    1212
    1313import plugin
     
    3838        raise ValueError, "No value for uninitialized NumericValue object "+obj.name
    3939    return tmp
    40    
     40
     41def is_constant(obj):
     42    """
     43    A utility function that returns a boolean that indicates whether the object is a constant
     44    """
     45    if obj is None:
     46        return False   
     47    elif type(obj) in [bool,int,long,float]:
     48        return True
     49    if not isinstance(obj, NumericValue):
     50        return False
     51    return obj.is_constant()
    4152
    4253def as_numeric(obj):
     
    7586        #print "NUMVAL",self.name,self.domain,self.value
    7687
     88    def is_constant(self):
     89        return True
     90
    7791    def fixed_value(self):
    7892        return False
  • coopr.pyomo/trunk/coopr/pyomo/base/var.py

    r1926 r1959  
    6969
    7070    def fixed_value(self):
     71        if self.fixed:
     72            return True
     73        return False
     74
     75    def is_constant(self):
    7176        if self.fixed:
    7277            return True
     
    374379        self._varval[None].var = self
    375380
     381    def is_constant(self):
     382        return _VarValue.is_constant(self)
     383
    376384
    377385class _VarArray(_VarBase):
  • coopr.pyomo/trunk/coopr/pyomo/presolve/collect_linear_terms.py

    r1804 r1959  
    9292                   if e.fixed_value():
    9393                       c /= e.value
    94                    elif (isinstance(e, expr._SumExpression) is True) and (e.evaluates_to_constant() is True):
    95                       # the following logic should be extended to product expressions and all other types
    96                       # of core expressions; this is experimental, based on issues with logically valid
    97                       # expressions being flagged as "nonlinear, with variables". in particular, the
    98                       # evaluates_to_constant() should be a method of the base class.
     94                   elif e.is_constant():
     95                      # This is experimental, based on issues with logically valid
     96                      # expressions being flagged as "nonlinear, with variables".
    9997                      try:
    10098                         c /= e()
  • coopr.pyomo/trunk/coopr/pyomo/tests/unit/test_expr.py

    r1768 r1959  
    416416        try:
    417417            instance.b[3] = -2.2
    418             print "HERE",type(instance.b[3])
     418            #print "HERE",type(instance.b[3])
    419419            self.fail("can't set an array variable with a bad value")
    420420        except ValueError:
     
    477477            return (3.0,model.b[1])
    478478        def c5_rule(i,model):
    479             return (0.0,model.b[i])
     479            return (model.b[i],0.0)
     480
     481        def c6_rule(model):
     482            return 0.0 <= model.c
     483        def c7_rule(model):
     484            return model.c <= 1.0
     485        def c8_rule(model):
     486            return model.c == 2.0
     487        def c9_rule(model):
     488            return model.A+model.A <= model.c
     489        def c10_rule(model):
     490            return model.c <= model.B+model.B
     491        def c11_rule(model):
     492            return model.c == model.A+model.B
     493
     494        def c12_rule(model):
     495            return model.c == model.d
     496        def c13_rule(model):
     497            return model.c <= model.d
     498        def c14_rule(model):
     499            return model.c >= model.d
     500
     501        def c20_rule(model):
     502            return model.A > model.c > model.B
     503        def c21_rule(model):
     504            return model.A > model.c < model.B
     505        def c22_rule(model):
     506            return model.A < model.c > model.B
     507        def c23_rule(model):
     508            return model.A < model.c < model.B
     509
    480510        def o2_rule(i,model):
    481511            return model.b[i]
     
    484514        model.b = Var(model.a,initialize=1.1,within=PositiveReals)
    485515        model.c = Var(initialize=2.1, within=PositiveReals)
     516        model.d = Var(initialize=3.1, within=PositiveReals)
     517        model.e = Var(initialize=4.1, within=PositiveReals)
     518        model.A = Param(default=-1)
     519        model.B = Param(default=-2)
    486520        #model.o1 = Objective()
    487521        model.o2 = Objective(model.a,rule=o2_rule)
     
    492526        model.c4 = Constraint(rule=c4_rule)
    493527        model.c5 = Constraint(model.a,rule=c5_rule)
     528
     529        model.c6 = Constraint(rule=c6_rule)
     530        model.c7 = Constraint(rule=c7_rule)
     531        model.c8 = Constraint(rule=c8_rule)
     532        model.c9 = Constraint(rule=c9_rule)
     533        model.c10 = Constraint(rule=c10_rule)
     534        model.c11 = Constraint(rule=c11_rule)
     535
     536        model.c12 = Constraint(rule=c12_rule)
     537        model.c13 = Constraint(rule=c13_rule)
     538        model.c14 = Constraint(rule=c14_rule)
     539
     540        #model.c20 = Constraint(rule=c20_rule)
     541        #model.c21 = Constraint(rule=c21_rule)
     542        #model.c22 = Constraint(rule=c22_rule)
     543        #model.c23 = Constraint(rule=c23_rule)
     544
    494545        instance=model.create()
    495546        OUTPUT=open(currdir+"varpprint.out","w")
  • coopr.pyomo/trunk/coopr/pyomo/tests/unit/varpprint.txt

    r1484 r1959  
    990 RangeSet Declarations
    1010
    11 0 Param Declarations
     112 Param Declarations
     12   A :  Size=1  Domain=Any
     13        -1
     14        default: -1
     15   B :  Size=1  Domain=Any
     16        -2
     17        default: -2
    1218
    13 2 Var Declarations
     194 Var Declarations
    1420   b :  Size=3  Domain=PositiveReals
    1521        Key : Initial Value : Lower Bound : Upper Bound : Current Value: Fixed
     
    2026        Initial Value : Lower Bound : Upper Bound : Current Value: Fixed
    2127        2.1 : 0 : None : None : False
     28   d :  Size=1  Domain=PositiveReals
     29        Initial Value : Lower Bound : Upper Bound : Current Value: Fixed
     30        3.1 : 0 : None : None : False
     31   e :  Size=1  Domain=PositiveReals
     32        Initial Value : Lower Bound : Upper Bound : Current Value: Fixed
     33        4.1 : 0 : None : None : False
    2234
    23352 Objective Declarations
     
    2840   o3 :         Size=0  Index= o3_index
    2941
    30 5 Constraint Declarations
     4214 Constraint Declarations
    3143   c1 :         Size=1
    3244        None
    3345                identity( 1.0 )
    3446                identity( b[1] )
     47                Inf
     48   c10 :        Size=1
     49        None
     50                -Inf
     51                identity( c )
     52                sum( B , B )
     53   c11 :        Size=1
     54        None
     55                sum( A , B )
     56                identity( c )
     57                sum( A , B )
     58   c12 :        Size=1
     59        None
     60                identity( 0.0 )
     61                sum( c , -1 *  d )
     62                identity( 0.0 )
     63   c13 :        Size=1
     64        None
     65                identity( 0.0 )
     66                sum( d , -1 *  c )
     67                Inf
     68   c14 :        Size=1
     69        None
     70                identity( 0.0 )
     71                sum( c , -1 *  d )
    3572                Inf
    3673   c2 :         Size=1
     
    6299                identity( b[3] )
    63100                identity( 0.0 )
     101   c6 :         Size=1
     102        None
     103                identity( 0.0 )
     104                identity( c )
     105                Inf
     106   c7 :         Size=1
     107        None
     108                -Inf
     109                identity( c )
     110                identity( 1.0 )
     111   c8 :         Size=1
     112        None
     113                identity( 2.0 )
     114                identity( c )
     115                identity( 2.0 )
     116   c9 :         Size=1
     117        None
     118                sum( A , A )
     119                identity( c )
     120                Inf
    64121
    65 11 Declarations: a b c o2 o3_index o3 c1 c2 c3 c4 c5
     12224 Declarations: a b c d e A B o2 o3_index o3 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14
Note: See TracChangeset for help on using the changeset viewer.