σ
~9­\c           @` s  d  Z  d d l m Z m Z m Z d d l m Z d d l m Z m	 Z	 m
 Z
 m Z m Z m Z m Z d d l m Z m Z m Z m Z d d l m Z d d l m Z d e f d	     YZ d
 e f d     YZ d   Z e d   d    Z e d d d   g Z e d d d   g Z e d  Z e d  Z  e e e e   e d  e e e   d d   Z! e e d  e e   e e    Z" e d   d    Z# d   Z$ d   Z% e d   e%  Z& e d   d    Z' d    Z( e& e' e e! e" f Z) d! S("   sδ  
Classes and functions useful for rewriting expressions for optimized code
generation. Some languages (or standards thereof), e.g. C99, offer specialized
math functions for better performance and/or precision.

Using the ``optimize`` function in this module, together with a collection of
rules (represented as instances of ``Optimization``), one can rewrite the
expressions for this purpose::

    >>> from sympy import Symbol, exp, log
    >>> from sympy.codegen.rewriting import optimize, optims_c99
    >>> x = Symbol('x')
    >>> optimize(3*exp(2*x) - 3, optims_c99)
    3*expm1(2*x)
    >>> optimize(exp(2*x) - 3, optims_c99)
    exp(2*x) - 3
    >>> optimize(log(3*x + 3), optims_c99)
    log1p(x) + log(3)
    >>> optimize(log(2*x + 3), optims_c99)
    log(2*x + 3)

The ``optims_c99`` imported above is tuple containing the following instances
(which may be imported from ``sympy.codegen.rewriting``):

- ``expm1_opt``
- ``log1p_opt``
- ``exp2_opt``
- ``log2_opt``
- ``log2const_opt``


i    (   t   absolute_importt   divisiont   print_function(   t   chain(   t   logt   expt   Maxt   Mint   Wildt
   expand_logt   Dummy(   t   log1pt   log2t   exp2t   expm1(   t   Mul(   t   siftt   Optimizationc           B` s   e  Z d  Z d d d  Z RS(   sν    Abstract base class for rewriting optimization.

    Subclasses should implement ``__call__`` taking an expression
    as argument.

    Parameters
    ==========
    cost_function : callable returning number
    priority : number

    i   c         C` s   | |  _  | |  _ d  S(   N(   t   cost_functiont   priority(   t   selfR   R   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   __init__6   s    	N(   t   __name__t
   __module__t   __doc__t   NoneR   (    (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR   *   s   t   ReplaceOptimc           B` s    e  Z d  Z d   Z d   Z RS(   s¦   Rewriting optimization calling replace on expressions.

    The instance can be used as a function on expressions for which
    it will apply the ``replace`` method (see
    :meth:`sympy.core.basic.Basic.replace`).

    Parameters
    ==========
    query : first argument passed to replace
    value : second argument passed to replace

    Examples
    ========

    >>> from sympy import Symbol, Pow
    >>> from sympy.codegen.rewriting import ReplaceOptim
    >>> from sympy.codegen.cfunctions import exp2
    >>> x = Symbol('x')
    >>> exp2_opt = ReplaceOptim(lambda p: p.is_Pow and p.base == 2,
    ...     lambda p: exp2(p.exp))
    >>> exp2_opt(2**x)
    exp2(x)

    c         K` s,   t  t |   j |   | |  _ | |  _ d  S(   N(   t   superR   R   t   queryt   value(   R   R   R   t   kwargs(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR   U   s    	c         C` s   | j  |  j |  j  S(   N(   t   replaceR   R   (   R   t   expr(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   __call__Z   s    (   R   R   R   R   R!   (    (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR   ;   s   	c         ` s   x t  | d d   d t D]c     |   }   j d k rF | }  q t   f d   |  | f  \ } } | | k r | }  q q W|  S(   sλ   Apply optimizations to an expression.

    Parameters
    ==========

    expr : expression
    optimizations : iterable of ``Optimization`` instances
        The optimizations will be sorted with respect to ``priority`` (highest first).

    Examples
    ========

    >>> from sympy import log, Symbol
    >>> from sympy.codegen.rewriting import optims_c99, optimize
    >>> x = Symbol('x')
    >>> optimize(log(x+3)/log(2) + log(x**2 + 1), optims_c99)
    log1p(x**2) + log2(x + 3)

    t   keyc         S` s   |  j  S(   N(   R   (   t   opt(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   <lambda>s   t    t   reversec         ` s     j  |   S(   N(   R   (   t   x(   t   optim(    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   x   R%   N(   t   sortedt   TrueR   R   t   map(   R    t   optimizationst   new_exprt   beforet   after(    (   R(   s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   optimize^   s    "	$c         C` s   |  j  o |  j d k S(   Ni   (   t   is_Powt   base(   t   p(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      R%   c         C` s   t  |  j  S(   N(   R   R   (   R3   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      R%   t   dt
   propertiesc         C` s   |  j  S(   N(   t   is_Dummy(   R'   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      R%   t   uc         C` s   |  j  o |  j S(   N(   t	   is_numbert   is_Add(   R'   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      R%   t   vt   wi   R   c         C` s   |  j  d    S(   Nc         S` s9   |  j  r |  j j p8 t |  t t f  o8 |  j d j S(   Ni    (   R1   R   t   is_negativet
   isinstanceR   R   t   argsR8   (   t   e(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      s    (   t   count(   R    (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      s   c         C` sY   t  |  t  oX |  j d j oX t |  j d j  d k oX t d   |  j d j D  S(   Ni    i   c         s` s   |  ] } t  | t  Vq d  S(   N(   R=   R   (   t   .0t   t(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pys	   <genexpr>   s    (   R=   R   R>   R9   t   lent   all(   t   l(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      s   c         C` sh   t  g  |  j d j D] } | j d ^ q   t t t g  |  j d j D] } | j d ^ qG     S(   Ni    (   R   R>   R   R   R   (   RE   R?   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      s    -c         ` si   |  j  t d   d t \ } } | j   } d   | j   D   | j  t d   f d    j    S(   Nc         S` s   t    S(   N(   R
   (   t   arg(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$      R%   R+   c         S` s   i  |  ] \ } } | |  q S(    (    (   RA   t   kR:   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pys
   <dictcomp>‘   s   	 i   c         ` s   t    |  j d  S(   Ni    (   R   R>   (   R4   (   t   new_old(    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   ’   R%   (   R   R   R*   t   factort   itemst   _dt   xreplace(   R    t	   protectedt   old_newt   factored(    (   RH   s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt
   _try_expm1   s    !c         C` sπ   t  |  j d   d t \ } } t  | d   d t \ } } t |  } g  t } } xi | D]a } | r{ | j |  q_ | | }	 t |	  }
 |	 |
 k r­ | j |  q_ t } | j |
  q_ W| sΪ | j |  n  |  j t | |    S(   Nc         S` s   |  j  S(   N(   R8   (   RF   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   ¦   R%   t   binaryc         S` s   |  j  t  S(   N(   t   hasR   (   RF   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   §   R%   (	   R   R>   R*   t   sumt   Falset   appendRP   t   funcR   (   R?   t   numberst   non_numt   non_num_expt   non_num_othert   numsumt   new_exp_termst   donet   exp_termt
   looking_att   attempt(    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   _expm1_value₯   s"    !
c         C` s   |  j  S(   N(   R9   (   R?   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   »   R%   c         C` s   t  |  t  S(   N(   R=   R   (   R?   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   Ώ   R%   c         C` s5   t  |  j t d     j t t d  t t   S(   Nc         S` s   t  |  j    S(   N(   R   RI   (   RF   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   Α   R%   i   (   R	   R   R   t   _uR   (   RE   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   ΐ   s   	c         ` s   t    f d   d    S(   sΈ   Creates an instance of :class:`ReplaceOptim` for expanding ``Pow``.

    The requirements for expansions are that the base needs to be a symbol
    and the exponent needs to be an integer (and be less than or equal to
    ``limit``).

    Parameters
    ==========

    limit : int
         The highest power which is expanded into multiplication.

    Examples
    ========

    >>> from sympy import Symbol, sin
    >>> from sympy.codegen.rewriting import create_expand_pow_optimization
    >>> x = Symbol('x')
    >>> expand_opt = create_expand_pow_optimization(3)
    >>> expand_opt(x**5 + x**3)
    x**5 + x*x*x
    >>> expand_opt(x**5 + x**3 + sin(x)**3)
    x**5 + x*x*x + sin(x)**3

    c         ` s:   |  j  o9 |  j j o9 |  j j o9 |  j j o9 |  j   k S(   N(   R1   R2   t	   is_symbolR   t
   is_integert   is_nonnegative(   R?   (   t   limit(    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   ΰ   R%   c         S` s   t  d t |  j g |  j  S(   Nt   evaluate(   R   RT   R2   R   (   R3   (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyR$   α   R%   (   R   (   Rf   (    (   Rf   s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   create_expand_pow_optimizationΕ   s    N(*   R   t
   __future__R    R   R   t	   itertoolsR   t   sympyR   R   R   R   R   R	   R
   t   sympy.codegen.cfunctionsR   R   R   R   t   sympy.core.mulR   t   sympy.utilities.iterablesR   t   objectR   R   R0   t   exp2_optRK   Rb   t   _vt   _wt   log2_optt   log2const_optt   logsumexp_2terms_optRP   Ra   t	   expm1_optt	   log1p_optRh   t
   optims_c99(    (    (    s6   lib/python2.7/site-packages/sympy/codegen/rewriting.pyt   <module>!   s:   4"#	 6%			 