o
    i|'                     @   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   ZrtolZatolN)r   iv_ratioselfvxr r(   [/home/kim/smarthome/.venv/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-   r5   r(   r(   r)   test_tiny_xX   s   zTestIvRatio.test_tiny_xr   g 7yACr@   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-   r5   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)r3   hypotr   r"   r$   r%   r&   texpectedr(   r(   r)   test_huge_v_x{   s   zTestIvRatio.test_huge_v_xN__name__
__module____qualname__pytestmarkZparametrizer*   r3   infr.   r4   ZfinfofloatZsmallest_normalZsmallest_subnormalr6   maxr;   sqrtrB   rF   rL   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   rZ   r#   r(   r(   r)   r.      r/   zTestIvRatioC.test_infr%   r0   r&   c                 C   r1   r2   )r   rZ   r3   r4   r5   r(   r(   r)   r6      r7   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.r8   rE   r9   Nr[   r:   r(   r(   r)   r;      r<   zTestIvRatioC.test_zero_xr=   r>   r?   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.
        rE   r   Nr[   r5   r(   r(   r)   rB      s    zTestIvRatioC.test_tiny_xrC   rD   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   rX   r   r!   NrY   r5   r(   r(   r)   rF      s   "zTestIvRatioC.test_huge_xrG   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)r3   rH   r   rZ   rI   r(   r(   r)   rL      s   zTestIvRatioC.test_huge_v_xNrM   r(   r(   r(   r)   rW      sJ    






rW   )rQ   numpyr3   Znumpy.testingr   r   Zscipy.special._ufuncsr   r"   r   rZ   r   rW   r(   r(   r(   r)   <module>   s    