Changeset 5089


Ignore:
Timestamp:
10/13/11 17:45:37 (3 years ago)
Author:
jwatson
Message:

Created specialized encoding for linear components of canonical expressions, to avoid the use (and memory) associated with frozendicts. Corresponding changes required to expression flattener and LP writer.

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

Legend:

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

    r4675 r5089  
    8282            if val != 0: 
    8383                ans[0] = { None: val } 
    84         tmp = ans.setdefault(1,{}) 
    85         for key, val in coef.iteritems(): 
    86             tmp[frozendict({key:1})] = val 
     84        ans[1] = coef 
    8785        ans[-1] = varmap 
    8886        return ans 
    8987    elif degree > 1: 
    90         return collect_general_canonical_repn(exp) 
     88        ans = collect_general_canonical_repn(exp) 
     89        if 1 in ans: 
     90            linear_terms = {} 
     91            for key, coef in ans[1].iteritems(): 
     92                linear_terms[key.keys()[0]] = coef 
     93            ans[1] = linear_terms 
     94        return ans 
    9195    elif degree == 0: 
    9296        return { 0: { None:exp() } } 
     
    233237        return {} 
    234238    elif exp.__class__ is _VarValue: 
    235         key = ( id(exp.var().model()), exp.id ) 
    236         return { key : exp } 
     239        return { id(exp) : exp } 
    237240    elif exp.type() is Var: 
    238         key = ( id(exp.model()), exp.id ) 
    239         return { key : exp } 
     241        return { id(exp) : exp } 
    240242    else: 
    241243        raise ValueError, "Unexpected expression type: "+str(exp) 
     
    254256        return { None: exp() }, {} 
    255257    elif exp.__class__ is _VarValue: 
    256         if exp.var() is not None and exp.var().model is not None: 
    257             key = ( id(exp.var().model()), exp.id ) 
    258         else: 
    259             key = ( id(None), exp.id ) 
     258        key = id(exp) 
    260259        return { key : 1.0 }, { key : exp } 
    261260    elif exp.is_expression(): 
     
    303302                if (arg.__class__ is _VarValue) and (arg.fixed is False): 
    304303                    # save an expensive recursion - this is by far the most common case. 
    305                     if arg.var is not None and arg.var() is not None and arg.var().model is not None: 
    306                         var_key = ( id(arg.var().model()), arg.id ) 
    307                     else: 
    308                         var_key = ( id(None), arg.id ) 
     304                    var_key = id(arg) 
    309305                    varmap.setdefault(var_key, arg) 
    310306                    coef[var_key] = coef.get(var_key, 0.0) + arg_coef 
     
    320316                              (type(exp).__name__, str(exp)) ) 
    321317    elif exp.type() is Var: 
    322         if exp.model is not None: 
    323             key = ( id(exp.model()), exp.id ) 
    324         else: 
    325             key = ( id(None), exp.id ) 
     318        key = id(exp) 
    326319        return { key : 1.0 }, { key : exp } 
    327320    elif isinstance(exp, _ConnectorValue): 
     
    415408    # 
    416409    elif type(exp) is _VarValue or exp.type() is Var: 
    417         if type(exp) is _VarValue: 
    418             if exp.var() is not None and exp.var().model is not None: 
    419                 mid = id(exp.var().model()) 
    420             else: 
    421                 mid = id(None) 
    422         else: 
    423             if exp.model is not None: 
    424                 mid = id(exp.model()) 
    425             else: 
    426                 mid = id(None) 
    427         temp_var = { -1: {(mid,exp.id):exp}, 1: {frozendict({(mid,exp.id):1}):1.0} } 
     410        temp_var = { -1: {id(exp):exp}, 1: {frozendict({id(exp):1}):1.0} } 
    428411        return temp_var 
    429412    # 
  • coopr.pyomo/trunk/coopr/pyomo/expr/linear_repn.py

    r4119 r5089  
    4848                    constant_term = canonical_encoding[0][None] 
    4949 
    50                 for variable_key, coefficient in canonical_encoding[1].iteritems(): 
    51                     var_value = variable_map[variable_key.keys()[0]] 
    52                     linear_terms.append((coefficient, var_value)) 
     50                for var_hash, var_coefficient in canonical_encoding[1].iteritems(): 
     51                    var_value = variable_map[var_hash] 
     52                    linear_terms.append((var_coefficient, var_value)) 
    5353 
    5454                # eliminate the expression tree - we don't need it any longer. 
  • coopr.pyomo/trunk/coopr/pyomo/io/cpxlp.py

    r5075 r5089  
     1 
    12#  _________________________________________________________________________ 
    23# 
     
    2829from pyutilib.misc import deprecated, tostr 
    2930 
    30 # various labelers used by the LP writer. exporting them for broader visibility 
    31 # because they are useful in other contexts at the moment, specifically when 
    32 # re-building symbol maps for particular instances. 
    33  
    34 class CPXLP_numeric_labeler(object): 
    35     def __init__(self, prefix): 
    36         self.id = 0 
    37         self.prefix = prefix 
    38     def __call__(self, obj): 
    39         self.id += 1 
    40         return self.prefix + str(self.id) 
    41  
    42 class CPXLP_text_labeler(object): 
    43     def __call__(self, obj): 
    44         label = str(obj.name) 
    45  
    46         try: 
    47             block = obj.component 
    48         except: 
    49             block = None 
    50  
    51         if block is None: 
    52             return label_from_name(label) 
    53         block = block().parent 
    54         if block is None: 
    55             return label_from_name(label) 
    56  
    57         block = block() 
    58         while block.parent is not None and block.parent() is not None: 
    59             label = block.name + "." + label 
    60             block = block.parent() 
    61         return label_from_name(label) 
    62  
    63 class CPXLP_prefix_labeler(object): 
    64     def __call__(self, obj): 
    65         label = str(obj.name) 
    66  
    67         # We *really* need to move to a unified "parent" notion... 
    68         try: 
    69             block = obj.component 
    70         except: 
    71             block = None 
    72  
    73         if block is None: 
    74             return label_from_name(label) 
    75         block = block().parent 
    76         if block is None: 
    77             return label_from_name(label) 
    78  
    79         block = block() 
    80         while block is not None: 
    81             label = block.name + "." + label 
    82             block = block.parent() 
    83         return label_from_name(label) 
    84  
    8531 
    8632class ProblemWriter_cpxlp(AbstractProblemWriter): 
     
    14086            return None 
    14187 
     88 
     89    class _numeric_labeler(object): 
     90        def __init__(self, prefix): 
     91            self.id = 0 
     92            self.prefix = prefix 
     93        def __call__(self, obj): 
     94            self.id += 1 
     95            return self.prefix + str(self.id) 
     96 
     97    class _text_labeler(object): 
     98        def __call__(self, obj): 
     99            label = str(obj.name) 
     100 
     101            try: 
     102                block = obj.component 
     103            except: 
     104                block = None 
     105 
     106            if block is None: 
     107                return label_from_name(label) 
     108            block = block().parent 
     109            if block is None: 
     110                return label_from_name(label) 
     111 
     112            block = block() 
     113            while block.parent is not None and block.parent() is not None: 
     114                label = block.name + "." + label 
     115                block = block.parent() 
     116            return label_from_name(label) 
     117 
     118    class _prefix_labeler(object): 
     119        def __call__(self, obj): 
     120            label = str(obj.name) 
     121 
     122            # We *really* need to move to a unified "parent" notion... 
     123            try: 
     124                block = obj.component 
     125            except: 
     126                block = None 
     127 
     128            if block is None: 
     129                return label_from_name(label) 
     130            block = block().parent 
     131            if block is None: 
     132                return label_from_name(label) 
     133 
     134            block = block() 
     135            while block is not None: 
     136                label = block.name + "." + label 
     137                block = block.parent() 
     138            return label_from_name(label) 
     139 
     140 
    142141    @staticmethod 
    143142    def _collect_key ( a ): 
     
    255254        if 1 in x: 
    256255            sorted_names = [] 
    257             for this_hash, coefficient in x[1].iteritems(): 
    258                 var_value = x[-1][this_hash.keys()[0]] 
     256            for var_hash, var_coefficient in x[1].iteritems(): 
     257                var_value = x[-1][var_hash] 
    259258                name = symbol_map.getSymbol( var_value, labeler ) 
    260                 sorted_names.append((name,coefficient)) 
     259                sorted_names.append((name,var_coefficient)) 
    261260 
    262261            sorted_names.sort() 
     
    390389        symbol_map = SymbolMap(model) 
    391390        if self._output_prefixes: 
    392             labeler = CPXLP_prefix_labeler() 
     391            labeler = ProblemWriter_cpxlp._prefix_labeler() 
    393392        else: 
    394             labeler = CPXLP_text_labeler() 
    395         #labeler = CPXLP_numeric_labeler('x') 
     393            labeler = ProblemWriter_cpxlp._text_labeler() 
     394        #labeler = ProblemWriter_cpxlp._numeric_labeler('x') 
    396395        _obj = model.active_components(Objective) 
    397396 
Note: See TracChangeset for help on using the changeset viewer.