Changeset 2640


Ignore:
Timestamp:
Jun 2, 2010 12:56:37 PM (11 years ago)
Author:
prsteel
Message:

Refactored repn_add

Refactored variable names to be more self-explanatory.
Referenced comments in generate_canonical_repn.
Added inline explanations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • coopr.pyomo/trunk/coopr/pyomo/expr/canonical_repn.py

    r2214 r2640  
    1717import copy
    1818
    19 
    2019#
    2120# A frozen dictionary that can be hashed.  This dictionary isn't _really_
     
    3029        return rval
    3130
     31#
     32# Generate a canonical representation of an expression.
     33#
     34# The canonical representation is a dictionary.  Each element is a mapping
     35# from a term degree to terms in the expression.  If the term degree is
     36# None, then the map value is simply an expression of terms without a
     37# specific degree.  Otherwise, the map value is a dictionary of terms to
     38# their coefficients.  A term is represented as a frozen dictionary that
     39# maps variable id to variable power.  A constant term is represented
     40# with None.
     41#
     42# Examples:
     43#  Let x[1] ... x[4] be the first 4 variables, and
     44#      y[1] ... y[4] be the next 4 variables
     45#
     46# 1.3                           {0:{ None :1.3}}
     47# 3.2*x[1]                      {1:{ {0:1} :3.2}}
     48# 2*x[1]*y[2] + 3*x[2] + 4      {0:{None:4.0}, 1:{{1:1}:3.0}, 2:{{0:1, 5:1}:2.0}}
     49# 2*x[1]**4*y[2]    + 4         {0:{None:4.0}, 1:{{1:1}:3.0}, 5:{{0:4, 5:1 }:2.0}}
     50# log(y[1]) + x[1]*x[1]         {2:{{0:2}:1.0}, None:log(y[1])}
     51#
     52def generate_canonical_repn(expr):
     53    return collect_canonical_repn(expr)
    3254
    3355
     
    6183    return expr
    6284   
    63 
    64 def repn_add(rep, r2, coef=1.0):
    65     for d in r2:
    66         if d is None:
    67             if d in rep:
    68                 rep[d] += r2[d]
     85def repn_add(lhs, rhs, coef=1.0):
     86    """
     87    lhs and rhs are the expressions being added together.
     88    'lhs' and 'rhs' are left-hand and right-hand side operands
     89    See generate_canonical_repn for explanation of pyomo expressions
     90    """
     91    for order in rhs:
     92        # For each order term, first-order might be 3*x,
     93        # second order 4*x*y or 5*x**2
     94        if order is None:
     95            # i.e., (currently) order is a constant or logarithm
     96            if order in lhs:
     97                lhs[order] += rhs[order]
    6998            else:
    70                 rep[d] = r2[d]
    71             continue
    72         if d < 0:
    73             continue
    74         if not d in rep:
    75             rep[d] = {}
    76         for var in r2[d]:
    77             rep[d][var] = coef*r2[d][var] + rep[d].get(var,0.0)
     99                lhs[order] = rhs[order]
     100            continue
     101        if order < 0:
     102            # ignore now, handled below
     103            continue
     104        if not order in lhs:
     105            lhs[order] = {}
     106        for var in rhs[order]:
     107            # Add coefficients of variables in this order (e.g., third power)
     108            lhs[order][var] = coef*rhs[order][var] + lhs[order].get(var,0.0)
    78109    #
    79110    # Merge the VarValue maps
    80111    #
    81     if -1 in r2:
    82         if -1 in rep:
    83             rep[-1].update(r2[-1])
    84         else:
    85             rep[-1] = r2[-1]
    86     return rep
     112    if -1 in rhs:
     113        if -1 in lhs:
     114            lhs[-1].update(rhs[-1])
     115        else:
     116            lhs[-1] = rhs[-1]
     117    return lhs
    87118
    88119
     
    236267
    237268
    238 #
    239 # Generate a canonical representation of an expression.
    240 #
    241 # The canonical representation is a dictionary.  Each element is a mapping
    242 # from a term degree to terms in the expression.  If the term degree is
    243 # None, then the map value is simply an expression of terms without a
    244 # specific degree.  Otherwise, the map value is a dictionary of terms to
    245 # their coefficients.  A term is represented as a frozen dictionary that
    246 # maps variable id to variable power.  A constant term is represented
    247 # with None.
    248 #
    249 # Examples:
    250 #  Let x[1] ... x[4] be the first 4 variables, and
    251 #      y[1] ... y[4] be the next 4 variables
    252 #
    253 # 1.3                           {0:{ None :1.3}}
    254 # 3.2*x[1]                      {1:{ {0:1} :3.2}}
    255 # 2*x[1]*y[2] + 3*x[2] + 4      {0:{None:4.0}, 1:{{1:1}:3.0}, 2:{{0:1, 5:1}:2.0}}
    256 # log(y[1]) + x[1]*x[1]         {2:{{0:2}:1.0}, None:log(y[1])}
    257 #
    258 def generate_canonical_repn(expr):
    259     return collect_canonical_repn(expr)
    260269
    261270def is_constant(repn):
Note: See TracChangeset for help on using the changeset viewer.