Changeset 3688


Ignore:
Timestamp:
Feb 21, 2011 2:30:02 PM (9 years ago)
Author:
jdsiiro
Message:

Significant simplification of expression hierarchy (removes many
unneeded slots).

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

Legend:

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

    r3658 r3688  
    2020import sys
    2121import copy
    22 
     22import logging
     23import StringIO
     24
     25logger = logging.getLogger('coopr.pyomo')
    2326
    2427class Expression(NumericValue):
    2528    """An object that defines a mathematical expression that can be evaluated"""
    2629
    27     __slots__ = '_args','_operation','_tuple_op'
    28 
    29     def __init__(self, name="UNKNOWN", nargs=None, args=None, operation=None, tuple_op=False):
     30    __slots__ = ('_args', )
     31
     32    def __init__(self, name, nargs, args):
    3033        """Construct an expression with an operation and a set of arguments"""
    3134        NumericValue.__init__(self, name=name)
    3235        self._args=args
    33         self._operation=operation
    34         self._tuple_op=tuple_op
    3536        if nargs and nargs != len(args):
    36             raise ValueError, "There were " + `len(self._args)` + " arguments specified for expression " + self.name + " but this expression requires " + `nargs` + " arguments"
     37            raise ValueError, "%s() takes exactly %d arguments (%d given)" % \
     38                ( name, nargs, len(args) )
    3739
    3840    def __getstate__(self):
     
    6769    def clone(self):
    6870        """Clone this object using the specified arguments"""
    69         if self.__class__ is Expression:
    70            return Expression( name=self.name, nargs=None, args=copy.copy(self._args),
    71                               operation=self._operation, tuple_op=self._tuple_op)
    72         return self.__class__(args=copy.copy(self._args))
     71        raise NotImplementedError, "Derived expression (%s) failed to "\
     72            "implement clone()" % ( str(self.__class__), )
    7373
    7474    def simplify(self, model):
     
    110110    def __call__(self, exception=True):
    111111        """Evaluate the expression"""
    112         values=[]
    113         for arg in self._args:
    114           try:
    115             val = value(arg)
    116           except ValueError, e:
     112        try:
     113            return self._apply_operation(self._evaluate_arglist(self._args))
     114        except (ValueError, TypeError):
    117115            if exception:
    118                 raise ValueError, "Error evaluating expression: %s" % str(e)
     116                raise
    119117            return None
    120           #try:
    121           #  val = value(arg)
    122           #except AttributeError:
    123           #  return None
    124           if val is None:
    125              return None
    126           values.append( val )
    127         return self._apply_operation(values)
     118
     119    def _evaluate_arglist(self, arglist):
     120        for arg in arglist:
     121            try:
     122                yield value(arg)
     123            except Exception, e:
     124                buffer = StringIO.StringIO()
     125                self.pprint(buffer)
     126                logger.error("evaluating expression: %s\nExpression: %s",
     127                             str(e), buffer.getvalue())
     128                raise
    128129
    129130    def _apply_operation(self, values):
    130         """Method that can be overwritten to re-define the operation in this expression"""
    131         if self._tuple_op:
    132            return self._operation(*tuple(values))
    133         else:
    134            return self._operation(values)
     131        """Method that can be overwritten to define the operation in
     132        this expression"""
     133        raise NotImplementedError, "Derived expression (%s) failed to "\
     134            "implement _apply_operation()" % ( str(self.__class__), )
    135135       
    136136    def __str__(self):
    137137        return self.name
    138138
     139
     140class _IntrinsicFunctionExpression(Expression):
     141    __slots__ = ('_operator', )
     142
     143    def __init__(self, name, nargs, args, operator):
     144        """Construct an expression with an operation and a set of arguments"""
     145        Expression.__init__(self, name=name, nargs=nargs, args=args)
     146        self._operator = operator
     147
     148    def __getstate__(self):
     149       result = Expression.__getstate__(self)
     150       for i in _IntrinsicFunctionExpression.__slots__:
     151          result[i] = getattr(self, i)
     152       return result
     153
     154    def clone(self):
     155        return self.__class__( self.name,
     156                               None,
     157                               copy.copy(self._args),
     158                               self._operator )
     159
     160    def _apply_operation(self, values):
     161        return self._operator(*tuple(values))
     162
     163
     164# Should this actually be a special class, or just an instance of
     165# _IntrinsicFunctionExpression (like sin, cos, etc)?
     166class _AbsExpression(_IntrinsicFunctionExpression):
     167
     168    __slots__ = ()
     169
     170    def __init__(self, args):
     171        _IntrinsicFunctionExpression.__init__(self, 'abs', 1, args, abs)
     172
     173    def __getstate__(self):
     174       return _IntrinsicFunctionExpression.__getstate__(self)
     175
     176    def clone(self):
     177        return self.__class__( copy.copy(self._args) )
     178
     179# Should this actually be a special class, or just an instance of
     180# _IntrinsicFunctionExpression (like sin, cos, etc)?
     181class _PowExpression(_IntrinsicFunctionExpression):
     182
     183    __slots__ = ()
     184
     185    def __init__(self, args):
     186        _IntrinsicFunctionExpression.__init__(self, 'pow', 2, args, pow)
     187
     188    def __getstate__(self):
     189       return _IntrinsicFunctionExpression.__getstate__(self)
     190 
     191    def clone(self):
     192        return self.__class__( copy.copy(self._args) )
     193
     194    def polynomial_degree(self):
     195        # Right now, all _PowExpressions are considered to be
     196        # non-polynomial, even though there is a special case where
     197        # _args[0] is polynomial and _args[1] is constant and a
     198        # non-negative integer.  I am still choosing to return
     199        # "nonpolynomial" because most consumers (like expression
     200        # compilers) do not recognize that pow could actually be
     201        # polynomial.
     202        return None
     203
     204
    139205class _LinearExpression(Expression):
    140206
    141207    __slots__ = ()
     208
     209    def __init__(self, name, nargs, args):
     210        """Constructor"""
     211        Expression.__init__(self, name, nargs, args)
     212
     213    def __getstate__(self):
     214       return Expression.__getstate__(self)
     215
     216    def clone(self):
     217        return self.__class__( copy.copy(self._args) )
    142218
    143219    def polynomial_degree(self):
     
    160236    def __init__(self, args):
    161237        """Constructor"""
    162         Expression.__init__(self,name='lt',nargs=2,args=args)
     238        _LinearExpression.__init__(self, 'lt', 2, args)
     239
     240    def __getstate__(self):
     241       return _LinearExpression.__getstate__(self)
    163242
    164243    def _apply_operation(self, values):
    165244        """Method that defines the less-than operation"""
    166         return values[0] < values[1]
     245        return values.next() < values.next()
    167246
    168247
     
    174253    def __init__(self, args):
    175254        """Constructor"""
    176         Expression.__init__(self,name='lt',nargs=2,args=args)
     255        _LinearExpression.__init__(self, 'le', 2, args)
     256
     257    def __getstate__(self):
     258       return _LinearExpression.__getstate__(self)
    177259
    178260    def _apply_operation(self, values):
    179261        """Method that defines the less-than-or-equal operation"""
    180         return values[0] <= values[1]
     262        return values.next() <= values.next()
    181263
    182264
     
    188270    def __init__(self, args):
    189271        """Constructor"""
    190         Expression.__init__(self,name='eq',nargs=2,args=args)
     272        _LinearExpression.__init__(self, 'eq', 2, args)
     273
     274    def __getstate__(self):
     275       return _LinearExpression.__getstate__(self)
    191276
    192277    def _apply_operation(self, values):
    193278        """Method that defines the equal-to operation"""
    194         return values[0] == values[1]
     279        return values.next() == values.next()
    195280
    196281
     
    198283    """An object that defines a product expression"""
    199284
    200     __slots__ = '_denominator','_numerator','coef'
     285    __slots__ = ('_denominator','_numerator','coef')
    201286
    202287    def __init__(self):
    203288        """Constructor"""
    204         Expression.__init__(self,name='prod',nargs=None)
     289        Expression.__init__(self,name='prod',nargs=None, args=None)
    205290        self._denominator = []
    206291        self._numerator = []
     
    226311            if x.polynomial_degree() != 0:
    227312                return None
    228         # NB: We can't use sum() here because None (non-polynomial)
    229         # overrides a numeric value (and sum() just ignores it)
    230         degree = 0
    231         for x in self._numerator:
    232             x_degree = x.polynomial_degree()
    233             if x_degree is None:
    234                 return None
    235             degree += x_degree
    236         return degree
     313        try:
     314            return sum(x.polynomial_degree() for x in self._numerator)
     315        except TypeError:
     316            return None
    237317
    238318    def invert(self):
     
    307387    def __call__(self, exception=True):
    308388        """Evaluate the expression"""
    309         ans = self.coef
    310         for arg in self._numerator:
    311             try:
    312                 val = value(arg)
    313             except ValueError, e:
    314                 if exception:
    315                     raise ValueError, "Error evaluating expression: %s" % str(e)
    316                 return None
    317             if val is None:
    318                 return None
    319             ans *= val
    320         for arg in self._denominator:
    321             try:
    322                 val = value(arg)
    323             except ValueError, e:
    324                 if exception:
    325                     raise ValueError, "Error evaluating expression: %s" % str(e)
    326                 return None
    327             if val is None:
    328                 return None
    329             if val != 1:
    330                 ans /= 1.0*val
    331         return ans
    332 
    333 
    334 class _IdentityExpression(Expression):
     389        try:
     390            ans = self.coef
     391            for n in self._evaluate_arglist(self._numerator):
     392                ans *= n
     393            for n in self._evaluate_arglist(self._denominator):
     394                ans /= n
     395            return ans
     396        except (TypeError, ValueError):
     397            if exception:
     398                raise
     399            return None
     400
     401
     402class _IdentityExpression(_LinearExpression):
    335403    """An object that defines a identity expression"""
    336404
     
    341409        arg_type = type(args)
    342410        if arg_type is list or arg_type is tuple:
    343            Expression.__init__(self,name='identity',nargs=1,args=args)
     411           Expression.__init__(self, 'identity', 1, args)
    344412        else:
    345            Expression.__init__(self,name='identity',nargs=1,args=[args])
     413           Expression.__init__(self, 'identity', 1, [args])
     414
     415    def __getstate__(self):
     416       return _LinearExpression.__getstate__(self)
    346417
    347418    def _apply_operation(self, values):
    348419        """Method that defines the identity operation"""
    349         return values[0]
    350 
    351     def polynomial_degree(self):
    352         return self._args[0].polynomial_degree()
    353 
    354 
    355 class _AbsExpression(Expression):
    356 
    357     __slots__ = ()
    358 
    359     def __init__(self, args):
    360         Expression.__init__(self, name='abs', nargs=1, args=args, operation=abs, tuple_op=True)
    361 
    362 
    363 class _PowExpression(Expression):
    364 
    365     __slots__ = ()
    366 
    367     def __init__(self, args):
    368         Expression.__init__(self, name='pow', nargs=2, args=args, operation=pow, tuple_op=True)
    369 
    370     def polynomial_degree(self):
    371         # Right now, all _PowExpressions are considered to be
    372         # non-polynomial, even though there is a special case where
    373         # _args[0] is polynomial and _args[1] is constant and a
    374         # non-negative integer.  I am still choosing to return
    375         # "nonpolynomial" because most consumers (like expression
    376         # compilers) do not recognize that pow could actually be
    377         # polynomial.
    378         return None
     420        return values.next()
    379421
    380422
     
    382424    """An object that defines a weighted summation of expressions"""
    383425
    384     __slots__ = '_coef','_const'
     426    __slots__ = ('_coef','_const')
    385427
    386428    def __init__(self):
    387429        """Constructor"""
    388         Expression.__init__(self,name='sum',nargs=None,args=[])
     430        _LinearExpression.__init__(self, 'sum', None, [])
    389431        self._coef = []
    390432        self._const = 0
    391433
    392434    def __getstate__(self):
    393        result = Expression.__getstate__(self)
     435       result = _LinearExpression.__getstate__(self)
    394436       for i in _SumExpression.__slots__:
    395437          result[i] = getattr(self, i)
     
    437479              print >>ostream, ""
    438480
    439     def __call__(self, exception=True):
     481    def _apply_operation(self, values):
    440482        """Evaluate the expression"""
    441         values=[]
    442         for i, arg in enumerate(self._args):
    443             try:
    444                 val = value(arg)
    445             except ValueError, e:
    446                 if exception:
    447                     raise ValueError, "Error evaluating expression: %s" % str(e)
    448                 return None
    449             if val is None:
    450                 return None
    451             values.append( self._coef[i]*val )
    452         return sum(values)+self._const
     483        return sum(c*values.next() for c in self._coef) + self._const
    453484
    454485    def add_term(self,expr=None,coef=1):
     
    467498def generate_expression(*_args):
    468499    def _clone_if_needed(obj):
    469             #if obj.is_expression():
    470             count = sys.getrefcount(obj) - generate_expression.UNREFERENCED_EXPR_COUNT
    471             if generate_expression.clone_if_needed_callback:
    472                 generate_expression.clone_if_needed_callback(count)
    473             if count == 0:
    474                 return obj
    475             elif count > 0:
    476                 generate_expression.clone_counter += 1
    477                 return obj.clone()
    478             else:
    479                 raise RuntimeError, "Expression entered generate_expression() "\
    480                       "with too few references (%s<0); this is indicative of a "\
    481                       "SERIOUS ERROR in the expression reuse detection scheme." %\
    482                       (count)
    483             #return obj
     500        count = sys.getrefcount(obj) - generate_expression.UNREFERENCED_EXPR_COUNT
     501        if generate_expression.clone_if_needed_callback:
     502            generate_expression.clone_if_needed_callback(count)
     503        if count == 0:
     504            return obj
     505        elif count > 0:
     506            generate_expression.clone_counter += 1
     507            return obj.clone()
     508        else:
     509            raise RuntimeError, "Expression entered generate_expression() " \
     510                "with too few references (%s<0); this is indicative of a " \
     511                "SERIOUS ERROR in the expression reuse detection scheme." \
     512                % ( count, )
    484513
    485514    etype = _args[0]
     
    488517        _self = _clone_if_needed(_self)
    489518    elif _self.is_indexed():
    490         msg = "Argument for expression '%s' is an n-ary numeric value: %s" % (etype, _self.name)
    491         msg += "\n    Have you given variable or parameter '%s' an index?" % _self.name
    492         raise ValueError, msg
     519        raise ValueError, "Argument for expression '%s' is an n-ary "\
     520            "numeric value: %s\n    Have you given variable or "\
     521            "parameter '%s' an index?" % (etype, _self.name, _self.name)
    493522       
    494523    #
     
    509538            other = _clone_if_needed(other)
    510539        elif other.is_indexed():
    511             msg = "Argument for expression '%s' is an n-ary numeric value: %s" % (etype, other.name)
    512             msg += "\n    Have you given variable or parameter '%s' an index?" % other.name
    513             raise ValueError, msg
     540            raise ValueError, "Argument for expression '%s' is an n-ary "\
     541                "numeric value: %s\n    Have you given variable or "\
     542                "parameter '%s' an index?" % (etype, _self.name, _self.name)
    514543
    515544    #
     
    532561
    533562    #
     563    # Some binary operators are special cases of other operators
     564    #
     565    multiplier = 1
     566    if etype == 'sub':
     567        multiplier = -1
     568        etype = 'add'
     569
     570    #
    534571    # Now, handle all binary operators
    535572    #
     
    542579        if self_type is _SumExpression:
    543580            if other_type is NumericConstant:
    544                 _self.add_const(other())
     581                _self.add_const(multiplier * other())
    545582            elif other_type is _ProductExpression and \
    546583                 len(other._numerator) == 1 and \
    547584                 not other._denominator:
    548                 _self.add_term(expr=other._numerator[0], coef=other.coef)
     585                _self.add_term( expr=other._numerator[0],
     586                                coef=multiplier*other.coef )
    549587            elif other_type is _SumExpression:
     588                if multiplier < 0:
     589                    other.negate()
    550590                _self.merge(other)
    551591            else:
    552                 _self.add_term(expr=other)
     592                _self.add_term(coef=multiplier, expr=other)
    553593            ans = _self
    554594        else:
    555595            if other_type is _SumExpression:
     596                if multiplier < 0:
     597                    other.negate()
    556598                if self_type is NumericConstant:
    557599                    other.add_const(_self())
     
    570612                         len(_self._numerator) == 1 and \
    571613                         not _self._denominator:
    572                     ans.add_term(expr=_self._numerator[0], coef=_self.coef)
     614                    ans.add_term( expr=_self._numerator[0], coef=_self.coef )
    573615                else:
    574616                    ans.add_term(expr=_self)
    575617                if other_type is NumericConstant:
    576                     ans.add_const(other())
     618                    ans.add_const(multiplier * other())
    577619                elif other_type is _ProductExpression and \
    578620                         len(other._numerator) == 1 and \
    579621                         not other._denominator:
    580                     ans.add_term(expr=other._numerator[0], coef=other.coef)
    581                 else:
    582                     ans.add_term(expr=other)
    583 
    584         # Special cases for simplifying expressions
    585         if ans._const == 0 and len(ans._args) == 1 and ans._coef[0] == 1:
    586             return ans._args[0]
    587         return ans
    588 
    589     elif etype == 'sub':
    590         #
    591         # self - other
    592         #
    593         self_type = type(_self)
    594         other_type = type(other)
    595         if self_type is _SumExpression:
    596             if other_type is NumericConstant:
    597                 _self.add_const(-1 * other())
    598             elif other_type is _ProductExpression and \
    599                  len(other._numerator) == 1 and \
    600                  not other._denominator:
    601                 _self.add_term(expr=other._numerator[0], coef=-1*other.coef)
    602             elif other_type is _SumExpression:
    603                 other.negate()
    604                 _self.merge(other)
    605             else:
    606                 _self.add_term(coef=-1, expr=other)
    607             ans = _self
    608         else:
    609             if type(other) is _SumExpression:
    610                 other.negate()
    611                 if self_type is NumericConstant:
    612                     other.add_const(_self())
    613                 elif self_type is _ProductExpression and \
    614                          len(_self._numerator) == 1 and \
    615                          not _self._denominator:
    616                     other.add_term(expr=_self._numerator[0], coef=_self.coef)
    617                 else:
    618                     other.add_term(expr=_self)
    619                 ans = other
    620             else:
    621                 ans = _SumExpression()
    622                 if self_type is NumericConstant:
    623                     ans.add_const(_self())
    624                 elif self_type is _ProductExpression and \
    625                          len(_self._numerator) == 1 and \
    626                          not _self._denominator:
    627                     ans.add_term(expr=_self._numerator[0], coef=_self.coef)
    628                 else:
    629                     ans.add_term(expr=_self)
    630                 if other_type is NumericConstant:
    631                     ans.add_const(-1 * other())
    632                 elif other_type is _ProductExpression and \
    633                          len(other._numerator) == 1 and \
    634                          not other._denominator:
    635                     ans.add_term(expr=other._numerator[0], coef=-1*other.coef)
    636                 else:
    637                     ans.add_term(expr=other, coef=-1)
     622                    ans.add_term( expr=other._numerator[0],
     623                                  coef=multiplier*other.coef)
     624                else:
     625                    ans.add_term(coef=multiplier, expr=other)
    638626
    639627        # Special cases for simplifying expressions
  • coopr.pyomo/trunk/coopr/pyomo/base/intrinsic_functions.py

    r3565 r3688  
    1717#
    1818
    19 __all__ = ['log', 'log10', 'sin', 'cos', 'tan', 'cosh', 'sinh', 'tanh', 'asin', 'acos', 'atan', 'exp', 'sqrt', 'asinh', 'acosh', 'atanh']
     19__all__ = ['log', 'log10', 'sin', 'cos', 'tan', 'cosh', 'sinh', 'tanh',
     20           'asin', 'acos', 'atan', 'exp', 'sqrt', 'asinh', 'acosh', 'atanh']
    2021
    21 import component
    22 import expr
    23 import numvalue
    2422import math
    2523
    26 
    27 class _IntrinsicFuncExpression(expr.Expression):
    28     """
    29     An expression class that is used for all intrinsic expressions.
    30     """
    31 
    32     def __init__(self, args=(), name=None, operation=None):
    33         expr.Expression.__init__(self, args=args, nargs=len(args), name=name, operation=operation, tuple_op=True)
    34 
    35 def expr_args(*args):
    36     """
    37     Return False if one of the arguments is not an expression or numeric
    38     value.
    39     """
    40     for arg in args:
    41         if not (isinstance(arg,expr.Expression) or isinstance(arg,numvalue.NumericValue) or isinstance(arg,component.Component)):
    42             return False
    43     return True
    44        
     24from component import Component
     25from expr import _IntrinsicFunctionExpression
     26from numvalue import NumericValue, as_numeric
    4527
    4628
     29#class _IntrinsicFuncExpression(expr.Expression):
     30#    """
     31#    An expression class that is used for all intrinsic expressions.
     32#    """
     33#    __slots__ = ()
     34#
     35#    def __init__(self, args, name, operation):
     36#        expr.Expression.__init__(self, args=args, nargs=len(args),
     37#                                 name=name, operation=operation, tuple_op=True)
     38#
     39#    def __getstate__(self):
     40#       result = Expression.__getstate__(self)
     41#       for i in _IntrinsicFuncExpression.__slots__:
     42#          result[i] = getattr(self, i)
     43#       return result
     44
     45
     46def generate_intrinsic_function_expression(args, nargs, name, fcn):
     47    #if len(args) != nargs:
     48    #    raise ValueError, "%s() takes exactly %d argument (%d given)" % \
     49    #        ( name, nargs, len(args) )
     50    pyomo_expression = False
     51    for arg in args:
     52        if isinstance(arg, NumericValue) or isinstance(arg, Component):
     53            pyomo_expression = True
     54            break
     55    if not pyomo_expression:
     56        return fcn(*args)
     57
     58    new_args = []
     59    for arg in args:
     60        new_arg = as_numeric(arg)
     61        if new_arg.is_expression():
     62            new_arg = new_arg.clone()
     63        elif new_arg.is_indexed():
     64            raise ValueError, "Argument for intrinsic function '%s' is an "\
     65                "n-ary numeric value: %s\n    Have you given variable or "\
     66                "parameter '%s' an index?" % (name, new_arg.name, new_arg.name)
     67        new_args.append(arg)
     68    return _IntrinsicFunctionExpression(name, nargs, new_args, fcn)
     69           
     70   
     71
    4772def log(*args):
    48     if len(args) != 1:
    49        raise "TypeError: log() takes exactly 1 argument (%d given)" % len(args)
    50     if expr_args(*args):
    51         tmp = list()
    52         tmp.append(args[0])
    53         return _IntrinsicFuncExpression(args=tmp, name='log', operation=math.log)
    54     return math.log(*args)
     73    return generate_intrinsic_function_expression(args, 1, 'log', math.log)
    5574
    5675def log10(*args):
    57     if len(args) != 1:
    58        raise "TypeError: log10() takes exactly 1 argument (%d given)" % len(args)
    59     if expr_args(*args):
    60         tmp = list()
    61         tmp.append(args[0])
    62         return _IntrinsicFuncExpression(args=tmp, name='log10', operation=math.log10)
    63     return math.log10(*args)
     76    return generate_intrinsic_function_expression(args, 1, 'log10', math.log10)
    6477
    6578def sin(*args):
    66     if len(args) != 1:
    67        raise "TypeError: sin() takes exactly 1 argument (%d given)" % len(args)
    68     if expr_args(*args):
    69         tmp = list()
    70         tmp.append(args[0])
    71         return _IntrinsicFuncExpression(args=tmp, name='sin', operation=math.sin)
    72     return math.sin(*args)
     79    return generate_intrinsic_function_expression(args, 1, 'sin', math.sin)
    7380
    7481def cos(*args):
    75     if len(args) != 1:
    76        raise "TypeError: cos() takes exactly 1 argument (%d given)" % len(args)
    77     if expr_args(*args):
    78         tmp = list()
    79         tmp.append(args[0])
    80         return _IntrinsicFuncExpression(args=tmp, name='cos', operation=math.cos)
    81     return math.cos(*args)
     82    return generate_intrinsic_function_expression(args, 1, 'cos', math.cos)
    8283
    8384def tan(*args):
    84     if len(args) != 1:
    85        raise "TypeError: tan() takes exactly 1 argument (%d given)" % len(args)
    86     if expr_args(*args):
    87         tmp = list()
    88         tmp.append(args[0])
    89         return _IntrinsicFuncExpression(args=tmp, name='tan', operation=math.tan)
    90     return math.tan(*args)
     85    return generate_intrinsic_function_expression(args, 1, 'tan', math.tan)
    9186
    9287def sinh(*args):
    93     if len(args) != 1:
    94        raise "TypeError: sinh() takes exactly 1 argument (%d given)" % len(args)
    95     if expr_args(*args):
    96         tmp = list()
    97         tmp.append(args[0])
    98         return _IntrinsicFuncExpression(args=tmp, name='sinh', operation=math.sinh)
    99     return math.sinh(*args)
     88    return generate_intrinsic_function_expression(args, 1, 'sinh', math.sinh)
    10089
    10190def cosh(*args):
    102     if len(args) != 1:
    103        raise "TypeError: cosh() takes exactly 1 argument (%d given)" % len(args)
    104     if expr_args(*args):
    105         tmp = list()
    106         tmp.append(args[0])
    107         return _IntrinsicFuncExpression(args=tmp, name='cosh', operation=math.cosh)
    108     return math.cosh(*args)
     91    return generate_intrinsic_function_expression(args, 1, 'cosh', math.cosh)
    10992
    11093def tanh(*args):
    111     if len(args) != 1:
    112        raise "TypeError: tanh() takes exactly 1 argument (%d given)" % len(args)
    113     if expr_args(*args):
    114         tmp = list()
    115         tmp.append(args[0])
    116         return _IntrinsicFuncExpression(args=tmp, name='tanh', operation=math.tanh)
    117     return math.tanh(*args)
     94    return generate_intrinsic_function_expression(args, 1, 'tanh', math.tanh)
    11895
    11996def asin(*args):
    120     if len(args) != 1:
    121        raise "TypeError: asin() takes exactly 1 argument (%d given)" % len(args)
    122     if expr_args(*args):
    123         tmp = list()
    124         tmp.append(args[0])
    125         return _IntrinsicFuncExpression(args=tmp, name='asin', operation=math.asin)
    126     return math.asin(*args)
     97    return generate_intrinsic_function_expression(args, 1, 'asin', math.asin)
    12798
    12899def acos(*args):
    129     if len(args) != 1:
    130        raise "TypeError: acos() takes exactly 1 argument (%d given)" % len(args)
    131     if expr_args(*args):
    132         tmp = list()
    133         tmp.append(args[0])
    134         return _IntrinsicFuncExpression(args=tmp, name='acos', operation=math.acos)
    135     return math.acos(*args)
     100    return generate_intrinsic_function_expression(args, 1, 'acos', math.acos)
    136101
    137102def atan(*args):
    138     if len(args) != 1:
    139        raise "TypeError: atan() takes exactly 1 argument (%d given)" % len(args)
    140     if expr_args(*args):
    141         tmp = list()
    142         tmp.append(args[0])
    143         return _IntrinsicFuncExpression(args=tmp, name='atan', operation=math.atan)
    144     return math.atan(*args)
     103    return generate_intrinsic_function_expression(args, 1, 'atan', math.atan)
    145104
    146105def exp(*args):
    147     if len(args) != 1:
    148        raise "TypeError: exp() takes exactly 1 argument (%d given)" % len(args)
    149     if expr_args(*args):
    150         tmp = list()
    151         tmp.append(args[0])
    152         return _IntrinsicFuncExpression(args=tmp, name='exp', operation=math.exp)
    153     return math.exp(*args)
     106    return generate_intrinsic_function_expression(args, 1, 'exp', math.exp)
    154107
    155108def sqrt(*args):
    156     if len(args) != 1:
    157        raise "TypeError: sqrt() takes exactly 1 argument (%d given)" % len(args)
    158     if expr_args(*args):
    159         tmp = list()
    160         tmp.append(args[0])
    161         return _IntrinsicFuncExpression(args=tmp, name='sqrt', operation=math.sqrt)
    162     return math.sqrt(*args)
     109    return generate_intrinsic_function_expression(args, 1, 'sqrt', math.sqrt)
    163110
    164111def asinh(*args):
    165     if len(args) != 1:
    166        raise "TypeError: atan() takes exactly 1 argument (%d given)" % len(args)
    167     if expr_args(*args):
    168         tmp = list()
    169         tmp.append(args[0])
    170         return _IntrinsicFuncExpression(args=tmp, name='asinh', operation=math.asinh)
    171     return math.asinh(*args)
     112    return generate_intrinsic_function_expression(args, 1, 'asinh', math.asinh)
    172113
    173114def acosh(*args):
    174     if len(args) != 1:
    175        raise "TypeError: atan() takes exactly 1 argument (%d given)" % len(args)
    176     if expr_args(*args):
    177         tmp = list()
    178         tmp.append(args[0])
    179         return _IntrinsicFuncExpression(args=tmp, name='acosh', operation=math.acosh)
    180     return math.acosh(*args)
     115    return generate_intrinsic_function_expression(args, 1, 'acosh', math.acosh)
    181116
    182117def atanh(*args):
    183     if len(args) != 1:
    184        raise "TypeError: atan() takes exactly 1 argument (%d given)" % len(args)
    185     if expr_args(*args):
    186         tmp = list()
    187         tmp.append(args[0])
    188         return _IntrinsicFuncExpression(args=tmp, name='atanh', operation=math.atanh)
    189     return math.atanh(*args)
     118    return generate_intrinsic_function_expression(args, 1, 'atanh', math.atanh)
  • coopr.pyomo/trunk/coopr/pyomo/io/ampl.py

    r3566 r3688  
    5454   
    5555    def _print_nonlinear_terms_NL(self, OUTPUT, exp):
    56         if isinstance(exp, intrinsic_functions._IntrinsicFuncExpression):
     56        if isinstance(exp, expr._IntrinsicFunctionExpression):
    5757            if exp.name == 'log':
    5858                print >>OUTPUT, "o43", " #log"
     
    8787            elif exp.name == 'atanh':
    8888                print >>OUTPUT, "o47", " #atanh"
     89            elif exp.name == 'pow':
     90                print >>OUTPUT, "o5", " #^"
     91            else:
     92                logger.error("Unexpected intrinsic function (%s)", exp.name)
     93                raise TypeError, "ASL writer cannot handle '%s' expressions"
    8994               
    9095            for child_exp in exp._args:
     
    820825            return ampl_repn
    821826             
    822         elif isinstance(exp,intrinsic_functions._IntrinsicFuncExpression):
     827        elif isinstance(exp,expr._IntrinsicFunctionExpression):
    823828            assert(len(exp._args) == 1)
    824829
Note: See TracChangeset for help on using the changeset viewer.