K iOddlmZddlmZ ej ZedZdZ eddZ dZ edd Z d Z ed Zifd Zed ZeddZeddZedZedZy#e$rejZYnwxYw))xrange)defunct|}|j}d|dzz}t|dzD]}||||zz }|||z z|dzz}|S)z Given a sequence `(s_k)` containing at least `n+1` items, returns the `n`-th forward difference, .. math :: \Delta^n = \sum_{k=0}^{\infty} (-1)^{k+n} {n \choose k} s_k. r)intzeror)ctxsndbks e/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/mpmath/calculus/differentiation.py differencer sh AA A QA AaC[! Q1X  !A#YAaC ! Hc |jd}|jdd}|jdd}|d|zz|dzz} |j} | |_|jd} | H|jd rt|j|} nd} |j d| |z | z } n|j | } |jdd}|r%| |j |z} t|dz} | }nt| |dzd} d| z}|r|d | zz }| Dcgc]}|||| zz}}||| f| |_Scc}w#| |_wxYw) Nsingularaddprec directionrrhrelativeg?)getprecrmagldexpconvertsignr)r fxr roptionsrrrworkprecorigr hextramagstepsnormrvaluess rhstepsr*s_{{:&Hkk)R(G K+IQwY1Q3'H 88D KK  9{{:& O   !dU7]945A AAKK Q/  )$ $A1Q3KEDA2qsA&EaCD  QJA$)*q!AacE(**tX%+sCE !E6E E Ec <d} t}td}|r.Dcgc]}j|c}t|S|j dd}dk(r-|dk7r(|j dsjSj } |dk(r4t | fi|\} } } | _j| | zz } n|dk(rxj dz c_j|j d d fd }j|dd jzg}|jzd jzz } ntd |z| _| S#t$rYhwxYwcc}w#| _wxYw)a Numerically computes the derivative of `f`, `f'(x)`, or generally for an integer `n \ge 0`, the `n`-th derivative `f^{(n)}(x)`. A few basic examples are:: >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> diff(lambda x: x**2 + x, 1.0) 3.0 >>> diff(lambda x: x**2 + x, 1.0, 2) 2.0 >>> diff(lambda x: x**2 + x, 1.0, 3) 0.0 >>> nprint([diff(exp, 3, n) for n in range(5)]) # exp'(x) = exp(x) [20.0855, 20.0855, 20.0855, 20.0855, 20.0855] Even more generally, given a tuple of arguments `(x_1, \ldots, x_k)` and order `(n_1, \ldots, n_k)`, the partial derivative `f^{(n_1,\ldots,n_k)}(x_1,\ldots,x_k)` is evaluated. For example:: >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (0,1)) 2.75 >>> diff(lambda x,y: 3*x*y + 2*y - x, (0.25, 0.5), (1,1)) 3.0 **Options** The following optional keyword arguments are recognized: ``method`` Supported methods are ``'step'`` or ``'quad'``: derivatives may be computed using either a finite difference with a small step size `h` (default), or numerical quadrature. ``direction`` Direction of finite difference: can be -1 for a left difference, 0 for a central difference (default), or +1 for a right difference; more generally can be any complex number. ``addprec`` Extra precision for `h` used to account for the function's sensitivity to perturbations (default = 10). ``relative`` Choose `h` relative to the magnitude of `x`, rather than an absolute value; useful for large or tiny `x` (default = False). ``h`` As an alternative to ``addprec`` and ``relative``, manually select the step size `h`. ``singular`` If True, evaluation exactly at the point `x` is avoided; this is useful for differentiating functions with removable singularities. Default = False. ``radius`` Radius of integration contour (with ``method = 'quad'``). Default = 0.25. A larger radius typically is faster and more accurate, but it must be chosen so that `f` has no singularities within the radius from the evaluation point. A finite difference requires `n+1` function evaluations and must be performed at `(n+1)` times the target precision. Accordingly, `f` must support fast evaluation at high precision. With integration, a larger number of function evaluations is required, but not much extra precision is required. For high order derivatives, this method may thus be faster if f is very expensive to evaluate at high precision. **Further examples** The direction option is useful for computing left- or right-sided derivatives of nonsmooth functions:: >>> diff(abs, 0, direction=0) 0.0 >>> diff(abs, 0, direction=1) 1.0 >>> diff(abs, 0, direction=-1) -1.0 More generally, if the direction is nonzero, a right difference is computed where the step size is multiplied by sign(direction). For example, with direction=+j, the derivative from the positive imaginary direction will be computed:: >>> diff(abs, 0, direction=j) (0.0 - 1.0j) With integration, the result may have a small imaginary part even even if the result is purely real:: >>> diff(sqrt, 1, method='quad') # doctest:+ELLIPSIS (0.5 - 4.59...e-26j) >>> chop(_) 0.5 Adding precision to obtain an accurate value:: >>> diff(cos, 1e-30) 0.0 >>> diff(cos, 1e-30, h=0.0001) -9.99999998328279e-31 >>> diff(cos, 1e-30, addprec=100) -1.0e-30 FTmethodsteprquadrrradiusg?cRj|z}|z}||zz SN)expj)treizr r!r r/r"s rgzdiff..gs0SXXa[(Gtc1f}$rrzunknown method: %r) list TypeErrorr _partial_diffrrr*rquadtspi factorial ValueError)r r!r"r r#partialorders_r,rr)r(r$vr6r r/s```` @rdiffrBCsRG a G%& 'S[[^ 'S!Q88 [[6 *FAv&F"7;;z+BQ  88D V %+CAq$%J'%J "FD(CHvq)D!G3A v  HHNH[[Xt!<=F % % 1q!CFF(m,ACMM!$$#&&1A1F:; ; 2I7     (.s#E=F "CF= F  F  Fc|sSt|s|Sdtt|D] |s n|fd}d|<t|||S)NrcDfd}j|fiS)Nc.d|fzdzdzSNr)r3r!f_argsis rinnerz1_partial_diff..fdiff_inner..inners*vbqzQD(6!A#$<79 9rrB)rHrJr r!rIr#orders` r fdiff_innerz"_partial_diff..fdiff_inners& :sxxvay%;7;;r)sumrangelenr9)r r!xsr?r#rMrIrLs`` ` @@rr9r9sw s v;"v  A 3v;  !9  1IE<<F1I k2vw ??rNc+K| |j}n t|}|jdddk7r0d}||dzkr%|j|||fi||dz }||dzkr%y|jd}|r|j||ddn||j ||dkry||jk(rd \}}nd|dz}} |j } t ||||| fi|\} } } t||D]5} | |_|j| || |zz } | |_| ||k\s5y|t|d zdz}}t||}#| |_wxYww) ad Returns a generator that yields the sequence of derivatives .. math :: f(x), f'(x), f''(x), \ldots, f^{(k)}(x), \ldots With ``method='step'``, :func:`~mpmath.diffs` uses only `O(k)` function evaluations to generate the first `k` derivatives, rather than the roughly `O(k^2)` evaluations required if one calls :func:`~mpmath.diff` `k` separate times. With `n < \infty`, the generator stops as soon as the `n`-th derivative has been generated. If the exact number of needed derivatives is known in advance, this is further slightly more efficient. Options are the same as for :func:`~mpmath.diff`. **Examples** >>> from mpmath import * >>> mp.dps = 15 >>> nprint(list(diffs(cos, 1, 5))) [0.540302, -0.841471, -0.540302, 0.841471, 0.540302, -0.841471] >>> for i, d in zip(range(6), diffs(cos, 1)): ... print("%s %s" % (i, d)) ... 0 0.54030230586814 1 -0.841470984807897 2 -0.54030230586814 3 0.841470984807897 4 0.54030230586814 5 -0.841470984807897 Nr,r-rrrT)r)rrgffffff?) infrrrBrrr*rrmin)r r!r"r r#rrABcallprecyr(r$r s rdiffsrYsL y GG F{{8V$. !a%i#((1a.g. . FA!a%i {{:&Hhhq!Qh.. A1uCGG|1!A#1 88"31aEWE41 A $#NN1a(472#"HAv #aeAg,1 1I $s+AE!BE9E E*#E EEc0tgfd}|S)Nc|tt|dzD]}jt|SrF)rrPappendnext)rrIdatagens rr!ziterable_to_function..f,s:D 1Q3' #A KKS " #Awr)iter)r_r!r^s` @riterable_to_functionra)s s)C D Hrc#Kt|}|dk(r|dD]}|yt|j|d|dz}t|j||dzd}d} |||dz}d}td|dzD]*} ||| z dzz| z}||||| z z|| zz },||dz }Yw)aV Given a list of `N` iterables or generators yielding `f_k(x), f'_k(x), f''_k(x), \ldots` for `k = 1, \ldots, N`, generate `g(x), g'(x), g''(x), \ldots` where `g(x) = f_1(x) f_2(x) \cdots f_N(x)`. At high precision and for large orders, this is typically more efficient than numerical differentiation if the derivatives of each `f_k(x)` admit direct computation. Note: This function does not increase the working precision internally, so guard digits may have to be added externally for full accuracy. **Examples** >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> f = lambda x: exp(x)*cos(x)*sin(x) >>> u = diffs(f, 1) >>> v = mp.diffs_prod([diffs(exp,1), diffs(cos,1), diffs(sin,1)]) >>> next(u); next(v) 1.23586333600241 1.23586333600241 >>> next(u); next(v) 0.104658952245596 0.104658952245596 >>> next(u); next(v) -5.96999877552086 -5.96999877552086 >>> next(u); next(v) -12.4632923122697 -12.4632923122697 rrNr)rPra diffs_prodr) r factorsNcurAr r ars rrcrc2sH G AAv AG  !A!? @ 1!? @ !qt AAAac] '1QK1$Q1Q3Z!A$&& 'G FAsBc||vr||S|sddi|d<t|dz }tdt|D}i}t|D]+\}}|ddzf|ddz}||vr||xx|z cc<'|||<-t|D]c\}}t|st |D]D\}}|s |d||dz ||dzdzfz||dzdz} | |vr|| xx||zz cc<=||z|| <Fe|||<||S)z nth differentiation polynomial for exp (Faa di Bruno's formula). TODO: most exponents are zero, so maybe a sparse representation would be better. rrrc30K|]\}}|dz|fyw)rjNrG).0rfrAs r zdpoly..ts 2EQqafQZ 2sNr)dpolydict iteritemsrN enumerate) r _cacheRRapowerscountpowers1rppowers2s rrnrnhsG F{ay !Hq  ac A 2Yq\ 22A B"1 !9Q;.6!":- b= wK5 KBwK  #1 * 6{ V$ *CAa !*!F1Q3KM'::VAaCD\Ib=wK1U7*K"#E'BwK  * *F1I !9rc #$Kt||jd}|d} |jd}tt |D].\}}|||j fdt |Dzz }0||z|dz }cw)a Given an iterable or generator yielding `f(x), f'(x), f''(x), \ldots` generate `g(x), g'(x), g''(x), \ldots` where `g(x) = \exp(f(x))`. At high precision and for large orders, this is typically more efficient than numerical differentiation if the derivatives of `f(x)` admit direct computation. Note: This function does not increase the working precision internally, so guard digits may have to be added externally for full accuracy. **Examples** The derivatives of the gamma function can be computed using logarithmic differentiation:: >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> >>> def diffs_loggamma(x): ... yield loggamma(x) ... i = 0 ... while 1: ... yield psi(i,x) ... i += 1 ... >>> u = diffs_exp(diffs_loggamma(3)) >>> v = diffs(gamma, 3) >>> next(u); next(v) 2.0 2.0 >>> next(u); next(v) 1.84556867019693 1.84556867019693 >>> next(u); next(v) 2.49292999190269 2.49292999190269 >>> next(u); next(v) 3.44996501352367 3.44996501352367 rrc3FK|]\}}|s |dz|zyw)rNrG)rlrrxfns rrmzdiffs_exp..s#LEQq!R!WaZLs !!)raexpmpfrprnfprodrq)r fdiffsf0rIr rurfr|s @r diffs_exprsX f %B AB H A GGAJ"58, MIFA 399LYv5FLLL LA M"f  Q sB Bc ttjj|dzd}||z dz fd}j |||j ||z z S)a Calculates the Riemann-Liouville differintegral, or fractional derivative, defined by .. math :: \,_{x_0}{\mathbb{D}}^n_xf(x) = \frac{1}{\Gamma(m-n)} \frac{d^m}{dx^m} \int_{x_0}^{x}(x-t)^{m-n-1}f(t)dt where `f` is a given (presumably well-behaved) function, `x` is the evaluation point, `n` is the order, and `x_0` is the reference point of integration (`m` is an arbitrary parameter selected automatically). With `n = 1`, this is just the standard derivative `f'(x)`; with `n = 2`, the second derivative `f''(x)`, etc. With `n = -1`, it gives `\int_{x_0}^x f(t) dt`, with `n = -2` it gives `\int_{x_0}^x \left( \int_{x_0}^t f(u) du \right) dt`, etc. As `n` is permitted to be any number, this operator generalizes iterated differentiation and iterated integration to a single operator with a continuous order parameter. **Examples** There is an exact formula for the fractional derivative of a monomial `x^p`, which may be used as a reference. For example, the following gives a half-derivative (order 0.5):: >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> x = mpf(3); p = 2; n = 0.5 >>> differint(lambda t: t**p, x, n) 7.81764019044672 >>> gamma(p+1)/gamma(p-n+1) * x**(p-n) 7.81764019044672 Another useful test function is the exponential function, whose integration / differentiation formula easy generalizes to arbitrary order. Here we first compute a third derivative, and then a triply nested integral. (The reference point `x_0` is set to `-\infty` to avoid nonzero endpoint terms.):: >>> differint(lambda x: exp(pi*x), -1.5, 3) 0.278538406900792 >>> exp(pi*-1.5) * pi**3 0.278538406900792 >>> differint(lambda x: exp(pi*x), 3.5, -3, -inf) 1922.50563031149 >>> exp(pi*3.5) / pi**3 1922.50563031149 However, for noninteger `n`, the differentiation formula for the exponential function must be modified to give the same result as the Riemann-Liouville differintegral:: >>> x = mpf(3.5) >>> c = pi >>> n = 1+2*j >>> differint(lambda x: exp(c*x), x, n) (-123295.005390743 + 140955.117867654j) >>> x**(-n) * exp(c)**x * (x*c)**n * gammainc(-n, 0, x*c) / gamma(-n) (-123295.005390743 + 140955.117867654j) rc8jfdgS)Nc&|z z|zSr1rG)r3r!rr"s rz-differint....sacAX!_r)r.)r"r r!rx0s`rrzdifferint..s#((4r1g>r)maxrceilrerBgamma)r r!r"r rmr6rs`` ` @r differintrscH C# $Q &*A !AA>A 88Aq! syy1~ --rc ,dk(rSfd}|S)a3 Given a function `f`, returns a function `g(x)` that evaluates the nth derivative `f^{(n)}(x)`:: >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> cos2 = diffun(sin) >>> sin2 = diffun(sin, 4) >>> cos(1.3), cos2(1.3) (0.267498828624587, 0.267498828624587) >>> sin(1.3), sin2(1.3) (0.963558185417193, 0.963558185417193) The function `f` must support arbitrary precision evaluation. See :func:`~mpmath.diff` for additional details and supported keyword options. rc.j|fiSr1rK)r"r r!r r#s rr6zdiffun..gssxx1a+7++rrG)r r!r r#r6s```` rdiffunr s& Av, Hrc 4t|j|||fi|}|jddr6|Dcgc](\}}|j||j |z *c}}S|Dcgc]\}}||j |z c}}Scc}}wcc}}w)a Produces a degree-`n` Taylor polynomial around the point `x` of the given function `f`. The coefficients are returned as a list. >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> nprint(chop(taylor(sin, 0, 5))) [0.0, 1.0, 0.0, -0.166667, 0.0, 0.00833333] The coefficients are computed using high-order numerical differentiation. The function must be possible to evaluate to arbitrary precision. See :func:`~mpmath.diff` for additional details and supported keyword options. Note that to evaluate the Taylor polynomial as an approximation of `f`, e.g. with :func:`~mpmath.polyval`, the coefficients must be reversed, and the point of the Taylor expansion must be subtracted from the argument: >>> p = taylor(exp, 2.0, 10) >>> polyval(p[::-1], 2.5 - 2.0) 12.1824939606092 >>> exp(2.5) 12.1824939607035 chopT)rqrYrrr<)r r!r"r r#r_rIr s rtaylorr"s8 ICIIaA11 2C{{64 9<=A CMM!,,==/23tq!#--""33>3s -B,Bct|||zdzkr td|dk(r4|dk(r|jg|jgfS|d|dz|jgfS|j|}t |D]2}t t |||zdzD]}|||z|z |||f<4|j||dz||zdz }|j ||}|jgt|z} dg|dzz} t |dzD];}||} t dt ||dzD]}| | ||||z zz } | | |<=| | fS)a Computes a Pade approximation of degree `(L, M)` to a function. Given at least `L+M+1` Taylor coefficients `a` approximating a function `A(x)`, :func:`~mpmath.pade` returns coefficients of polynomials `P, Q` satisfying .. math :: P = \sum_{k=0}^L p_k x^k Q = \sum_{k=0}^M q_k x^k Q_0 = 1 A(x) Q(x) = P(x) + O(x^{L+M+1}) `P(x)/Q(x)` can provide a good approximation to an analytic function beyond the radius of convergence of its Taylor series (example from G.A. Baker 'Essentials of Pade Approximants' Academic Press, Ch.1A):: >>> from mpmath import * >>> mp.dps = 15; mp.pretty = True >>> one = mpf(1) >>> def f(x): ... return sqrt((one + 2*x)/(one + x)) ... >>> a = taylor(f, 0, 6) >>> p, q = pade(a, 3, 3) >>> x = 10 >>> polyval(p[::-1], x)/polyval(q[::-1], x) 1.38169105566806 >>> f(x) 1.38169855941551 rz%L+M+1 Coefficients should be providedrN)rPr=onematrixrOrTlu_solver7) r rhLMrUjrIrAr"qrxr s rpaderDsP 1v!A~@AAAv 6GG9swwi' 'Tac7SWWI% % 1 A 1Xs1ac!e}% A!AhAadG  AqsQqSU$ %%A QA  DGA QqS A 1Q3Z aDq#a(Q,' A 1a!f A !  a4Kr)rr1)rr) libmp.backendrcalculusrrorpAttributeErroritemsrr*rBr9rYrarcrnrrrrrrGrrrs"I  "!HHHT@"GGR 33jB44lF.F.P  044BBB Is A55B B