
    gA-              	          d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZmZ ddlmZmZmZ dd	l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dlm Z  ddl!m"Z"m#Z# ddl$m%Z%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,  G d d          Z- G d de-          Z.d Z/ e.d d           Z0 edd g          Z1 edd g          Z2 ed          Z3 ed           Z4 ed!d" g          Z5 e. ee4          e4z   ee4                    Z6 e. ee5e4z            e4z  e5 ee5e4z            z            Z7e6e7fZ8 e.e3 ee4          z   ed#          z  e3 ee4          z  d$ %          Z9 e. ed#           ee4          z   ee4                    Z: e.d& d'           Z; G d( d)e.          Z< e<e
e          Z= e<ee%          Z> e<e e&          Z? e.d* d+           Z@d, d-d.ZAd/ ZBd0 ZC e.eBeC          ZD e. e e
e3           e
e4          z              e"e3e4                    ZE e. e e d#e3           e d#e4          z              e#e3e4           ed#          z            ZFe=e@e0e9e:fZGeGeEeFfz   e8z   ZHe>e?fZId1S )2a  
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) - 1 - exp(-33), optims_c99)
    expm1(2*x) - exp(-33)
    >>> 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``


    )
expand_log)S)Wild)sign)explog)MaxMin)cossinsinc)Qask)log1plog2exp2expm1)MatrixSolve)UnevaluatedExpr)Pow)	logaddexp
logaddexp2)cosm1powm1)Mul)MatrixSymbol)siftc                        e Zd ZdZddZd ZdS )Optimizationz Abstract base class for rewriting optimization.

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

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

    N   c                 "    || _         || _        d S N)cost_functionpriority)selfr#   r$   s      S/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/codegen/rewriting.py__init__zOptimization.__init__@   s    *    c                 .    t          || j                  S )N)key)minr#   )r%   argss     r&   cheapestzOptimization.cheapestD   s    4T/0000r(   )Nr    )__name__
__module____qualname____doc__r'   r-    r(   r&   r   r   4   sA        
 
   1 1 1 1 1r(   r   c                   (     e Zd ZdZ fdZd Z xZS )ReplaceOptima   Rewriting optimization calling replace on expressions.

    Explanation
    ===========

    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
    >>> 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                 V     t                      j        di | || _        || _        d S )Nr2   )superr'   queryvalue)r%   r7   r8   kwargs	__class__s       r&   r'   zReplaceOptim.__init__h   s2    ""6"""



r(   c                 B    |                     | j        | j                  S r"   )replacer7   r8   )r%   exprs     r&   __call__zReplaceOptim.__call__m   s    ||DJ
333r(   )r.   r/   r0   r1   r'   r>   __classcell__r:   s   @r&   r4   r4   H   sQ         >    
4 4 4 4 4 4 4r(   r4   c                     t          |d d          D ]-} ||           }|j        |} |                    | |          } .| S )a   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)

    c                     | j         S r"   )r$   )opts    r&   <lambda>zoptimize.<locals>.<lambda>   s    s| r(   T)r*   reverse)sortedr#   r-   )r=   optimizationsoptimnew_exprs       r&   optimizerJ   q   s]    * +C+CTRRR 2 25;;&DD>>$11DDKr(   c                 &    | j         o
| j        dk    S )N   )is_Powbaseps    r&   rD   rD      s    ah&16Q; r(   c                 *    t          | j                  S r"   )r   r   rO   s    r&   rD   rD      s    d15kk r(   dc                     | j         S r"   )is_Dummyxs    r&   rD   rD      s    QZ r(   )
propertiesuc                 "    | j          o| j         S r"   )	is_numberis_AddrU   s    r&   rD   rD      s    _%EQX r(   vwnc                     | j         S r"   rZ   rU   s    r&   rD   rD      s    Q[ r(   rL   c                 .    |                      d           S )Nc                     | j         r| j        j        p.t          | t          t
          f          o| j        d         j         S )Nr   )rM   r   is_negative
isinstancer   r   r,   rZ   es    r&   rD   z<lambda>.<locals>.<lambda>   s>    	&QU& 	Dq3+&&Bqvay/B+B r(   )count)r=   s    r&   rD   rD      s%    SWS]S]E ET T r(   r#   c                     t          | t                    o]| j        d         j        oKt	          | j        d         j                  dk    o(t          d | j        d         j        D                       S )Nr   rL   c              3   @   K   | ]}t          |t                    V  d S r"   )rd   r   ).0ts     r&   	<genexpr>z<lambda>.<locals>.<genexpr>   s,      BBaz!S))BBBBBBr(   )rd   r   r,   r[   lenallls    r&   rD   rD      sm    z!S!! C6!9#Cqvay~&&!+C BB16!9>BBBBB r(   c           
          t          d | j        d         j        D              t          t          t	          d | j        d         j        D                                  z   S )Nc                 (    g | ]}|j         d          S r   r,   rk   rf   s     r&   
<listcomp>z<lambda>.<locals>.<listcomp>   s    000AafQi000r(   r   c                 (    g | ]}|j         d          S rt   ru   rv   s     r&   rw   z<lambda>.<locals>.<listcomp>   s    :::aq	:::r(   )r	   r,   r   r   r
   rp   s    r&   rD   rD      sZ    000001c#::16!9>:::;<<==	> r(   c                   :     e Zd ZdZd fd	Zd Zd Z fdZ xZS )FuncMinusOneOptima  Specialization of ReplaceOptim for functions evaluating "f(x) - 1".

    Explanation
    ===========

    Numerical functions which go toward one as x go toward zero is often best
    implemented by a dedicated function in order to avoid catastrophic
    cancellation. One such example is ``expm1(x)`` in the C standard library
    which evaluates ``exp(x) - 1``. Such functions preserves many more
    significant digits when its argument is much smaller than one, compared
    to subtracting one afterwards.

    Parameters
    ==========

    func :
        The function which is subtracted by one.
    func_m_1 :
        The specialized function evaluating ``func(x) - 1``.
    opportunistic : bool
        When ``True``, apply the transformation as long as the magnitude of the
        remaining number terms decreases. When ``False``, only apply the
        transformation if it completely eliminates the number term.

    Examples
    ========

    >>> from sympy import symbols, exp
    >>> from sympy.codegen.rewriting import FuncMinusOneOptim
    >>> from sympy.codegen.cfunctions import expm1
    >>> x, y = symbols('x y')
    >>> expm1_opt = FuncMinusOneOptim(exp, expm1)
    >>> expm1_opt(exp(x) + 2*exp(5*y) - 3)
    expm1(x) + 2*expm1(5*y)


    Tc                     dt                                          d | j        fd           || _        | _        || _        d S )N
   c                     | j         S r"   )r[   re   s    r&   rD   z,FuncMinusOneOptim.__init__.<locals>.<lambda>   s    18 r(   c                 ^    |                                  |                               z  z
  S r"   )	count_opsrg   )r=   func_m_1weights    r&   rD   z,FuncMinusOneOptim.__init__.<locals>.<lambda>   s(    DNN4D4DvdjjYaNbNbGb4b r(   rh   )r6   r'   replace_in_Addfuncr   opportunistic)r%   r   r   r   r   r:   s     ` @r&   r'   zFuncMinusOneOptim.__init__   sd    ++T-@'b'b'b'b'b 	 	d 	d 	d	 *r(   c                      t          |j        d d          \  }}t          |          }t          | fdd          \  }}|||fS )Nc                     | j         S r"   r`   args    r&   rD   z4FuncMinusOneOptim._group_Add_terms.<locals>.<lambda>   s    cm r(   Tbinaryc                 8    |                      j                  S r"   )hasr   r   r%   s    r&   rD   z4FuncMinusOneOptim._group_Add_terms.<locals>.<lambda>   s    37749;M;M r(   )r   r,   sum)r%   addnumbersnon_numnumsumterms_with_funcothers   `      r&   _group_Add_termsz"FuncMinusOneOptim._group_Add_terms   s^    *C*CDQQQW!%g/M/M/M/MVZ![![![--r(   c                                           |          \  }}}|dk    r|S g g }}|D ]#}|j        rWt          |j         fdd          \  }}	t	          |          dk    r$t	          |	          dk    r|d         |	d         }	}n$d}	n!|j         j        k    r|t          j        }	}nd}	|	|	j        rt          |	          t          |           k    rb j
        r$t          |	|z             t          |          k     }
n	|	|z   dk    }
|
r,||	z  }|                    |	  j        |j         z             |                    |           % |j        |g|||R  S )z1 passed as second argument to Basic.replace(...) r   c                 $    | j         j         k    S r"   )r   r   s    r&   rD   z2FuncMinusOneOptim.replace_in_Add.<locals>.<lambda>   s    sx49?T r(   Tr   r    N)r   is_Mulr   r,   rn   r   r   OnerZ   r   r   absappendr   )r%   rf   r   r   other_non_num_termssubstituted	untouched	with_funcr   coeffdo_substitutes   `          r&   r   z FuncMinusOneOptim.replace_in_Add   s   7;7L7LQ7O7O4!4Q;;H!#RY( 	( 	(I 	"9>3T3T3T3T]abbbet99>>c%jjAoo"&q'58%DD EE49,,'e U_ ef9U9U% 6$'f$5$5F$CMM$)&LA$5M  eOF&&u]T]DI-F'FGGGY''''qvfM{MYM9LMMMMr(   c                     t                                          |          }t                                          |                                          }|                     ||          S r"   )r6   r>   factorr-   )r%   r=   alt1alt2r:   s       r&   r>   zFuncMinusOneOptim.__call__  sM    ww%%ww..}}T4(((r(   )T)	r.   r/   r0   r1   r'   r   r   r>   r?   r@   s   @r&   rz   rz      s        $ $L+ + + + + +. . .N N N@) ) ) ) ) ) ) ) )r(   rz   c                 ,    t          | t                    S r"   )rd   r   re   s    r&   rD   rD     s    jC   r(   c                     t          |                     t          d                                         t          t          dz             t	          t                              S )Nc                 D    t          |                                           S r"   )r   r   r   s    r&   rD   z<lambda>.<locals>.<lambda>  s    SZZ\\** r(   r    )r   r<   r   _ur   rp   s    r&   rD   rD     sK    j**   ws2a4yy%))$$ r(   c                     | j         S r"   )	is_symbol)bs    r&   rD   rD     s     r(   )base_reqc                0     t           fdd           S )a   Creates an instance of :class:`ReplaceOptim` for expanding ``Pow``.

    Explanation
    ===========

    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.
    base_req : function returning bool
         Requirement on base for expansion to happen, default is to return
         the ``is_symbol`` attribute of the base.

    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 + sin(x)**3 + x*x*x
    >>> opt2 = create_expand_pow_optimization(3, base_req=lambda b: not b.is_Function)
    >>> opt2((x+1)**2 + sin(x)**2)
    sin(x)**2 + (x + 1)*(x + 1)

    c                 z    | j         o3 | j                  o#| j        j        ot	          | j                  k    S r"   )rM   rN   r   
is_Integerr   )rf   r   limits    r&   rD   z0create_expand_pow_optimization.<locals>.<lambda>B  s7    !(\xx//\AE4D\QUW\I\ r(   c                     | j         dk    r(t          t          | j        g| j         
 z  ddi          n*dt          t          | j        g| j          z  ddi          z  S )Nr   evaluateFr    )r   r   r   rN   rO   s    r&   rD   z0create_expand_pow_optimization.<locals>.<lambda>C  sb    HIPQ		OC16(AE6/CUCCDDDocQVHaeVOEuEEFFF r(   )r4   )r   r   s   ``r&   create_expand_pow_optimizationr     s2    F \\\\\	
 	
  r(   c                 &   | j         rt          | j                  dk    rq| j        \  }}|j        r`|j        d         dk    rO|j        }t          |t                    r3t          t          t          j        |j                                      S dS )NrL   r    F)	is_MatMulrn   r,   
is_Inverseshaper   rd   r   boolr   r   fullrankr=   leftrightinv_args       r&   _matinv_predicater   I  s    ~ 7#di..A--ie? 	7u{1~22hG'<00 7C
48 4 4556665r(   c                 D    | j         \  }}|j        }t          ||          S r"   )r,   r   r   r   s       r&   _matinv_transformr   T  s$    )KD%hGw&&&r(   N)Jr1   sympy.core.functionr   sympy.core.singletonr   sympy.core.symbolr   $sympy.functions.elementary.complexesr   &sympy.functions.elementary.exponentialr   r   (sympy.functions.elementary.miscellaneousr	   r
   (sympy.functions.elementary.trigonometricr   r   r   sympy.assumptionsr   r   sympy.codegen.cfunctionsr   r   r   r   sympy.codegen.matrix_nodesr   sympy.core.exprr   sympy.core.powerr   sympy.codegen.numpy_nodesr   r   sympy.codegen.scipy_nodesr   r   sympy.core.mulr   "sympy.matrices.expressions.matexprr   sympy.utilities.iterablesr   r   r4   rJ   exp2_opt_dr   _v_w_n	sinc_opt1	sinc_opt2	sinc_optslog2_optlog2const_optlogsumexp_2terms_optrz   	expm1_opt	cosm1_opt	powm1_opt	log1p_optr   r   r   
matinv_optlogaddexp_optlogaddexp2_opt
optims_c99optims_numpyoptims_scipyr2   r(   r&   <module>r      s   @ + * * * * * " " " " " " " " " " " " 5 5 5 5 5 5 = = = = = = = = ? ? ? ? ? ? ? ? E E E E E E E E E E $ $ $ $ $ $ $ $ = = = = = = = = = = = = 2 2 2 2 2 2 + + + + + +             ; ; ; ; ; ; ; ; 2 2 2 2 2 2 2 2       ; ; ; ; ; ; * * * * * *1 1 1 1 1 1 1 1(&4 &4 &4 &4 &4< &4 &4 &4R  < <&&  
T#//0111	T#EEFGGG	T#YY	T#YY	T#001222LCGGBJR 	 LC2JJrM2dd2b5kk> 	 	"	<33r77
33q66)2dd2hh; G G    SSVVDDHH_cc"gg66#|D D 	 	 X) X) X) X) X) X) X) X)v c5))	c5))	c5))	L  % % 	 7L6K ( ( ( ( (V	 	 	' ' ' \+->??
 SSRR1199R3D3DEEcc##a**SSBZZ"788**R:L:LSSQRVV:STT HhF
]N<<yH9%r(   