o
    oh/                     @   sb   d dl Z d dlmZ d dlmZmZ d dlmZ d dlm	Z	 	 G dd deZ
G dd	 d	eZdS )
    N)Interval)is_increasingis_decreasing)Optimization)UndefinedFunctionc                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
	SumApproxa8  
    Approximates sum by neglecting small terms.

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

    If terms are expressions which can be determined to be monotonic, then
    bounds for those expressions are added.

    Parameters
    ==========

    bounds : dict
        Mapping expressions to length 2 tuple of bounds (low, high).
    reltol : number
        Threshold for when to ignore a term. Taken relative to the largest
        lower bound among bounds.

    Examples
    ========

    >>> from sympy import exp
    >>> from sympy.abc import x, y, z
    >>> from sympy.codegen.rewriting import optimize
    >>> from sympy.codegen.approximations import SumApprox
    >>> bounds = {x: (-1, 1), y: (1000, 2000), z: (-10, 3)}
    >>> sum_approx3 = SumApprox(bounds, reltol=1e-3)
    >>> sum_approx2 = SumApprox(bounds, reltol=1e-2)
    >>> sum_approx1 = SumApprox(bounds, reltol=1e-1)
    >>> expr = 3*(x + y + exp(z))
    >>> optimize(expr, [sum_approx3])
    3*(x + y + exp(z))
    >>> optimize(expr, [sum_approx2])
    3*y + 3*exp(z)
    >>> optimize(expr, [sum_approx1])
    3*y

    c                    s"   t  jdi | || _|| _d S )N )super__init__boundsreltol)selfr   r   kwargs	__class__r   p/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/codegen/approximations.pyr
   6   s   
zSumApprox.__init__c                       |   j fddS )Nc                    
     | S Nvalueargr   r   r   <lambda><      
 z$SumApprox.__call__.<locals>.<lambda>factorreplacequeryr   exprr   r   r   __call__;      zSumApprox.__call__c                 C   s   |j S r   )is_Addr    r   r   r   r   >   s   zSumApprox.queryc           
         s  |j D ]j}|js| jv st|jdkrq|j\}| jvrqt j|  }t|||rH|| j| d i|| j| d if j|< qt|||rj|| j| d i|| j| d if j|< q|  S t	 fdd|j D r͇ fdd|j D }d}|D ]\}}|d  kr|krn nqt
|tt|t|}qg }	t|j |D ]\}\}}t
t|t|| j kr|	| q|j|	 S |S )N   r   c                 3   s     | ]}|j p| jv V  qd S r   	is_numberr   .0termr   r   r   	<genexpr>V   s    z"SumApprox.value.<locals>.<genexpr>c                    s$   g | ]}|j r||fn j| qS r   r&   r(   r   r   r   
<listcomp>W   s   $ z#SumApprox.value.<locals>.<listcomp>)argsr'   r   lenfree_symbolsr   r   subsr   allmaxminabszipr   appendfunc)
r   addr*   fsintrvlr   largest_abs_guaranteelohi	new_termsr   r   r   r   A   s@   



zSumApprox.value	__name__
__module____qualname____doc__r
   r"   r   r   __classcell__r   r   r   r   r      s    'r   c                       s:   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Z  ZS )SeriesApproxa    Approximates functions by expanding them as a series.

    Parameters
    ==========

    bounds : dict
        Mapping expressions to length 2 tuple of bounds (low, high).
    reltol : number
        Threshold for when to ignore a term. Taken relative to the largest
        lower bound among bounds.
    max_order : int
        Largest order to include in series expansion
    n_point_checks : int (even)
        The validity of an expansion (with respect to reltol) is checked at
        discrete points (linearly spaced over the bounds of the variable). The
        number of points used in this numerical check is given by this number.

    Examples
    ========

    >>> from sympy import sin, pi
    >>> from sympy.abc import x, y
    >>> from sympy.codegen.rewriting import optimize
    >>> from sympy.codegen.approximations import SeriesApprox
    >>> bounds = {x: (-.1, .1), y: (pi-1, pi+1)}
    >>> series_approx2 = SeriesApprox(bounds, reltol=1e-2)
    >>> series_approx3 = SeriesApprox(bounds, reltol=1e-3)
    >>> series_approx8 = SeriesApprox(bounds, reltol=1e-8)
    >>> expr = sin(x)*sin(y)
    >>> optimize(expr, [series_approx2])
    x*(-y + (y - pi)**3/6 + pi)
    >>> optimize(expr, [series_approx3])
    (-x**3/6 + x)*sin(y)
    >>> optimize(expr, [series_approx8])
    sin(x)*sin(y)

       c                    sX   t  jdi | || _|| _|| _|d dkrtd|| _tt	| j | _
d S )N   r%   z7Checking the solution at expansion point is not helpfulr   )r	   r
   r   r   	max_order
ValueErrorn_point_checksmathceillog10_prec)r   r   r   rH   rJ   r   r   r   r   r
      s   zSeriesApprox.__init__c                    r   )Nc                    r   r   r   r   r   r   r   r      r   z'SeriesApprox.__call__.<locals>.<lambda>r   r    r   r   r   r"      r#   zSeriesApprox.__call__c                 C   s    |j ot|t ot|jdkS )Nr%   )is_Function
isinstancer   r.   r-   r    r   r   r   r      s   zSeriesApprox.queryc                 C   s   |j }t|dkr|S |\}|| jvr|S | j| \}}|| d }d }t| jd ddD ]I}|j|||d }	d}
t| jD ]0}||||  | jd   }|	||i}|||i}t	d||  
| j| jkrpd}
 nq@|
rv|	}q- |d u r}|S |S )Nr%   rG   r   )x0nTF)r/   r.   r   rangerH   seriesremoveOrJ   xreplacer4   evalfrN   r   )r   fexprr/   symbr<   r=   rR   cheapestrS   fserin_okidxxvalrefr   r   r   r      s4   
zSeriesApprox.value)rF   rF   r?   r   r   r   r   rE   g   s    %
rE   )rK   sympy.sets.setsr   sympy.calculus.singularitiesr   r   sympy.codegen.rewritingr   sympy.core.functionr   r   rE   r   r   r   r   <module>   s    Y