
    wgA-              	       &   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ZIy1)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y)Optimizationz Abstract base class for rewriting optimization.

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

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

    Nc                      || _         || _        y N)cost_functionpriority)selfr"   r#   s      \/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/codegen/rewriting.py__init__zOptimization.__init__@   s    *    c                 0    t        || j                        S )N)key)minr"   )r$   argss     r%   cheapestzOptimization.cheapestD   s    4T//00r'   )N   )__name__
__module____qualname____doc__r&   r,    r'   r%   r   r   4   s    
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                 @    t        |   di | || _        || _        y )Nr2   )superr&   queryvalue)r$   r7   r8   kwargs	__class__s       r%   r&   zReplaceOptim.__init__h   s!    "6"

r'   c                 N    |j                  | j                  | j                        S r!   )replacer7   r8   )r$   exprs     r%   __call__zReplaceOptim.__call__m   s    ||DJJ

33r'   )r.   r/   r0   r1   r&   r>   __classcell__r:   s   @r%   r4   r4   H   s    >
4r'   r4   c                     t        |d d      D ]+  } ||       }|j                  |} |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   sN    * +CTR 2;&D>>$1D2 Kr'   c                 <    | j                   xr | j                  dk(  S )N   )is_Powbaseps    r%   rD   rD      s    ahh&166Q; r'   c                 ,    t        | j                        S r!   )r   r   rO   s    r%   rD   rD      s    d155k r'   dc                     | j                   S r!   )is_Dummyxs    r%   rD   rD      s
    QZZ r'   )
propertiesuc                 :    | j                    xr | j                   S r!   )	is_numberis_AddrU   s    r%   rD   rD      s    _%EQXX r'   vwnc                     | j                   S r!   rZ   rU   s    r%   rD   rD      s
    Q[[ r'   rL   c                 &    | j                  d       S )Nc                     | j                   xr | j                  j                  xs2 t        | t        t
        f      xr | j                  d   j                   S Nr   )rM   r   is_negative
isinstancer   r   r+   rZ   es    r%   rD   z<lambda>.<locals>.<lambda>   sG    	&QUU&& 	Dq3+&Bqvvay/B/B+B r'   )count)r=   s    r%   rD   rD      s    SWS]S]ET r'   r"   c                     t        | t              xrk | j                  d   j                  xrP t	        | j                  d   j                        dk(  xr) t        d | j                  d   j                  D              S )Nr   rL   c              3   <   K   | ]  }t        |t                y wr!   )re   r   ).0ts     r%   	<genexpr>z<lambda>.<locals>.<genexpr>   s     Baz!S)Bs   )re   r   r+   r[   lenallls    r%   rD   rD      sh    z!S! C66!9##Cqvvay~~&!+C B166!9>>BB r'   c                 $   t        | j                  d   j                  D cg c]  }|j                  d    c} t        t        t	        | j                  d   j                  D cg c]  }|j                  d    c}             z   S c c}w c c}w rc   )r	   r+   r   r   r
   )rr   rg   s     r%   rD   rD      sj    0AaffQi01c#166!9>>:aq	:;<=	> 0:s   B$B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)


    c                 z    dt         |   d | j                  fd       || _        | _        || _        y )N
   c                     | j                   S r!   )r[   rf   s    r%   rD   z,FuncMinusOneOptim.__init__.<locals>.<lambda>   s
    188 r'   c                 N    | j                         | j                        z  z
  S r!   )	count_opsrh   )r=   func_m_1weights    r%   rD   z,FuncMinusOneOptim.__init__.<locals>.<lambda>   s"    DNN4DvdjjYaNbGb4b r'   ri   )r6   r&   replace_in_Addfuncr{   opportunistic)r$   r~   r{   r   r|   r:   s     ` @r%   r&   zFuncMinusOneOptim.__init__   s?    +T-@-@'b 	 	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
    cmm r'   Tbinaryc                 :    | j                  j                        S r!   )hasr~   r   r$   s    r%   rD   z4FuncMinusOneOptim._group_Add_terms.<locals>.<lambda>   s    377499;M r'   )r   r+   sum)r$   addnumbersnon_numnumsumterms_with_funcothers   `      r%   _group_Add_termsz"FuncMinusOneOptim._group_Add_terms   sF    *CDQW!%g/MVZ![--r'   c                      j                  |      \  }}}|dk(  r|S g g }}|D ]  }|j                  rHt        |j                   fdd      \  }}	t	        |      dk(  rt	        |	      dk(  r|d   |	d   }	}n1d}	n.|j
                   j
                  k(  r|t        j                  }	}nd}	|	|	j                  r{t        |	      t        |       k(  rc j                  rt        |	|z         t        |      k  }
n|	|z   dk(  }
|
r2||	z  }|j                  |	  j                  j                   z         |j                  |       "  |j
                  |g||| S )z1 passed as second argument to Basic.replace(...) r   c                 6    | j                   j                   k(  S r!   )r~   r   s    r%   rD   z2FuncMinusOneOptim.replace_in_Add.<locals>.<lambda>   s    sxx499?T r'   Tr   r-   N)r   is_Mulr   r+   ro   r~   r   OnerZ   r   r   absappendr{   )r$   rg   r   r   other_non_num_termssubstituted	untouched	with_funcr~   coeffdo_substitutes   `          r%   r}   z FuncMinusOneOptim.replace_in_Add   sZ   7;7L7LQ7O4!4Q;H!#RY( 	(I"9>>3T]abet9>c%jAo"&q'58%D E499,'e U__ef9U%%$'f$5F$CM$)&LA$5M eOF&&u]T]]DII-F'FGY'-	(0 qvvfM{MYM9LMMr'   c                     t         |   |      }t         |   |j                               }| j                  ||      S r!   )r6   r>   factorr,   )r$   r=   alt1alt2r:   s       r%   r>   zFuncMinusOneOptim.__call__  s8    w%w.}}T4((r'   )T)	r.   r/   r0   r1   r&   r   r}   r>   r?   r@   s   @r%   ru   ru      s$    $L+.N@) )r'   ru   c                 "    t        | t              S r!   )re   r   rf   s    r%   rD   rD     s    jC  r'   c                     t        | j                  t        d             j                  t        t        dz         t	        t                    S )Nc                 4    t        | j                               S r!   )r   r   r   s    r%   rD   z<lambda>.<locals>.<lambda>  s    SZZ\* r'   r-   )r   r<   r   _ur   rq   s    r%   rD   rD     s7    j* ws2a4y%)$ r'   c                     | j                   S r!   )	is_symbol)bs    r%   rD   rD     s
     r'   )base_reqc                (     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                     | j                   xrD  | j                        xr0 | j                  j                  xr t	        | j                        k  S r!   )rM   rN   r   
is_Integerr   )rg   r   limits    r%   rD   z0create_expand_pow_optimization.<locals>.<lambda>B  s;    !((\x/\AEE4D4D\QUUW\I\ r'   c                     | j                   dkD  r-t        t        | j                  g| j                   z  ddi      S 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  s`    HIPQ	OC166(AEE6/CUCD ocQVVHaeeVOEuEFF r'   )r4   )r   r   s   ``r%   create_expand_pow_optimizationr     s    F \	
 r'   c                 @   | j                   rt        | j                        dk(  rz| j                  \  }}|j                  r_|j                  d   dk(  rM|j
                  }t        |t              r1t        t        t        j                  |j
                                    S y)NrL   r-   F)	is_MatMulro   r+   
is_Inverseshaper   re   r   boolr   r   fullrankr=   leftrightinv_args       r%   _matinv_predicater   I  sn    ~~#dii.A-iie??u{{1~2hhG'<0C

488 4566r'   c                 P    | j                   \  }}|j                  }t        ||      S r!   )r+   r   r   r   s       r%   _matinv_transformr   T  s%    ))KD%hhG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_optru   	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 = ? E E $ = = 2 +   ; 2  ; *1 1(&4< &4R< & 
#/01	#EFG	#Y	#Y	#012GBJR	 2JrM2d2b5k>	 	"	3r7
3q6)2d2h; G  SVDH_c"g6#D	 X) X)v c5)	c5)	c5)	 %	 7L (V	' +->?
 SRR19R3DEc#a*SBZ"78*R:LSQRV:ST HhF
]N<<yH9%r'   