L iddlZddlmZddlZddlZddlmZddl m Z ddl m Z ddl m Z mZddlmZddlmZmZmZgdZded Zd Zee_dfdZdZdgdZdZdhd d ddZdej>dej>de ej>ej>gej>fdej>fdZ dej>dej>dej>fdZ!dej>dej>dej>fdZ"dejFdej>fdZ$dd d dddZ%did Z&d!d"d!d!gd d#fd!d$gd%d d&fd$d'gd(d)d*fd"d+gd,d-d.fd d/gd0d1d2fd!d3gd4d5d6fd7d8gd9d:d;fdd?d@fdAdBgdCdDdEfd dFgdGdHdIfdJdKgdLdMdNfd!dOgdPdQdRfdSdTgdUdVdWfd7dXgdYdZd[fd\Z'djd]Z(d^Z)ed_d`dagZ*d'dbdddcddZ+y)kN) namedtuple)Callable)roots_legendre)gammaln logsumexp) _rng_spawn)_asarrayarray_namespacexp_result_type) fixed_quadromb trapezoidsimpsoncumulative_trapezoid newton_cotesqmc_quadcumulative_simpson?c 0t|}t||d}t|d|}|j}t dg|z}t dg|z}t dd||<t dd||<||} nt||d}|jdk(r.|dd|ddz } dg|z} t d| |<| t | } n9|j ||j}|t ||t |z } |j| |t ||t |zzdz ||} | S#t$r[|j| } |j|}|j| |t ||t |zzdz ||} Y| SwxYw) 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. The default is the last axis. 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.]) T)xpsubok)force_floatingrNr@)axisdtype) r r r ndimslicetuple broadcast_toshapesum ValueErrorasarray) yxdxrr result_dtypendslice1slice2dslice3rets a/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/scipy/integrate/_quadrature.pyrrsL  Br&A"!DR@L BDk]2 FDk]2 FD>F4Lr?F4Ly  Q2T * 66Q;!"#2AVb[F ;F4L%- A177+A%- 1U6]#33A  ff 5=!AeFm$44 5 ;\  J  JJqM JJqMff 5=!AeFm$44 5 ;\  J s:5D11A FFc|tjvrtj|St|tj|<tj|S)zX Cache roots_legendre results to speed up calls of the fixed_quad function. )_cached_roots_legendrecacher)ns r0r2r2sK  " ( ((%++A..&4Q&7  # ! ' ' **c,t|\}}tj|}tj|stj|r t d||z |dzzdz |z}||z dz tj |||g|zdzdfS)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 romb : integrators for sampled data simpson : integrators for sampled data cumulative_trapezoid : cumulative integration for sampled data 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.rrrrN)r2nprealisinfr$r#)funcabargsr4r'wr&s r0r r st "! $DAq  A xx{bhhqk*+ + 1qs C!A aC9rvvaQ.R8 8$ >>r5c8t|}|||<t|SN)listr )tivaluels r0tuplesetrHs QA AaD 8Or5c8tj|}|j|dk(r td||}ntj|}|jdk(r>> 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() rz,At least one point is required along `axis`.Nrr2If given, shape of x must be 1-D or the same as y.r87If given, length of x along axis must be the same as y.rz `initial` must be `None` or `0`.z'`initial` parameter should be a scalar.r)r9r%r"r$rdiffreshapelenrHrcumsumisscalarrC concatenatefullr) r&r'r(rinitialr-r"r*r+r,ress r0rrsf 1 Awwt}GHHy  JJqM 66Q; AC!&&LEE$K % A \S\ )*+ +%A 774=AGGDMA- -*+ + QWWB uT{nR'uQ~ >F uT{nR'uT2 ?F ))A6QvY./#5D AC a<?@ @{{7#FG GSYYd nnbggeWCIIFL"&( Jr5c t|j}|d}d}tdf|z}t||t|||} t||t|dz|dz|} t||t|dz|dz|} |3t j || d|| zz|| z|} | |dz z} | St j ||} t||t|||}t||t|dz|dz|}| |jtd}| |jtd}||z}||z}t j||t j||dk7 }|d z || d t jd |t j||dk7 z z|| |t j||t j||dk7 zzz|| d |z zzz}t j ||} | S) Nrrg@r8@Fcopyoutwhereg@rr) rOr"rrHr9r#rMastypefloat true_divide zeros_like)r&startstopr'r(rr*step slice_allslice0r+r,resulthsl0sl1h0h1hsumhprodh0divh1tmps r0_basic_simpsonrqXs# QWWB } Dtr!I iuUD$'? @F iuU1Wd1fd'C DF iuU1Wd1fd'C DFy& C& M1AfI=DI"s(, M% GGAD !y$eT4(@Ay$eAgtAvt(DE sV]]5u] - sV]]5u] -BwR..RR]]2->bAgN3h!F)W46MM'4J6=l"DDEF)t')~~dE:<--:M>> from scipy import integrate >>> import numpy as np >>> x = np.arange(0, 10) >>> y = np.arange(0, 10) >>> integrate.simpson(y, x=x) 40.5 >>> y = np.power(x, 3) >>> integrate.simpson(y, x=x) 1640.5 >>> integrate.quad(lambda x: x**3, 0, 9)[0] 1640.25 rNrrJrKrWgr?rLr8r[rX)r9r%rOr"rNr r$rrHrqfloat64rMsqueezer`ra)r&r'r(rr*Nlast_dx returnshapeshapex saveshapevalrgrer+r,r.rhhm2hm1diffsnumdenalphabetaetas r0rr}s| 1 A QWWB  AGK} JJqM qww<1 S2XF771:F4LIK %-(A \S\ )*+ + 774=A *+ + 1uz4[NR' 6ir2Fir2F}F)ai/ 3=AfI& $9: :C$Aq!A#q"d;Fir2Fir2Fir2F B82::6A}y$b"a0@Ay$b$0BC 27714#89ZZc 6ZZc 68adai-!ad(QqT/1Cqtad{#CNNMM#&Qh EA$!)cAaDj1Q4//Cad(C>>MM#&Qh Dadai-Cad(adQqTk*C..MM#&Qh C eAfIoQvY6QvYF FF# 1ac1b$7 IIi  Mr5r&r(integration_funcreturncN|||}||ddddf|ddddfddddf}t|j}|dxxdz cc<tj|}|ddddf|ddddf<|ddddf|ddddf<|d|d<tj|d}|S)zCalculate cumulative sum of Simpson integrals. Takes as input the integration function to be used. The integration_func is assumed to return the cumulative sum using composite Simpson's rule. Assumes the axis of summation is -1. .NrrrW).rr8)rCr"r9emptyrP)r&r(rsub_integrals_h1sub_integrals_h2r" sub_integralsrUs r0#_cumulatively_sum_simpson_integralsrs(2.'#tt) bddmDS$B$YO !'' (E "INIHHUOM 0cc :M#u1u*/SqS9M#qt!t).g6M' ))M +C Jr5c~|dddf}|dddf}|dddf}|dddf}|dz d|zd z d|zz|d z z zS) zCalculate the Simpson integrals for all h1 intervals assuming equal interval widths. The function can also be used to calculate the integral for all h2 intervals by reversing the inputs, `y` and `dx`. .NrrsrrWrur6)r&r(r-f1f2f3s r0#_cumulative_simpson_equal_intervalsr7sq 38 A 38B 3"9B 37B q5AFQJR'"q&0 11r5c|dddf}|dddf}|dddf}|dddf}|dddf}||z}||z }||z } || z} d|z } d| z|z} | } |dz | |z| |zz| |zzzS) zCalculate the Simpson integrals for all h1 intervals assuming unequal interval widths. The function can also be used to calculate the integral for all h2 intervals by reversing the inputs, `y` and `dx`. .NrrrsrWrurwr)r&r(x21x32rrrx31x21_x31x21_x32 x21x21_x31x32coeff1coeff2coeff3s r0%_cumulative_simpson_unequal_intervalsrEs S#2#X,C S!"W+C 38B 3"9B 37B )C#gG#gGg%M[F   (F^F q5F2Ir )F2I5 66r5arrctj|}tj|jtjr|j t d}|S)NFrY)r9r% issubdtyperintegerr^r_)rs r0_ensure_float_arrayr]s< **S/C }}SYY +jjUj+ Jr5)r'r(rrTcjt|}|}|j} tj||d}|jddkr)t||||d} tj| |d} no|t|}d}|j|k(s+|j d k(rt|||k(s t ||j d k(r tj||jntj||d}tj|d }tj|d kr t d t||t} nt|}t||||d z } t||d } d }|j d k(s|j| k(s t |tj|| }tj||d}t||t} |t|}t||d } d}|j d k(s|j| k(s t |tj|| }tj||d}| |z } tj || fd } tj| d|} | S#t$r$}d|d|j d}t ||d}~wwxYw)a, Cumulatively integrate y(x) using the composite Simpson's 1/3 rule. The integral of the samples at every point is calculated by assuming a quadratic relationship between each point and the two adjacent points. Parameters ---------- y : array_like Values to integrate. Requires at least one point along `axis`. If two or fewer points are provided along `axis`, Simpson's integration is not possible and the result is calculated with `cumulative_trapezoid`. x : array_like, optional The coordinate to integrate along. Must have the same shape as `y` or must be 1D with the same length as `y` along `axis`. `x` must also be strictly increasing along `axis`. If `x` is None (default), integration is performed using spacing `dx` between consecutive elements in `y`. dx : scalar or array_like, optional Spacing between elements of `y`. Only used if `x` is None. Can either be a float, or an array with the same shape as `y`, but of length one along `axis`. Default is 1.0. axis : int, optional Specifies the axis to integrate along. Default is -1 (last axis). initial : scalar or array_like, optional If given, insert this value at the beginning of the returned result, and add it to the rest of the result. 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. Can either be a float, or an array with the same shape as `y`, but of length one along `axis`. 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 cumulative_trapezoid : cumulative integration using the composite trapezoidal rule simpson : integrator for sampled data using the Composite Simpson's Rule Notes ----- .. versionadded:: 1.12.0 The composite Simpson's 1/3 method can be used to approximate the definite integral of a sampled input function :math:`y(x)` [1]_. The method assumes a quadratic relationship over the interval containing any three consecutive sampled points. Consider three consecutive points: :math:`(x_1, y_1), (x_2, y_2), (x_3, y_3)`. Assuming a quadratic relationship over the three points, the integral over the subinterval between :math:`x_1` and :math:`x_2` is given by formula (8) of [2]_: .. math:: \int_{x_1}^{x_2} y(x) dx\ &= \frac{x_2-x_1}{6}\left[\ \left\{3-\frac{x_2-x_1}{x_3-x_1}\right\} y_1 + \ \left\{3 + \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} + \ \frac{x_2-x_1}{x_3-x_1}\right\} y_2\\ - \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} y_3\right] The integral between :math:`x_2` and :math:`x_3` is given by swapping appearances of :math:`x_1` and :math:`x_3`. The integral is estimated separately for each subinterval and then cumulatively summed to obtain the final result. For samples that are equally spaced, the result is exact if the function is a polynomial of order three or less [1]_ and the number of subintervals is even. Otherwise, the integral is exact for polynomials of order two or less. References ---------- .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Simpson's_rule .. [2] Cartwright, Kenneth V. Simpson's Rule Cumulative Integration with MS Excel and Irregularly-spaced Data. Journal of Mathematical Sciences and Mathematics Education. 12 (2): 1-9 Examples -------- >>> from scipy import integrate >>> import numpy as np >>> import matplotlib.pyplot as plt >>> x = np.linspace(-2, 2, num=20) >>> y = x**2 >>> y_int = integrate.cumulative_simpson(y, x=x, initial=0) >>> fig, ax = plt.subplots() >>> ax.plot(x, y_int, 'ro', x, x**3/3 - (x[0])**3/3, 'b-') >>> ax.grid() >>> plt.show() The output of `cumulative_simpson` is similar to that of iteratively calling `simpson` with successively higher upper limits of integration, but not identical. >>> def cumulative_simpson_reference(y, x): ... return np.asarray([integrate.simpson(y[:i], x=x[:i]) ... for i in range(2, len(y) + 1)]) >>> >>> rng = np.random.default_rng(354673834679465) >>> x, y = rng.random(size=(2, 10)) >>> x.sort() >>> >>> res = integrate.cumulative_simpson(y, x=x) >>> ref = cumulative_simpson_reference(y, x) >>> equal = np.abs(res - ref) < 1e-15 >>> equal # not equal when `simpson` has even number of subintervals array([False, True, False, True, False, True, False, True, True]) This is expected: because `cumulative_simpson` has access to more information than `simpson`, it can typically produce more accurate estimates of the underlying integral over subintervals. rz`axis=z$` is not valid for `y` with `y.ndim=z`.Nru)r(rrTz_If given, shape of `x` must be the same as `y` or 1-D with the same length as `y` along `axis`.rr8rz$Input x must be strictly increasing.zkIf provided, `dx` must either be a scalar or have the same shape as `y` but with only 1 point along `axis`.zpIf provided, `initial` must either be a scalar or have the same shape as `y` but with only 1 point along `axis`.)rr"r9swapaxes IndexErrorrr$rrOr!rManyrrrHrrR) r&r'r(rrT original_yoriginal_shapeemessagerUfinal_dx_shapealt_input_dx_shapealt_initial_input_shapes r0rrdsv AAJWWN) KK4 $ wwr{Q":qRdDQkk#tR(   ":>)FFaKCFnT.B$BW% %+,66Q;BOOAqww 'BKK4QSF1 ,> >W% % __R 0 [[T2 &1 r6 %g."*>4"CK !W]]6M%MW% %//'+BC++gtR0 wnngs^"5 ++c2t $C Jg )4& DQVVHBO!q()sJ J2J--J2Fc tj|}t|j}|j|}|dz }d}d}||kr|dz}|dz }||kr||k7r t di} t df|z} t | |d} t | |d} |tj|tz} || || zdz | z| d<| }|x}x}}td|dzD]}|dz}t ||t |||}|dz}d | |dz df| ||j| zzz| |df<td|dzD]0}| ||dz f}||| |dz |dz fz dd |zzdz z z| ||f<2| dz} |rtj| ds td n |d} |d}d|d|d}d}t|dt|zddt|dzD]4}t|dzD]}t|| ||fzdt6tdt|z| ||fS#ttf$rd }YwxYw#ttf$rd}YwxYw)aE 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 fixed_quad : fixed-order Gaussian quadrature dblquad : double integrals tplquad : triple integrals simpson : integrators for sampled data cumulative_trapezoid : cumulative integration for sampled data 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 rrz=Number of samples must be one plus a non-negative power of 2.NrrLr)rrrtr8rWzE*** Printing table only supported for integrals of a single data set.r6%.fz6Richardson Extrapolation Table for Romberg Integration= )sepend )r)r9r%rOr"r$rrHr_ranger#rQprint TypeErrorr)r&r(rshowr*NsampsNintervr4kRrerfslicem1rhslice_RrbrcrdrEjprevpreciswidthformstrtitles r0r r sr 1 A QWWB WWT]FQhG A A g+ a Q g+ G|45 5 At#I iq )Fy$+G"**Ru--A6QwZ',Q.AfIG!!E!D4 1ac] ! 7D%tT*BC  AaC8q7T)B'BBC1a& q!A# GAa1X;DQ!QqSz] 2ac A~FFAq!fI G S {{1V9% + , a Q%&+GLE %s5z)t >1Q3Z qs8A'Aq!fI-378  #E " # aV9!z*  z*  s$H0"I0IIIIrrW ru)rrrZr)rrururrvP-) rrriii )K2rrrii@/))irrriixriC) + rrrri iri_7) `)iDrrrrii?# i^) ) }=8Krrrrriiip) ><sB(:ihrrrrriii0 i0) I"!jmirrrrrrl& l7iR0P) @7@!!Nd7ipRrrrrrri$MY(rrrrrrrl`:l@ Al@d@*)i`p`*oFg!f\a LRl@`rrrrrrrlx=l7-)rrWrurr6rwrrr rrrcv t|dz }|rtj|dz}n-tjtj|dk(rd}|rH|t vr@t |\}}}}}|tj|tz|z }|t||z fS|ddk7s|d|k7r td|t|z } d| zdz } tj|dz} | | ddtjfz} tjj| } tdD](}d| z| j| j| z } *d| ddddzz }| dddddfj||dz z}|dzdk(r|r||d zz }|dz}n ||dzz }|dz}|tj| |z|z }|dz}|tj |zt#|z }tj$|}|||zfS#t $r |}tj|dz}d}YwxYw) 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 rrLrrz1The sample positions must start at 0 and end at NrWNrrX)rOr9arangeallrM Exception_builtincoeffsarrayr_r$newaxislinalginvrdotmathlogrexp)rnequalrznadavinbdbanyitinvecCCinvrEvecaiBNpowerp1facs r0rrs;B  GAI 1Q3B VVBGGBK1$ %E  n$+A.BB "((2U+ +b 059R< 1 2! )* * eAhB R!B 99QqS>D d1bjj=!!A 99== D 1X.v --. cc1 C a1f  # !b& )B A  "X! "X! bffRY# #B qB  gbk )C ((3-C r#v:G   YYqs^sAH%H87H8c ttdsddlm}|t_ntj}t s d}t |t j|j}t j|j}t j||\}}|jd} ||zdz  t j||gj} t j"|} || k7r d }t |t j"|} || k7r d }t |||j$j'| }n-t)||j$j*s d}t ||j,|jdk7r d}t|t/|dd}|j0j3|}|dvr d}t || ||| | ||||f S#t$r} d}t|| d} ~ wwxYw#t$r-} d| d}tj |d fd } Yd} ~ Vd} ~ wwxYw)Nqmcr)statsz`func` must be callable.rWz`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. For better performance, `func` should accept two-dimensional array `x` with shape `(len(a), n_points)` and return an array of the integrand value at each of the `n_points.ru stacklevelc4tjd|S)Nr)rr)r9apply_along_axis)r'r<s r0vfuncz_qmc_quad_iv..vfunc`s&&t"!< FTz*`log` must be boolean (`True` or `False`).)hasattrrscipyr,callablerr9 atleast_1drZbroadcast_arraysr"r r$rTwarningswarnint64r+Halton isinstance QMCEnginer-getattr_qmccheck_random_state)r<r=r>n_points n_estimatesqrngrr,rdimrr1 n_points_intn_estimates_intr2rngs` r0 _qmc_quad_ivrI9s7 8U # D>,   aA aA  q! $DAq ''!*C) a!eq[ = RXXq!f    88H%L<2  hh{+Oo%5   |yy$ eii11 2L   vvH!!tZ.H ** ' ' 1C ->  1ac3 NNe ))!q( )  =S!,,  g!, = = =s0;G9 )H9 HHH I!"I  I QMCQuadResultintegralstandard_errori)rCrBrDrc t||||||}|\ }}}}}}}} dd} dfd dfd dfd } tj||k(r=d} tj| dt |rtj dSddS||k} d | jd z}|| || c|| <|| <tj||z }||z }tj}t|j}tD]o}|j|}| jj|||j }||}| |||||<t#|dd ||i|j$}q||}| ||| }|r|dkr|tj&d zzn||z}t ||S)a Compute an integral in N-dimensions using Quasi-Monte Carlo quadrature. Parameters ---------- func : callable The integrand. Must accept a single argument ``x``, an array which specifies the point(s) at which to evaluate the scalar-valued integrand, and return the value(s) of the integrand. For efficiency, the function should be vectorized to accept an array of shape ``(d, n_points)``, where ``d`` is the number of variables (i.e. the dimensionality of the function domain) and `n_points` is the number of quadrature points, and return an array of shape ``(n_points,)``, the integrand at each quadrature point. a, b : array-like One-dimensional arrays specifying the lower and upper integration limits, respectively, of each of the ``d`` variables. n_estimates, n_points : int, optional `n_estimates` (default: 8) statistically independent QMC samples, each of `n_points` (default: 1024) points, will be generated by `qrng`. 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 ``d`` corresponding with the number of variables ``x1, ..., xd`` 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 the length of `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): ... # `multivariate_normal` expects the _last_ axis to correspond with ... # the dimensionality of the space, so `x` must be transposed ... return stats.multivariate_normal.pdf(x.T, 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.00018429555666024108, 1.0389431116001344e-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.0001839319802536469, 0.00018465913306683527) 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 cx|r!t|tj|zStj||zSrB)rr9rr#) integrandsdArs r0 sum_productzqmc_quad..sum_products0 Z(266":5 566*r/* *r5ct|r!t|tjz Stj|SrB)rr9rmean) estimatesrrCs r0rSzqmc_quad..means. Y'"&&*== =779% %r5rcl|xs ||}|rtj||\}}tj||tjdzzf}t |d}tj dt d|ztj |z z zStj||S)N?rr8rtrW)ddof)r9r7vstackpirr:rstd)rTmrWrtemprMrSrCs r0rZzqmc_quad..stds %i% ..y!#?@A A66)$/ /r5c|xs ||}|xs ||d|}|r|dtjzz S|tjz S)Nr)rWrrt)r9rsqrt)rTr[srrSrCrZs r0semzqmc_quad..semsY %i% 3Ys3 s266+... .rww{++ +r5z^A lower limit was equal to an upper limit, so the value of the integral is zero by definition.rWr-rr8seed)r[rrV)F)NrF)NNFr)rIr9rr9r:rJinfr#prodzerosrrHrrandomr+scaler8type _init_quadrY)r<r=r>rCrBrDrr?rHr,rQr`ri_swapsignArPrTrngsrEsampler'rOrKrLrSrZs ` @@r0rrs\ aHk4 ED?C 22r5)Nrr)rr6)NrrNrB)rrF)r),numpyr9 numpy.typingtypingnptrr9 collectionsrcollections.abcr scipy.specialrrrscipy._lib._utilrscipy._lib._array_apir r r __all__rr2dictr3r rHrrqrndarrayrrr ArrayLikerrr rrrIrJrrr5r0r{s "$(,'KK - L^ + $v@?F Zz"J^Sr^B zz  BJJ7CDZZ 2 22:: 22:: 2"** 27RZZ7RZZ7BJJ70S]]rzz $"dupo\ !QqE"R !GBr !Ib "^Bs# #!$u- #'40 %7fE %? f %#V- 67 )  H()4l D G016 @ \35@    J8:E   7 FjZGOT?Z9I,JK )*Dtr3r5