o
    	h|'                     @   sP   d dl Z d dlZd dlmZmZ d dlmZm	Z
 G dd dZG dd dZdS )    N)assert_equalassert_allclose)	_iv_ratio_iv_ratio_cc                   @   s  e Zd Zejdg ddd Zejddejdfejddfgdd Z	ejd	d
ej ej
ejgejdeej eej ej ej
ejgdd Zejd	ddeejejgdd Zejddeejfdeejfdeejd fdeejdfeejeeejfgdd Zejdddeeejeejfgdd Zejdeejeejfeejd eejfeejeejd fgdd ZdS )TestIvRatiov,x,r))      ?UUUUUU?g.a0R#?)r   UUUUUU?g<)?)r   r   gVS?)r   UUUUUU?gP]k(?)r   笪?gjD?)   6Z5Z?g&R͒U?)r   窪?gZ?)r   竪?gZr!?)r   ?g4e~u?)r   }|@gG)ȿ?)Q@}P?g1a?)r   j6i?gִN`?)r   :m@g9Ƭ7?)r   5T@g4+?)r   翎H%@gJ]?)EdL@9L;w3@g'~V?)r   ^s!iFE@g/X?)r   SR@g_8?)r   PT`@g )X?)r   >=s@g\h*?c                 C      t t|||ddd dS )a  The reference values are computed using mpmath as follows.

        from mpmath import mp
        mp.dps = 100

        def iv_ratio_mp(v, x):
            return mp.besseli(v, x) / mp.besseli(v - 1, x)

        def _sample(n, *, v):
            '''Return n positive real numbers x such that iv_ratio(v, x) are
            roughly evenly spaced over (0, 1).  The formula is taken from [1].

            [1] Banerjee A., Dhillon, I. S., Ghosh, J., Sra, S. (2005).
                "Clustering on the Unit Hypersphere using von Mises-Fisher
                Distributions."  Journal of Machine Learning Research,
                6(46):1345-1382.
            '''
            r = np.arange(1, n+1) / (n+1)
            return r * (2*v-r*r) / (1-r*r)

        for v in (0.5, 1, 2.34, 56.789):
            xs = _sample(5, v=v)
            for x in xs:
                print(f"({v}, {x}, {float(iv_ratio_mp(v,x))}),")
        缉ؗҼ<r   rtolatolN)r   iv_ratioselfvxr r*   U/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/special/tests/test_iv_ratio.pytest_against_reference_values   s   0z)TestIvRatio.test_against_reference_valuesr   r   c                 C      t t||| dS ziIf exactly one of v or x is inf and the other is within domain,
        should return 0 or 1 accordingly.Nr   r$   r%   r*   r*   r+   test_inf@      zTestIvRatio.test_infr'   \(\?r(   c                 C      t t||tj dS zeIf at least one argument is out of domain, or if v = x = inf,
        the function should return nan.N)r   r$   npnanr&   r'   r(   r*   r*   r+   test_nanI      zTestIvRatio.test_nanr   c                 C   s$   t t|dd t t|dd dS )z?If x is +/-0.0, return x to ensure iv_ratio is an odd function.               Nr/   r&   r'   r*   r*   r+   test_zero_xR      zTestIvRatio.test_zero_xv,x   @xD{   c                 C   s   t t||d| |  dS )a9  If x is much less than v, the bounds

                    x                                 x
        --------------------------- <= R <= -----------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-1+sqrt(x**2+(v+1)**2)

        collapses to R ~= x/2v.  Test against this asymptotic expression.
        r   Nr/   r7   r*   r*   r+   test_tiny_xX   s   zTestIvRatio.test_tiny_xr   g 7yACrB   g\)c=Hc                 C   s   t t||d dS )aA  If x is much greater than v, the bounds

                    x                                 x
        --------------------------- <= R <= ---------------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-0.5+sqrt(x**2+(v-0.5)**2)

        collapses to R ~= 1.  Test against this asymptotic expression.
              ?Nr/   r7   r*   r*   r+   test_huge_xk   s   zTestIvRatio.test_huge_x   c                 C   s6   || }|dt d|  }tt|||ddd dS )a  If both x and v are very large, the bounds

                    x                                 x
        --------------------------- <= R <= -----------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-1+sqrt(x**2+(v+1)**2)

        collapses to R ~= x/(v+sqrt(x**2+v**2).  Test against this asymptotic
        expression, and in particular that no numerical overflow occurs during
        intermediate calculations.
        r   r    r   r!   N)r5   hypotr   r$   r&   r'   r(   texpectedr*   r*   r+   test_huge_v_x{   s   zTestIvRatio.test_huge_v_xN__name__
__module____qualname__pytestmarkparametrizer,   r5   infr0   r6   finfofloatsmallest_normalsmallest_subnormalr8   maxr=   sqrtrD   rH   rN   r*   r*   r*   r+   r      sJ    






r   c                   @   s  e Zd Zejdg ddd Zejddejdfejddfgdd Z	ejd	d
ej ej
ejgejdeej eej ej ej
ejgdd Zejd	ddeejejgdd Zejddeejfdeejfdeejd fdeejdfeejeeejfgdd Zejdddeeejeejfgdd Zejdeejeejfeejd eejfeejeejd fgdd ZdS )TestIvRatioCr   ))r   r	   g{s+?)r   r
   ga*?)r   r   gTV6?)r   r   g`D)?)r   r   g,wU?)r   r   gvL[?)r   r   g>7R?)r   r   gL?)r   r   g5?)r   r   gZ ?)r   r   g3zʈ?)r   r   gؤO??)r   r   gsF?)r   r   g1?)r   r   gL9Ԋ?)r   r   gCv`?)r   r   g
-S?)r   r   g@ɣ?)r   r   gO?)r   r   g^VO?c                 C   r   )z8The reference values are one minus those of TestIvRatio.V瞯<r   r!   Nr   
iv_ratio_cr%   r*   r*   r+   r,      s   z*TestIvRatioC.test_against_reference_valuesr   r   c                 C   r-   r.   r   r`   r%   r*   r*   r+   r0      r1   zTestIvRatioC.test_infr'   r2   r(   c                 C   r3   r4   )r   r`   r5   r6   r7   r*   r*   r+   r8      r9   zTestIvRatioC.test_nanr   c                 C   s$   t t|dd t t|dd dS )zIf x is +/-0.0, return 1.r:   rG   r;   Nra   r<   r*   r*   r+   r=      r>   zTestIvRatioC.test_zero_xr?   r@   rA   c                 C   s    t t||dd| |   dS )a=  If x is much less than v, the bounds

                    x                                 x
        --------------------------- <= R <= -----------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-1+sqrt(x**2+(v+1)**2)

        collapses to 1-R ~= 1-x/2v.  Test against this asymptotic expression.
        rG   r   Nra   r7   r*   r*   r+   rD      s    zTestIvRatioC.test_tiny_xrE   rF   c                 C   s"   t t|||d | ddd dS )aK  If x is much greater than v, the bounds

                    x                                 x
        --------------------------- <= R <= ---------------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-0.5+sqrt(x**2+(v-0.5)**2)

        collapses to 1-R ~= (v-0.5)/x.  Test against this asymptotic expression.
        r   r^   r   r!   Nr_   r7   r*   r*   r+   rH      s   "zTestIvRatioC.test_huge_xrI   c                 C   s:   || }d|dt d|   }tt|||ddd dS )a  If both x and v are very large, the bounds

                    x                                 x
        --------------------------- <= R <= -----------------------
        v-0.5+sqrt(x**2+(v+0.5)**2)         v-1+sqrt(x**2+(v+1)**2)

        collapses to 1 - R ~= 1 - x/(v+sqrt(x**2+v**2).  Test against this
        asymptotic expression, and in particular that no numerical overflow
        occurs during intermediate calculations.
        r   r    r   r!   N)r5   rJ   r   r`   rK   r*   r*   r+   rN      s   zTestIvRatioC.test_huge_v_xNrO   r*   r*   r*   r+   r]      sJ    






r]   )rS   numpyr5   numpy.testingr   r   scipy.special._ufuncsr   r$   r   r`   r   r]   r*   r*   r*   r+   <module>   s    