U
    š»|eY³  ã                   @  sj  d dl mZ d dlmZmZmZmZmZmZ d dl	Z	d dl
Zd dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZ d dlmZ dd	d
dddddddddgZd¯dd„Zd°dd„ZG dd„ deƒZerêd dlmZ G dd„ deƒZneZdddœdd„Zed d!„ ƒZe ƒ e_!d±d$d„Z"d²d&d'„Z#d³d,d	„Z$d-d.„ Z%d´d/d„Z&dµd0d„Z'd1d2„ Z(d¶d4d„Z)d·d5d„Z*d¸d6d„Z+d7d8„ Z,d9d:„ Z-d;d<„ Z.d¹d?d
„Z/d+d@d+d+gddAfd+dBd+dCd+gddDfdBdEd+dBdBd+gdFdGfd@dHdIdJdAdJdIgdKdLfd#dMdNdOd)d)dOdNgdPdQfd+dRdSdTdUdVdUdTdSgdWdXfdIdYdZd[d\d]d]d\d[dZgd^d_fdCd`dadbdcdddedddcdbdag	dfdgfdhdidjdkdldmdndndmdldkdjg
dodpfd#dqdrdsdtdudvdwdvdudtdsdrgdxdyfdzd{d|d}d~dd€d�d�d€dd~d}d|gd‚dƒfd+d„d…d†d‡dˆd‰dŠd‹dŠd‰dˆd‡d†d…gdŒd�fdŽd�d�d‘d’d“d”d•d–d–d•d”d“d’d‘d�gd—d˜fdId™dšd›dœd�dždŸd d¡d dŸdžd�dœd›dšgd¢d£fd¤œZ0dºd¥d„Z1d¦d§„ Z2ed¨d©dªgƒZ3d«dEdd%dd¬œd­d®„Z4dS )»é    )Úannotations)ÚTYPE_CHECKINGÚCallableÚDictÚTupleÚAnyÚcastN)Ú
namedtuple)Úroots_legendre)ÚgammalnÚ	logsumexp)Ú
_rng_spawnÚ
fixed_quadÚ
quadratureÚrombergÚrombÚ	trapezoidÚtrapzÚsimpsÚsimpsonÚcumulative_trapezoidÚcumtrapzÚnewton_cotesÚAccuracyWarningç      ð?éÿÿÿÿc                 C  s2   t tdƒrtj| |||d�S tj| |||d�S dS )a›  
    Integrate along the given axis using the composite trapezoidal rule.

    If `x` is provided, the integration happens in sequence along its
    elements - they are not sorted.

    Integrate `y` (`x`) along each 1d slice on the given axis, compute
    :math:`\int y(x) dx`.
    When `x` is specified, this integrates along the parametric curve,
    computing :math:`\int_t y(t) dt =
    \int_t y(t) \left.\frac{dx}{dt}\right|_{x=x(t)} dt`.

    Parameters
    ----------
    y : array_like
        Input array to integrate.
    x : array_like, optional
        The sample points corresponding to the `y` values. If `x` is None,
        the sample points are assumed to be evenly spaced `dx` apart. The
        default is None.
    dx : scalar, optional
        The spacing between sample points when `x` is None. The default is 1.
    axis : int, optional
        The axis along which to integrate.

    Returns
    -------
    trapezoid : float or ndarray
        Definite integral of `y` = n-dimensional array as approximated along
        a single axis by the trapezoidal rule. If `y` is a 1-dimensional array,
        then the result is a float. If `n` is greater than 1, then the result
        is an `n`-1 dimensional array.

    See Also
    --------
    cumulative_trapezoid, simpson, romb

    Notes
    -----
    Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
    will be taken from `y` array, by default x-axis distances between
    points will be 1.0, alternatively they can be provided with `x` array
    or with `dx` scalar.  Return value will be equal to combined area under
    the red lines.

    References
    ----------
    .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Trapezoidal_rule

    .. [2] Illustration image:
           https://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png

    Examples
    --------
    Use the trapezoidal rule on evenly spaced points:

    >>> import numpy as np
    >>> from scipy import integrate
    >>> integrate.trapezoid([1, 2, 3])
    4.0

    The spacing between sample points can be selected by either the
    ``x`` or ``dx`` arguments:

    >>> integrate.trapezoid([1, 2, 3], x=[4, 6, 8])
    8.0
    >>> integrate.trapezoid([1, 2, 3], dx=2)
    8.0

    Using a decreasing ``x`` corresponds to integrating in reverse:

    >>> integrate.trapezoid([1, 2, 3], x=[8, 6, 4])
    -8.0

    More generally ``x`` is used to integrate along a parametric curve. We can
    estimate the integral :math:`\int_0^1 x^2 = 1/3` using:

    >>> x = np.linspace(0, 1, num=50)
    >>> y = x**2
    >>> integrate.trapezoid(y, x)
    0.33340274885464394

    Or estimate the area of a circle, noting we repeat the sample which closes
    the curve:

    >>> theta = np.linspace(0, 2 * np.pi, num=1000, endpoint=True)
    >>> integrate.trapezoid(np.cos(theta), x=np.sin(theta))
    3.141571941375841

    ``trapezoid`` can be applied along a specified axis to do multiple
    computations in one call:

    >>> a = np.arange(6).reshape(2, 3)
    >>> a
    array([[0, 1, 2],
           [3, 4, 5]])
    >>> integrate.trapezoid(a, axis=0)
    array([1.5, 2.5, 3.5])
    >>> integrate.trapezoid(a, axis=1)
    array([2.,  8.])
    r   ©ÚxÚdxÚaxisN)ÚhasattrÚnpr   r   ©Úyr   r   r   © r$   úX/var/www/website-v5/atlas_env/lib/python3.8/site-packages/scipy/integrate/_quadrature.pyr      s    h
c                 C  s   t | |||d�S )z}An alias of `trapezoid`.

    `trapz` is kept for backwards compatibility. For new code, prefer
    `trapezoid` instead.
    r   )r   r"   r$   r$   r%   r   …   s    c                   @  s   e Zd ZdS )r   N)Ú__name__Ú
__module__Ú__qualname__r$   r$   r$   r%   r   Ž   s   )ÚProtocolc                   @  s   e Zd ZU ded< dS )ÚCacheAttributeszDict[int, Tuple[Any, Any]]ÚcacheN)r&   r'   r(   Ú__annotations__r$   r$   r$   r%   r*   —   s   
r*   r   )ÚfuncÚreturnc                 C  s
   t t| ƒS ©N)r   r*   ©r-   r$   r$   r%   Úcache_decorator�   s    r1   c                 C  s,   | t jkrt j|  S t| ƒt j| < t j|  S )zX
    Cache roots_legendre results to speed up calls of the fixed_quad
    function.
    )Ú_cached_roots_legendrer+   r
   )Únr$   r$   r%   r2   ¡   s    

r2   r$   é   c                 C  sv   t |ƒ\}}t |¡}t |¡s*t |¡r2tdƒ‚|| |d  d | }|| d tj|| |f|žŽ  dd� dfS )a  
    Compute a definite integral using fixed-order Gaussian quadrature.

    Integrate `func` from `a` to `b` using Gaussian quadrature of
    order `n`.

    Parameters
    ----------
    func : callable
        A Python function or method to integrate (must accept vector inputs).
        If integrating a vector-valued function, the returned array must have
        shape ``(..., len(x))``.
    a : float
        Lower limit of integration.
    b : float
        Upper limit of integration.
    args : tuple, optional
        Extra arguments to pass to function, if any.
    n : int, optional
        Order of quadrature integration. Default is 5.

    Returns
    -------
    val : float
        Gaussian quadrature approximation to the integral
    none : None
        Statically returned value of None

    See Also
    --------
    quad : adaptive quadrature using QUADPACK
    dblquad : double integrals
    tplquad : triple integrals
    romberg : adaptive Romberg quadrature
    quadrature : adaptive Gaussian quadrature
    romb : integrators for sampled data
    simpson : integrators for sampled data
    cumulative_trapezoid : cumulative integration for sampled data
    ode : ODE integrator
    odeint : ODE integrator

    Examples
    --------
    >>> from scipy import integrate
    >>> import numpy as np
    >>> f = lambda x: x**8
    >>> integrate.fixed_quad(f, 0.0, 1.0, n=4)
    (0.1110884353741496, None)
    >>> integrate.fixed_quad(f, 0.0, 1.0, n=5)
    (0.11111111111111102, None)
    >>> print(1/9.0)  # analytical result
    0.1111111111111111

    >>> integrate.fixed_quad(np.cos, 0.0, np.pi/2, n=4)
    (0.9999999771971152, None)
    >>> integrate.fixed_quad(np.cos, 0.0, np.pi/2, n=5)
    (1.000000000039565, None)
    >>> np.sin(np.pi/2)-np.sin(0)  # analytical result
    1.0

    z8Gaussian quadrature is only available for finite limits.é   ç       @r   ©r   N)r2   r!   ÚrealÚisinfÚ
ValueErrorÚsum)r-   ÚaÚbÚargsr3   r   Úwr#   r$   r$   r%   r   ±   s    >
Fc                   s&   |r‡ ‡fdd„}n‡ ‡fdd„}|S )ao  Vectorize the call to a function.

    This is an internal utility function used by `romberg` and
    `quadrature` to create a vectorized version of a function.

    If `vec_func` is True, the function `func` is assumed to take vector
    arguments.

    Parameters
    ----------
    func : callable
        User defined function.
    args : tuple, optional
        Extra arguments for the function.
    vec_func : bool, optional
        True if the function func takes vector arguments.

    Returns
    -------
    vfunc : callable
        A function that will take a vector argument and return the
        result.

    c                   s   ˆ| fˆ žŽ S r/   r$   ©r   ©r>   r-   r$   r%   Úvfunc  s    zvectorize1.<locals>.vfuncc                   sŽ   t  | ¡rˆ| fˆ žŽ S t  | ¡} ˆ| d fˆ žŽ }t| ƒ}t|dt|ƒƒ}t j|f|d�}||d< td|ƒD ]}ˆ| | fˆ žŽ ||< qn|S )Nr   Údtype©rC   r5   )r!   ÚisscalarÚasarrayÚlenÚgetattrÚtypeÚemptyÚrange)r   Úy0r3   rC   ÚoutputÚirA   r$   r%   rB     s    

r$   )r-   r>   Úvec_funcrB   r$   rA   r%   Ú
vectorize1ø   s    rP   çÛ"•“\ÿO>é2   Tr5   c	                 C  s¨   t |tƒs|f}t| ||d�}	tj}
tj}t|d |ƒ}t||d ƒD ]D}t|	||d|ƒd }t||
 ƒ}|}
||k s†||t|
ƒ k rF q qFt	 
d||f t¡ |
|fS )aª  
    Compute a definite integral using fixed-tolerance Gaussian quadrature.

    Integrate `func` from `a` to `b` using Gaussian quadrature
    with absolute tolerance `tol`.

    Parameters
    ----------
    func : function
        A Python function or method to integrate.
    a : float
        Lower limit of integration.
    b : float
        Upper limit of integration.
    args : tuple, optional
        Extra arguments to pass to function.
    tol, rtol : float, optional
        Iteration stops when error between last two iterates is less than
        `tol` OR the relative change is less than `rtol`.
    maxiter : int, optional
        Maximum order of Gaussian quadrature.
    vec_func : bool, optional
        True or False if func handles arrays as arguments (is
        a "vector" function). Default is True.
    miniter : int, optional
        Minimum order of Gaussian quadrature.

    Returns
    -------
    val : float
        Gaussian quadrature approximation (within tolerance) to integral.
    err : float
        Difference between last two estimates of the integral.

    See Also
    --------
    romberg : adaptive Romberg quadrature
    fixed_quad : fixed-order Gaussian quadrature
    quad : adaptive quadrature using QUADPACK
    dblquad : double integrals
    tplquad : triple integrals
    romb : integrator for sampled data
    simpson : integrator for sampled data
    cumulative_trapezoid : cumulative integration for sampled data
    ode : ODE integrator
    odeint : ODE integrator

    Examples
    --------
    >>> from scipy import integrate
    >>> import numpy as np
    >>> f = lambda x: x**8
    >>> integrate.quadrature(f, 0.0, 1.0)
    (0.11111111111111106, 4.163336342344337e-17)
    >>> print(1/9.0)  # analytical result
    0.1111111111111111

    >>> integrate.quadrature(np.cos, 0.0, np.pi/2)
    (0.9999999999999536, 3.9611425250996035e-11)
    >>> np.sin(np.pi/2)-np.sin(0)  # analytical result
    1.0

    ©rO   r5   r$   r   z-maxiter (%d) exceeded. Latest difference = %e)Ú
isinstanceÚtuplerP   r!   ÚinfÚmaxrK   r   ÚabsÚwarningsÚwarnr   )r-   r<   r=   r>   ÚtolÚrtolÚmaxiterrO   ZminiterrB   ÚvalÚerrr3   Únewvalr$   r$   r%   r   %  s"    A

þc                 C  s   t | ƒ}|||< t|ƒS r/   )ÚlistrU   )ÚtrN   ÚvalueÚlr$   r$   r%   Útuplesetz  s    re   c                 C  s   t | ||||d�S )z–An alias of `cumulative_trapezoid`.

    `cumtrapz` is kept for backwards compatibility. For new code, prefer
    `cumulative_trapezoid` instead.
    )r   r   r   Úinitial)r   )r#   r   r   r   rf   r$   r$   r%   r   ‚  s    c                 C  sZ  t  | ¡} |dkr|}nŠt  |¡}|jdkrVt  |¡}dg| j }d||< | |¡}n,t|jƒt| jƒkrttdƒ‚nt j||d�}|j| | j| d kr¢tdƒ‚t| jƒ}tt	dƒf| |t	ddƒƒ}tt	dƒf| |t	ddƒƒ}	t j
|| | | |	   d |d�}
|dk	�rVt  |¡�s$tdƒ‚t|
jƒ}d||< t jt j|||
jd	�|
g|d�}
|
S )
a  
    Cumulatively integrate y(x) using the composite trapezoidal rule.

    Parameters
    ----------
    y : array_like
        Values to integrate.
    x : array_like, optional
        The coordinate to integrate along. If None (default), use spacing `dx`
        between consecutive elements in `y`.
    dx : float, optional
        Spacing between elements of `y`. Only used if `x` is None.
    axis : int, optional
        Specifies the axis to cumulate. Default is -1 (last axis).
    initial : scalar, optional
        If given, insert this value at the beginning of the returned result.
        Typically this value should be 0. Default is None, which means no
        value at ``x[0]`` is returned and `res` has one element less than `y`
        along the axis of integration.

    Returns
    -------
    res : ndarray
        The result of cumulative integration of `y` along `axis`.
        If `initial` is None, the shape is such that the axis of integration
        has one less value than `y`. If `initial` is given, the shape is equal
        to that of `y`.

    See Also
    --------
    numpy.cumsum, numpy.cumprod
    quad : adaptive quadrature using QUADPACK
    romberg : adaptive Romberg quadrature
    quadrature : adaptive Gaussian quadrature
    fixed_quad : fixed-order Gaussian quadrature
    dblquad : double integrals
    tplquad : triple integrals
    romb : integrators for sampled data
    ode : ODE integrators
    odeint : ODE integrators

    Examples
    --------
    >>> from scipy import integrate
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt

    >>> x = np.linspace(-2, 2, num=20)
    >>> y = x
    >>> y_int = integrate.cumulative_trapezoid(y, x, initial=0)
    >>> plt.plot(x, y_int, 'ro', x, y[0] + 0.5 * x**2, 'b-')
    >>> plt.show()

    Nr5   r   ú2If given, shape of x must be 1-D or the same as y.r7   ú7If given, length of x along axis must be the same as y.r6   z'`initial` parameter should be a scalar.rD   )r!   rF   ÚndimÚdiffÚreshaperG   Úshaper:   re   ÚsliceÚcumsumrE   ra   ÚconcatenateÚfullrC   )r#   r   r   r   rf   Údrl   ÚndÚslice1Úslice2Úresr$   r$   r%   r   ‹  s6    7





"

ÿc              
   C  s°  t | jƒ}|d krd}d}td ƒf| }t||t|||ƒƒ}	t||t|d |d |ƒƒ}
t||t|d |d |ƒƒ}|d kr°tj| |	 d| |
   | |  |d�}||d 9 }nütj||d�}t||t|||ƒƒ}t||t|d |d |ƒƒ}t || ¡}t || ¡}|| }|| }tj||t 	|¡|dkd�}|d | |	 d	tjd
|t 	|¡|dkd�  | |
 |tj||t 	|¡|dkd�   | | d	|    }tj||d�}|S )Nr   é   r5   ç      @r7   ç      @)ÚoutÚwhereg      @r6   r   )
rG   rl   rm   re   r!   r;   rj   Úfloat64Útrue_divideÚ
zeros_like)r#   ÚstartÚstopr   r   r   rr   ÚstepÚ	slice_allÚslice0rs   rt   ÚresultÚhZsl0Zsl1Zh0Úh1ZhsumZhprodZh0divh1Útmpr$   r$   r%   Ú_basic_simpsonè  sH    
&
þÿþÿüø	r‡   Úavgc                 C  s   t | ||||d�S )zyAn alias of `simpson`.

    `simps` is kept for backwards compatibility. For new code, prefer
    `simpson` instead.
    )r   r   r   Úeven)r   )r#   r   r   r   r‰   r$   r$   r%   r     s    c                 C  s&  t  | ¡} t| jƒ}| j| }|}|}d}	|dk	r®t  |¡}t|jƒdkr|dg| }
|jd |
|< |j}d}	| t|
ƒ¡}nt|jƒt| jƒkr˜tdƒ‚|j| |kr®tdƒ‚|d dk�rüd}d}tdƒf| }tdƒf| }|dkrðtd	ƒ‚|d
k�r^t||dƒ}t||dƒ}|dk	�r,|| ||  }|d| | | | |   7 }t	| d|d |||ƒ}|dk�rØt||dƒ}t||dƒ}|dk	�r¢|t|ƒ |t|ƒ  }|d| | | | |   7 }|t	| d|d |||ƒ7 }|dk�rò|d }|d }|| }nt	| d|d |||ƒ}|	�r"| |¡}|S )a­	  
    Integrate y(x) using samples along the given axis and the composite
    Simpson's rule. If x is None, spacing of dx is assumed.

    If there are an even number of samples, N, then there are an odd
    number of intervals (N-1), but Simpson's rule requires an even number
    of intervals. The parameter 'even' controls how this is handled.

    Parameters
    ----------
    y : array_like
        Array to be integrated.
    x : array_like, optional
        If given, the points at which `y` is sampled.
    dx : float, optional
        Spacing of integration points along axis of `x`. Only used when
        `x` is None. Default is 1.
    axis : int, optional
        Axis along which to integrate. Default is the last axis.
    even : str {'avg', 'first', 'last'}, optional
        'avg' : Average two results:1) use the first N-2 intervals with
                  a trapezoidal rule on the last interval and 2) use the last
                  N-2 intervals with a trapezoidal rule on the first interval.

        'first' : Use Simpson's rule for the first N-2 intervals with
                a trapezoidal rule on the last interval.

        'last' : Use Simpson's rule for the last N-2 intervals with a
               trapezoidal rule on the first interval.

    Returns
    -------
    float
        The estimated integral computed with the composite Simpson's rule.

    See Also
    --------
    quad : adaptive quadrature using QUADPACK
    romberg : adaptive Romberg quadrature
    quadrature : adaptive Gaussian quadrature
    fixed_quad : fixed-order Gaussian quadrature
    dblquad : double integrals
    tplquad : triple integrals
    romb : integrators for sampled data
    cumulative_trapezoid : cumulative integration for sampled data
    ode : ODE integrators
    odeint : ODE integrators

    Notes
    -----
    For an odd number of samples that are equally spaced the result is
    exact if the function is a polynomial of order 3 or less. If
    the samples are not equally spaced, then the result is exact only
    if the function is a polynomial of order 2 or less.

    Examples
    --------
    >>> from scipy import integrate
    >>> import numpy as np
    >>> x = np.arange(0, 10)
    >>> y = np.arange(0, 10)

    >>> integrate.simpson(y, x)
    40.5

    >>> y = np.power(x, 3)
    >>> integrate.simpson(y, x)
    1642.5
    >>> integrate.quad(lambda x: x**3, 0, 9)[0]
    1640.25

    >>> integrate.simpson(y, x, even='first')
    1644.5

    r   Nr5   rg   rh   rv   g        )rˆ   ÚlastÚfirstz3Parameter 'even' must be 'avg', 'last', or 'first'.)rˆ   r‹   r   éþÿÿÿç      à?é   )rˆ   rŠ   rˆ   r6   )
r!   rF   rG   rl   rk   rU   r:   rm   re   r‡   )r#   r   r   r   r‰   rr   ÚNZlast_dxZfirst_dxZreturnshapeZshapexZ	saveshaper^   rƒ   rs   rt   r$   r$   r%   r     s^    L











c              	   C  sŒ  t  | ¡} t| jƒ}| j| }|d }d}d}||k rH|dK }|d7 }q.||krXtdƒ‚i }	tdƒf| }
t|
|dƒ}t|
|dƒ}|t j|td� }| | | |  d | |	d< |
}| } }}td|d ƒD ]º}|dL }t||t|||ƒƒ}|dL }d	|	|d df || | j	|d
�   |	|df< td|d ƒD ]J}|	||d f }|||	|d |d f  dd| > d   |	||f< �q4|d }qÎ|�r€t  
|	d ¡�sªtdƒ nÖz|d }W n ttfk
�rÔ   d}Y nX z|d }W n ttfk
�r    d}Y nX d||f }d}t|dt|ƒ ddd� t|d ƒD ]8}t|d ƒD ]}t||	||f  dd� �qFtƒ  �q6tdt|ƒ ƒ |	||f S )aÔ  
    Romberg integration using samples of a function.

    Parameters
    ----------
    y : array_like
        A vector of ``2**k + 1`` equally-spaced samples of a function.
    dx : float, optional
        The sample spacing. Default is 1.
    axis : int, optional
        The axis along which to integrate. Default is -1 (last axis).
    show : bool, optional
        When `y` is a single 1-D array, then if this argument is True
        print the table showing Richardson extrapolation from the
        samples. Default is False.

    Returns
    -------
    romb : ndarray
        The integrated result for `axis`.

    See Also
    --------
    quad : adaptive quadrature using QUADPACK
    romberg : adaptive Romberg quadrature
    quadrature : adaptive Gaussian quadrature
    fixed_quad : fixed-order Gaussian quadrature
    dblquad : double integrals
    tplquad : triple integrals
    simpson : integrators for sampled data
    cumulative_trapezoid : cumulative integration for sampled data
    ode : ODE integrators
    odeint : ODE integrators

    Examples
    --------
    >>> from scipy import integrate
    >>> import numpy as np
    >>> x = np.arange(10, 14.25, 0.25)
    >>> y = np.arange(3, 12)

    >>> integrate.romb(y)
    56.0

    >>> y = np.sin(np.power(x, 2.5))
    >>> integrate.romb(y)
    -0.742561336672229

    >>> integrate.romb(y, show=True)
    Richardson Extrapolation Table for Romberg Integration
    ======================================================
    -0.81576
     4.63862  6.45674
    -1.10581 -3.02062 -3.65245
    -2.57379 -3.06311 -3.06595 -3.05664
    -1.34093 -0.92997 -0.78776 -0.75160 -0.74256
    ======================================================
    -0.742561336672229  # may vary

    r5   r   z=Number of samples must be one plus a non-negative power of 2.Nr   rD   r6   )r   r   r�   r7   rv   zE*** Printing table only supported for integrals of a single data set.r4   é   z%%%d.%dfz6Richardson Extrapolation Table for Romberg Integrationú=Ú
)ÚsepÚendú ©r”   )r!   rF   rG   rl   r:   rm   re   ÚfloatrK   r;   rE   ÚprintÚ	TypeErrorÚ
IndexError)r#   r   r   Úshowrr   ZNsampsZNintervr3   ÚkÚRr�   r‚   Zslicem1r„   Zslice_Rr~   r   r€   rN   ÚjÚprevZprecisÚwidthZformstrÚtitler$   r$   r%   r   ›  s`    =



08




c                 C  s’   |dkrt dƒ‚n||dkr6d| |d ƒ| |d ƒ  S |d }t|d |d  ƒ| }|d d|  }||t |¡  }tj| |ƒdd�}|S dS )aU  
    Perform part of the trapezoidal rule to integrate a function.
    Assume that we had called difftrap with all lower powers-of-2
    starting with 1. Calling difftrap only returns the summation
    of the new ordinates. It does _not_ multiply by the width
    of the trapezoids. This must be performed by the caller.
        'function' is the function to evaluate (must accept vector arguments).
        'interval' is a sequence with lower and upper limits
                   of integration.
        'numtraps' is the number of trapezoids to use (must be a
                   power-of-2).
    r   z#numtraps must be > 0 in difftrap().r5   r�   rv   r7   N)r:   r—   r!   Úaranger;   )ÚfunctionÚintervalZnumtrapsZnumtosumr„   ZloxÚpointsÚsr$   r$   r%   Ú	_difftrap  s    
r§   c                 C  s   d| }|| |  |d  S )zƒ
    Compute the differences for the Romberg quadrature corrections.
    See Forman Acton's "Real Computing Made Real," p 143.
    rw   r   r$   )r=   Úcrœ   r†   r$   r$   r%   Ú_romberg_diff6  s    r©   c                 C  sæ   d }}t dt| ƒdd� t d|ƒ t dƒ t dd ƒ tt|ƒƒD ]b}t d	d
| |d |d  d|  f dd� t|d ƒD ]}t d|| |  dd� q€t dƒ qDt dƒ t d|| | dd� t dd
t|ƒd  d dƒ d S )Nr   zRomberg integration ofr•   r–   ÚfromÚ z%6s %9s %9s)ZStepsZStepSizeZResultsz%6d %9frv   r5   r6   z%9fzThe final result isÚafterzfunction evaluations.)r˜   ÚreprrK   rG   )r£   r¤   ÚresmatrN   rž   r$   r$   r%   Ú_printresmat?  s    
,
r¯   ç`sáÓbÈO>é
   c	              	   C  sL  t  |¡st  |¡rtdƒ‚t| ||d�}	d}
||g}|| }t|	||
ƒ}|| }|gg}t j}|d }td|d ƒD ]ª}|
d9 }
|t|	||
ƒ7 }|| |
 g}t|ƒD ]"}| t|| || |d ƒ¡ q¨|| }||d  }|rî| |¡ t	|| ƒ}||k �s||t	|ƒ k �r �q6|}qvt
 d||f t¡ |�rHt|	||ƒ |S )a™
  
    Romberg integration of a callable function or method.

    Returns the integral of `function` (a function of one variable)
    over the interval (`a`, `b`).

    If `show` is 1, the triangular array of the intermediate results
    will be printed. If `vec_func` is True (default is False), then
    `function` is assumed to support vector arguments.

    Parameters
    ----------
    function : callable
        Function to be integrated.
    a : float
        Lower limit of integration.
    b : float
        Upper limit of integration.

    Returns
    -------
    results : float
        Result of the integration.

    Other Parameters
    ----------------
    args : tuple, optional
        Extra arguments to pass to function. Each element of `args` will
        be passed as a single argument to `func`. Default is to pass no
        extra arguments.
    tol, rtol : float, optional
        The desired absolute and relative tolerances. Defaults are 1.48e-8.
    show : bool, optional
        Whether to print the results. Default is False.
    divmax : int, optional
        Maximum order of extrapolation. Default is 10.
    vec_func : bool, optional
        Whether `func` handles arrays as arguments (i.e., whether it is a
        "vector" function). Default is False.

    See Also
    --------
    fixed_quad : Fixed-order Gaussian quadrature.
    quad : Adaptive quadrature using QUADPACK.
    dblquad : Double integrals.
    tplquad : Triple integrals.
    romb : Integrators for sampled data.
    simpson : Integrators for sampled data.
    cumulative_trapezoid : Cumulative integration for sampled data.
    ode : ODE integrator.
    odeint : ODE integrator.

    References
    ----------
    .. [1] 'Romberg's method' https://en.wikipedia.org/wiki/Romberg%27s_method

    Examples
    --------
    Integrate a gaussian from 0 to 1 and compare to the error function.

    >>> from scipy import integrate
    >>> from scipy.special import erf
    >>> import numpy as np
    >>> gaussian = lambda x: 1/np.sqrt(np.pi) * np.exp(-x**2)
    >>> result = integrate.romberg(gaussian, 0, 1, show=True)
    Romberg integration of <function vfunc at ...> from [0, 1]

    ::

       Steps  StepSize  Results
           1  1.000000  0.385872
           2  0.500000  0.412631  0.421551
           4  0.250000  0.419184  0.421368  0.421356
           8  0.125000  0.420810  0.421352  0.421350  0.421350
          16  0.062500  0.421215  0.421350  0.421350  0.421350  0.421350
          32  0.031250  0.421317  0.421350  0.421350  0.421350  0.421350  0.421350

    The final result is 0.421350396475 after 33 function evaluations.

    >>> print("%g %g" % (2*result, erf(1)))
    0.842701 0.842701

    z5Romberg integration only available for finite limits.rS   r5   r   rv   z,divmax (%d) exceeded. Latest difference = %e)r!   r9   r:   rP   r§   rV   rK   Úappendr©   rX   rY   rZ   r   r¯   )r£   r<   r=   r>   r[   r\   r›   ZdivmaxrO   rB   r3   r¤   ZintrangeZordsumrƒ   r®   r_   Úlast_rowrN   Úrowrœ   Z
lastresultr$   r$   r%   r   P  s@    U 

þrv   é   rŽ   é   éZ   r�   éýÿÿÿéP   é-   é   é    iøÿÿÿi±  i   é   éK   iíþÿÿi@/  éŒ   é)   éØ   é   i  i÷ÿÿÿix  i€C  iï  iù  i+  i­  i	àÿÿi é i_7  iÝ  i   i`üÿÿi )  iDîÿÿiÀöÿÿi?# é	   i ^ i)  i}=  i8  i�K  i’  iÁíÿÿi  ip‘ iÃ>  i<Ÿ isBÿÿi( i:üÿih… iiºõÿià0¾	é   i è0iI"! iËÉÍ i›Îÿi½í€ij•mÿi¾iì lýÿÿÿß&	 l    7Ý iR0P i«Ò i@— iè7Œÿi@!i!Nîüi€d7ipRÄúi<ôÿÿic] é   l    `5]vl   v[O l   =H/54 lýÿÿÿž+w l   "…-‘ lýÿÿÿMp:� l   £{•>À lýÿÿÿ$MY( lýÿÿÿí`«: l    @	Al   @d@* iiû`ipÌ`*io¼Òl   àFg! lýÿÿÿófÅ l   �\ a lýÿÿÿ¥LüR l   @`¯ lýÿÿÿ±xí= l   €7-¤)r5   rv   rŽ   r¶   r4   é   r»   r�   rÃ   r±   rÄ   rµ   rÅ   é   c                 C  sü  z<t | ƒd }|r"t |d ¡} nt t | ¡dk¡r:d}W n* tk
rf   | }t |d ¡} d}Y nX |r¬|tkr¬t| \}}}}}|tj|td� | }|t|ƒ| fS | d dksÄ| d |krÌt	dƒ‚| t|ƒ }	d|	 d }
t |d ¡}|
|dd…tj
f  }tj |¡}tdƒD ]}d| | |¡ |¡ }�qd|ddd… d  }|dd…ddd…f  |¡|d  }|d dk�r |�r ||d	  }|d }n||d  }|d }|t |	| |¡ }|d }|t |¡ t|ƒ }t |¡}||| fS )
aâ  
    Return weights and error coefficient for Newton-Cotes integration.

    Suppose we have (N+1) samples of f at the positions
    x_0, x_1, ..., x_N. Then an N-point Newton-Cotes formula for the
    integral between x_0 and x_N is:

    :math:`\int_{x_0}^{x_N} f(x)dx = \Delta x \sum_{i=0}^{N} a_i f(x_i)
    + B_N (\Delta x)^{N+2} f^{N+1} (\xi)`

    where :math:`\xi \in [x_0,x_N]`
    and :math:`\Delta x = \frac{x_N-x_0}{N}` is the average samples spacing.

    If the samples are equally-spaced and N is even, then the error
    term is :math:`B_N (\Delta x)^{N+3} f^{N+2}(\xi)`.

    Parameters
    ----------
    rn : int
        The integer order for equally-spaced data or the relative positions of
        the samples with the first sample at 0 and the last at N, where N+1 is
        the length of `rn`. N is the order of the Newton-Cotes integration.
    equal : int, optional
        Set to 1 to enforce equally spaced data.

    Returns
    -------
    an : ndarray
        1-D array of weights to apply to the function at the provided sample
        positions.
    B : float
        Error coefficient.

    Notes
    -----
    Normally, the Newton-Cotes rules are used on smaller integration
    regions and a composite rule is used to return the total integral.

    Examples
    --------
    Compute the integral of sin(x) in [0, :math:`\pi`]:

    >>> from scipy.integrate import newton_cotes
    >>> import numpy as np
    >>> def f(x):
    ...     return np.sin(x)
    >>> a = 0
    >>> b = np.pi
    >>> exact = 2
    >>> for N in [2, 4, 6, 8, 10]:
    ...     x = np.linspace(a, b, N + 1)
    ...     an, B = newton_cotes(N, 1)
    ...     dx = (b - a) / N
    ...     quad = dx * np.sum(an * f(x))
    ...     error = abs(quad - exact)
    ...     print('{:2d}  {:10.9f}  {:.5e}'.format(N, quad, error))
    ...
     2   2.094395102   9.43951e-02
     4   1.998570732   1.42927e-03
     6   2.000017814   1.78136e-05
     8   1.999999835   1.64725e-07
    10   2.000000001   1.14677e-09

    r5   rD   r   r   z1The sample positions must start at 0 and end at Nrv   Nr6   rx   )rG   r!   r¢   Úallrj   Ú	ExceptionÚ_builtincoeffsÚarrayr—   r:   ÚnewaxisÚlinalgÚinvrK   ÚdotÚmathÚlogr   Úexp)ÚrnÚequalr�   ÚnaÚdaÚviÚnbÚdbÚanÚyiÚtiZnvecÚCZCinvrN   ÚvecÚaiZBNÚpowerÚp1Úfacr$   r$   r%   r     sF    A
$

c              
     sð  t tdƒsddlm} |t_ntj}tˆ ƒs8d}t|ƒ‚t |¡ ¡ }t |¡ ¡ }t 	||¡\}}|j
d }	zˆ || d ƒ W n0 tk
r² }
 zd}t|ƒ|
‚W 5 d }
~
X Y nX zˆ t ||g¡ƒ ˆ }W nJ tk
�r }
 z*d|
› d�}tj|d	d
� ‡ fdd„}W 5 d }
~
X Y nX t |¡}||k�r:d}t|ƒ‚t |¡}||k�rZd}t|ƒ‚|d k�rr|j |	¡}nt||jjƒ�sŽd}t|ƒ‚|j|j
d k�r¬d}t|ƒ‚t|dd ƒ}|j |¡}|dk�rÚd}t|ƒ‚|||||||||f	S )NÚqmcr   )Ústatsz`func` must be callable.rv   z©`func` must evaluate the integrand at points within the integration range; e.g. `func( (a + b) / 2)` must return the integrand at the centroid of the integration volume.zAException encountered when attempting vectorized call to `func`: z«. `func` should accept two-dimensional array with shape `(n_points, len(a))` and return an array with the integrand value at each of the `n_points` for better performance.rŽ   ©Ú
stacklevelc                   s   t jˆ d| d�S )Nr   )r   Úarr)r!   Úapply_along_axisr@   r0   r$   r%   rB   š  s    z_qmc_quad_iv.<locals>.vfuncz`n_points` must be an integer.z!`n_estimates` must be an integer.z8`qrng` must be an instance of scipy.stats.qmc.QMCEngine.z�`qrng` must be initialized with dimensionality equal to the number of variables in `a`, i.e., `qrng.random().shape[-1]` must equal `a.shape[0]`.Úrng_seed>   FTz*`log` must be boolean (`True` or `False`).)r    Ú	_qmc_quadÚscipyrä   Úcallabler™   r!   Ú
atleast_1dÚcopyÚbroadcast_arraysrl   rÉ   r:   rË   rY   rZ   Úint64rã   ÚHaltonrT   Z	QMCEnginerq   rH   Z_qmcÚcheck_random_state)r-   r<   r=   Ún_pointsÚn_estimatesÚqrngrÑ   rä   ÚmessageÚdimÚerB   Zn_points_intZn_estimates_intré   Úrngr$   r0   r%   Ú_qmc_quad_ivs  sZ    







rú   ÚQMCQuadResultÚintegralÚstandard_errori   )ró   rô   rõ   rÑ   r>   c             	   C  s~  t | ||||||ƒ}|\	} }}}}}}}}	t ||k¡r`d}
tj|
dd� t|rXtj nddƒS ||k }d|jdd� }|| ||  ||< ||< t || ¡}|| }t 	|¡}t
|j|ƒ}t|ƒD ]r}| |¡}|	j |||¡}| |ƒ}|�rt|ƒt |¡ }nt || ¡}|||< t|ƒf d|| i|j—Ž}qÆt |¡}|�rb|dk �rb|tjd  n|| }|	 |¡}t||ƒS )	a²  
    Compute an integral in N-dimensions using Quasi-Monte Carlo quadrature.

    Parameters
    ----------
    func : callable
        The integrand. Must accept a single arguments `x`, an array which
        specifies the point at which to evaluate the integrand. For efficiency,
        the function should be vectorized to compute the integrand for each
        element an array of shape ``(n_points, n)``, where ``n`` is number of
        variables.
    a, b : array-like
        One-dimensional arrays specifying the lower and upper integration
        limits, respectively, of each of the ``n`` variables.
    n_points, n_estimates : int, optional
        One QMC sample of `n_points` (default: 256) points will be generated
        by `qrng`, and `n_estimates` (default: 8) statistically independent
        estimates of the integral will be produced. The total number of points
        at which the integrand `func` will be evaluated is
        ``n_points * n_estimates``. See Notes for details.
    qrng : `~scipy.stats.qmc.QMCEngine`, optional
        An instance of the QMCEngine from which to sample QMC points.
        The QMCEngine must be initialized to a number of dimensions
        corresponding with the number of variables ``x0, ..., xn`` passed to
        `func`.
        The provided QMCEngine is used to produce the first integral estimate.
        If `n_estimates` is greater than one, additional QMCEngines are
        spawned from the first (with scrambling enabled, if it is an option.)
        If a QMCEngine is not provided, the default `scipy.stats.qmc.Halton`
        will be initialized with the number of dimensions determine from
        `a`.
    log : boolean, default: False
        When set to True, `func` returns the log of the integrand, and
        the result object contains the log of the integral.

    Returns
    -------
    result : object
        A result object with attributes:

        integral : float
            The estimate of the integral.
        standard_error :
            The error estimate. See Notes for interpretation.

    Notes
    -----
    Values of the integrand at each of the `n_points` points of a QMC sample
    are used to produce an estimate of the integral. This estimate is drawn
    from a population of possible estimates of the integral, the value of
    which we obtain depends on the particular points at which the integral
    was evaluated. We perform this process `n_estimates` times, each time
    evaluating the integrand at different scrambled QMC points, effectively
    drawing i.i.d. random samples from the population of integral estimates.
    The sample mean :math:`m` of these integral estimates is an
    unbiased estimator of the true value of the integral, and the standard
    error of the mean :math:`s` of these estimates may be used to generate
    confidence intervals using the t distribution with ``n_estimates - 1``
    degrees of freedom. Perhaps counter-intuitively, increasing `n_points`
    while keeping the total number of function evaluation points
    ``n_points * n_estimates`` fixed tends to reduce the actual error, whereas
    increasing `n_estimates` tends to decrease the error estimate.

    Examples
    --------
    QMC quadrature is particularly useful for computing integrals in higher
    dimensions. An example integrand is the probability density function
    of a multivariate normal distribution.

    >>> import numpy as np
    >>> from scipy import stats
    >>> dim = 8
    >>> mean = np.zeros(dim)
    >>> cov = np.eye(dim)
    >>> def func(x):
    ...     return stats.multivariate_normal.pdf(x, mean, cov)

    To compute the integral over the unit hypercube:

    >>> from scipy.integrate import qmc_quad
    >>> a = np.zeros(dim)
    >>> b = np.ones(dim)
    >>> rng = np.random.default_rng()
    >>> qrng = stats.qmc.Halton(d=dim, seed=rng)
    >>> n_estimates = 8
    >>> res = qmc_quad(func, a, b, n_estimates=n_estimates, qrng=qrng)
    >>> res.integral, res.standard_error
    (0.00018441088533413305, 1.1255608140911588e-07)

    A two-sided, 99% confidence interval for the integral may be estimated
    as:

    >>> t = stats.t(df=n_estimates-1, loc=res.integral,
    ...             scale=res.standard_error)
    >>> t.interval(0.99)
    (0.00018401699720722663, 0.00018480477346103947)

    Indeed, the value reported by `scipy.stats.multivariate_normal` is
    within this range.

    >>> stats.multivariate_normal.cdf(b, mean, cov, lower_limit=a)
    0.00018430867675187443

    z^A lower limit was equal to an upper limit, so the value of the integral is zero by definition.rv   rå   r   r   r7   Úseedy              ð?)rú   r!   ÚanyrY   rZ   rû   rV   r;   ÚprodÚzerosr   rù   rK   Úrandomrã   Úscaler   rÑ   rI   Z
_init_quadÚmeanÚpiÚsem)r-   r<   r=   ró   rô   rõ   rÑ   r>   rù   rä   rö   Zi_swapÚsignÚAZdAZ	estimatesZrngsrN   Úsampler   Z
integrandsÚestimaterü   rý   r$   r$   r%   rê   À  s4    j


&
rê   )Nr   r   )Nr   r   )r$   r4   )r$   F)r$   rQ   rQ   rR   Tr5   )Nr   r   N)Nr   r   N)Nr   r   rˆ   )Nr   r   rˆ   )r   r   F)r$   r°   r°   Fr±   F)r   )5Ú
__future__r   Útypingr   r   r   r   r   r   Ú	functoolsÚnumpyr!   rÐ   ÚtypesrY   Úcollectionsr	   Úscipy.specialr
   r   r   Úscipy._lib._utilr   Ú__all__r   r   ÚWarningr   r)   r*   r1   r2   Údictr+   r   rP   r   re   r   r   r‡   r   r   r   r§   r©   r¯   r   rÊ   r   rú   rû   rê   r$   r$   r$   r%   Ú<module>   s&        ý
p
	

G
-    ÿ
U
	
]'
	
 
 	    ÿ
  ÿ ÿ ÿ    ÿ þ     þ þ      þ þ
       üû        ýüå#
mJ ÿ