jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def test_1(self):
        expect = (
            -1j
            * ssc.spherical_jn(2, 4 + 1j)
            * np.sqrt(15 / (2 * 3 * 8 * np.pi))
            * np.exp(1j)
            * np.array([0, 1j * np.cos(2), -np.cos(4)])
        )
        assert np.sum(np.abs(sc.vsw_rM(2, 1, 4 + 1j, 2, 1) - expect)) < EPS
//  [python]
def _get_tnl(l, w):
    r"""Fourier integral of the l-th Legendre polynomial:

        T_l(w) = \int_{-1}^1 dx \exp(iwx) P_l(x)
    """
    i_pow_l = _imag_power(l)
    return 2 * numpy.where(
        w >= 0,
        i_pow_l * s.spherical_jn(l, w),
        (i_pow_l * s.spherical_jn(l, -w)).conj(),
        )
//  [python]
def _get_tnl(l, w):
    r"""Fourier integral of the l-th Legendre polynomial:

        T_l(w) = \int_{-1}^1 dx \exp(iwx) P_l(x)
    """
    i_pow_l = _imag_power(l)
    return 2 * numpy.where(
        w >= 0,
        i_pow_l * scipy.special.spherical_jn(l, w),
        (i_pow_l * scipy.special.spherical_jn(l, -w)).conj(),
        )
//  [python]
def _get_tnl(l, w):
    r"""Fourier integral of the l-th Legendre polynomial::

        T_l(w) == \int_{-1}^1 dx \exp(iwx) P_l(x)
    """
    # spherical_jn gives NaN for w < 0, but since we know that P_l(x) is real,
    # we simply conjugate the result for w > 0 in these cases.
    result = 2 * _imag_power(l) * s.spherical_jn(l, np.abs(w))
    np.conjugate(result, out=result, where=w < 0)
    return result
//  [python]
def _get_tnl(l, w):
    r"""Fourier integral of the l-th Legendre polynomial::

        T_l(w) == \int_{-1}^1 dx \exp(iwx) P_l(x)
    """
    # spherical_jn gives NaN for w < 0, but since we know that P_l(x) is real,
    # we simply conjugate the result for w > 0 in these cases.
    result = 2 * _imag_power(l) * sp_special.spherical_jn(l, np.abs(w))
    np.conjugate(result, out=result, where=w < 0)
    return result
//  [python]
def test_1(self):
        expect = (
            -1j
            * np.sqrt(5 / (16 * np.pi))
            * np.exp(1j)
            * np.array(
                [
                    6 * s.spherical_jn(2, 4 + 1j) / (4 + 1j) * np.sin(2) * np.cos(2),
                    np.cos(4)
                    * (
                        s.spherical_jn(2, 4 + 1j, 1)
                        + s.spherical_jn(2, 4 + 1j) / (4 + 1j)
                    ),
                    1j
                    * np.cos(2)
                    * (
                        s.spherical_jn(2, 4 + 1j, 1)
                        + s.spherical_jn(2, 4 + 1j) / (4 + 1j)
                    ),
                ]
            )
        )
        assert np.sum(np.abs(sc.vsw_rN(2, 1, 4 + 1j, 2, 1) - expect)) < EPS
//  [python]
def test_1(self):
        expect = (
            -1j
            * np.sqrt(5 / (16 * np.pi))
            * np.exp(1j)
            * np.array(
                [
                    6 * ssc.spherical_jn(2, 4 + 1j) / (4 + 1j) * np.sin(2) * np.cos(2),
                    np.cos(4)
                    * (
                        ssc.spherical_jn(2, 4 + 1j, 1)
                        + ssc.spherical_jn(2, 4 + 1j) / (4 + 1j)
                    ),
                    1j
                    * np.cos(2)
                    * (
                        ssc.spherical_jn(2, 4 + 1j, 1)
                        + ssc.spherical_jn(2, 4 + 1j) / (4 + 1j)
                    ),
                ]
            )
        )
        assert np.sum(np.abs(sc.vsw_rN(2, 1, 4 + 1j, 2, 1) - expect)) < EPS
//  [python]
def test_spherical_bessel_j():
    if NumCpp.NUMCPP_NO_USE_BOOST and not NumCpp.STL_SPECIAL_FUNCTIONS:
        return

    order = np.random.randint(0, 10)
    value = np.random.rand(1).item()
    assert roundScalar(NumCpp.spherical_bessel_jn_Scalar(order, value), NUM_DECIMALS_ROUND) == roundScalar(
        s.spherical_jn(order, value).item(), NUM_DECIMALS_ROUND
    )

    shapeInput = np.random.randint(
        20,
        100,
        [
            2,
        ],
    )
    shape = NumCpp.Shape(shapeInput[0].item(), shapeInput[1].item())
    cArray = NumCpp.NdArray(shape)
    order = np.random.randint(0, 10)
    data = np.random.rand(shape.rows, shape.cols)
    cArray.setArray(data)
    assert np.array_equal(
        roundArray(NumCpp.spherical_bessel_jn_Array(order, cArray), NUM_DECIMALS_ROUND),
        roundArray(s.spherical_jn(order, data), NUM_DECIMALS_ROUND),
    )
//  [python]
def test_spherical_bessel_j():
    if NumCpp.NUMCPP_NO_USE_BOOST and not NumCpp.STL_SPECIAL_FUNCTIONS:
        return

    order = np.random.randint(0, 10)
    value = np.random.rand(1).item()
    assert roundScalar(NumCpp.spherical_bessel_jn_Scalar(order, value), NUM_DECIMALS_ROUND) == roundScalar(
        sp.spherical_jn(order, value).item(), NUM_DECIMALS_ROUND
    )

    shapeInput = np.random.randint(
        20,
        100,
        [
            2,
        ],
    )
    shape = NumCpp.Shape(shapeInput[0].item(), shapeInput[1].item())
    cArray = NumCpp.NdArray(shape)
    order = np.random.randint(0, 10)
    data = np.random.rand(shape.rows, shape.cols)
    cArray.setArray(data)
    assert np.array_equal(
        roundArray(NumCpp.spherical_bessel_jn_Array(order, cArray), NUM_DECIMALS_ROUND),
        roundArray(sp.spherical_jn(order, data), NUM_DECIMALS_ROUND),
    )
//  [python]
def spherical_hn(n, k, z):
    """nth-order sphericah Henkel function of kth kind
    Returns h_n^(k)(z)
    """
    if k == 1:
        return s.spherical_jn(n, z) + 1j * s.spherical_yn(n, z)
    elif k == 2:
        return s.spherical_jn(n, z) - 1j * s.spherical_yn(n, z)
    else:
        raise ValueError()
//  [python]
def spherical_hn(n, k, z):
    """nth-order sphericah Henkel function of kth kind
    Returns h_n^(k)(z)
    """
    if k == 1:
        return special.spherical_jn(n, z) + 1j * special.spherical_yn(n, z)
    elif k == 2:
        return special.spherical_jn(n, z) - 1j * special.spherical_yn(n, z)
    else:
        raise ValueError()
//  [python]
def jl(l, z):
    """A fast spherical bessel function using approximations at low and high z.

    Parameters
    ----------
    l, z : scalar or np.ndarray
        Spherical bessel function arguments.

    Returns
    -------
    jl : scalar or np.ndarray
        Spherical bessel functions.
    """

    lt = l
    zt = z

    l = np.atleast_1d(l)
    z = np.atleast_1d(z)

    zca = np.logical_and(z == 0.0, l > 0)
    zza = np.where(zca)
    lca = np.logical_and(
        np.logical_or(np.logical_and(l > 20, z < (l / 5.0)), z < (l * 1e-6)), z > 0.0
    )
    lza = np.where(lca)
    hca = np.logical_and(l > 20, z > 10.0 * l)
    hza = np.where(hca)
    gza = np.where(np.logical_not(np.logical_or(np.logical_or(lca, hca), zca)))
    la, za = np.broadcast_arrays(l, z)

    jla = np.empty_like(la).astype(np.float64)

    jla[zza] = 0.0
    jla[lza] = _jl_approx_lowz(la[lza], za[lza])
    jla[hza] = _jl_approx_highz(la[hza], za[hza])
    jla[gza] = s.spherical_jn(la[gza], za[gza])

    if isinstance(lt, np.ndarray) or isinstance(zt, np.ndarray):
        return jla
    else:
        return jla[0]
//  [python]
def jl(l, z):
    """A fast spherical bessel function using approximations at low and high z.

    Parameters
    ----------
    l, z : scalar or np.ndarray
        Spherical bessel function arguments.

    Returns
    -------
    jl : scalar or np.ndarray
        Spherical bessel functions.
    """

    lt = l
    zt = z

    l = np.atleast_1d(l)
    z = np.atleast_1d(z)

    zca = np.logical_and(z == 0.0, l > 0)
    zza = np.where(zca)
    lca = np.logical_and(
        np.logical_or(np.logical_and(l > 20, z < (l / 5.0)), z < (l * 1e-6)), z > 0.0
    )
    lza = np.where(lca)
    hca = np.logical_and(l > 20, z > 10.0 * l)
    hza = np.where(hca)
    gza = np.where(np.logical_not(np.logical_or(np.logical_or(lca, hca), zca)))
    la, za = np.broadcast_arrays(l, z)

    jla = np.empty_like(la).astype(np.float64)

    jla[zza] = 0.0
    jla[lza] = _jl_approx_lowz(la[lza], za[lza])
    jla[hza] = _jl_approx_highz(la[hza], za[hza])
    jla[gza] = ss.spherical_jn(la[gza], za[gza])

    if isinstance(lt, np.ndarray) or isinstance(zt, np.ndarray):
        return jla
    else:
        return jla[0]
//  [python]
def sf_int_basis3d(n, m, x, y, z, k):
    """Spherical wavefunction for interior sound field in 3D
    
    Parameters
    ------
    n, m: orders and degrees
    x, y, z: Position in Cartesian coordinates
    k: Wavenumber

    Returns
    ------
    sqrt(4pi) j_n(kr) Y_n^m(phi,theta)
    (Normalized so that 0th order coefficient corresponds to pressure)
    """
    phi, theta, r = cart2sph(x, y, z)
    J = s.spherical_jn(n, k * r)
    Y = sph_harm(m, n, phi, theta)
    f = np.sqrt(4*np.pi) * J * Y
    return f
//  [python]
def sf_int_basis3d(n, m, x, y, z, k):
    """Spherical wavefunction for interior sound field in 3D
    
    Parameters
    ------
    n, m: orders and degrees
    x, y, z: Position in Cartesian coordinates
    k: Wavenumber

    Returns
    ------
    sqrt(4pi) j_n(kr) Y_n^m(phi,theta)
    (Normalized so that 0th order coefficient corresponds to pressure)
    """
    phi, theta, r = cart2sph(x, y, z)
    J = special.spherical_jn(n, k * r)
    Y = sph_harm(m, n, phi, theta)
    f = np.sqrt(4*np.pi) * J * Y
    return f
//  [python]
def weightKernel(k, posMic):
    """Integrand for weighted pressure matching
    """
    def integralFunc(r):
        distance = np.transpose(distfuncs.cdist(r, posMic[:,0:2]), (1, 0))[None,:,:]
        kappa = s.spherical_jn(0, k[:,None,None] * distance) 
        funcVal = kappa[:, :, None, :].conj() * kappa[:, None, :, :]
        return funcVal
    return integralFunc
//  [python]
def weightKernel(k, posMic):
    """Integrand for weighted pressure matching
    """
    def integralFunc(r):
        distance = np.transpose(distfuncs.cdist(r, posMic[:,0:2]), (1, 0))[None,:,:]
        kappa = special.spherical_jn(0, k[:,None,None] * distance) 
        funcVal = kappa[:, :, None, :].conj() * kappa[:, None, :, :]
        return funcVal
    return integralFunc
//  [python]
def weightWPM(k, posMic, mcNumPoints, dimsEval, reg=1e-3):
    """Weighting matrix of weighted pressure-matching method for sound field synthesis
    - S. Koyama, K. Kimura, and N. Ueno, “Weighted Pressure and Mode Matching for Sound Field 
      Reproduction: Theoretical and Experimental Comparisons,” J. AES, DOI: 10.17743/jaes.2022.0058, 2023.
    """
    mcPointGen, mcVolume = mcBlockRect([dimsEval[0], dimsEval[1]], np.random.RandomState(2))
    func = weightKernel(k, posMic)
    integralVal = mcIntegrate(func, mcPointGen, mcNumPoints, mcVolume)

    # Uniform kernel
    numMic = posMic.shape[0]
    distMat = distfuncs.cdist(posMic, posMic)[None, :, :]
    K = s.spherical_jn(0, k[:,None,None] * distMat)

    eigK, _ = np.linalg.eig(K)
    regKer =  eigK[:,0] * reg
    K_inv = np.linalg.inv(K + regKer[:,None,None] * np.eye(numMic)[None,:,:])
    W = np.transpose(K_inv.conj(), (0,2,1)) @ integralVal @ K_inv
    return W
//  [python]
def weightWPM(k, posMic, mcNumPoints, dimsEval, reg=1e-3):
    """Weighting matrix of weighted pressure-matching method for sound field synthesis
    - S. Koyama, K. Kimura, and N. Ueno, “Weighted Pressure and Mode Matching for Sound Field 
      Reproduction: Theoretical and Experimental Comparisons,” J. AES, DOI: 10.17743/jaes.2022.0058, 2023.
    """
    mcPointGen, mcVolume = mcBlockRect([dimsEval[0], dimsEval[1]], np.random.RandomState(2))
    func = weightKernel(k, posMic)
    integralVal = mcIntegrate(func, mcPointGen, mcNumPoints, mcVolume)

    # Uniform kernel
    numMic = posMic.shape[0]
    distMat = distfuncs.cdist(posMic, posMic)[None, :, :]
    K = special.spherical_jn(0, k[:,None,None] * distMat)

    eigK, _ = np.linalg.eig(K)
    regKer =  eigK[:,0] * reg
    K_inv = np.linalg.inv(K + regKer[:,None,None] * np.eye(numMic)[None,:,:])
    W = np.transpose(K_inv.conj(), (0,2,1)) @ integralVal @ K_inv
    return W
//  [python]
def kiFilterGen(k, posMic, posEst, filterLen=None, smplShift=None):
    """Kernel interpolation filter for estimating pressure distribution from measurements
    - N. Ueno, S. Koyama, and H. Saruwatari, “Kernel Ridge Regression With Constraint of Helmholtz Equation 
      for Sound Field Interpolation,” Proc. IWAENC, DOI: 10.1109/IWAENC.2018.8521334, 2018.
    - N. Ueno, S. Koyama, and H. Saruwatari, “Sound Field Recording Using Distributed Microphones Based on 
      Harmonic Analysis of Infinite Order,” IEEE SPL, DOI: 10.1109/LSP.2017.2775242, 2018.
    """
    numMic = posMic.shape[0]
    numEst = posEst.shape[0]
    numFreq = k.shape[0]
    fftlen = numFreq*2
    reg = 1e-3

    if filterLen is None:
        filterLen = numFreq+1
    if smplShift is None:
        smplShift = numFreq/2

    k = k[:, None, None]
    distMat = distfuncs.cdist(posMic, posMic)[None, :, :]
    K = s.spherical_jn(0, k * distMat)
    Kinv = np.linalg.inv(K + reg * np.eye(numMic)[None, :, :])
    distVec = np.transpose(distfuncs.cdist(posEst, posMic), (1, 0))[None, :, :]
    kappa = s.spherical_jn(0, k * distVec)
    kiTF = np.transpose(kappa, (0, 2, 1)) @ Kinv
    kiTF = np.concatenate((np.zeros((1, numEst, numMic)), kiTF, kiTF[int(fftlen/2)-2::-1, :, :].conj()))
    kiFilter = np.fft.ifft(kiTF, n=fftlen, axis=0).real
    kiFilter = np.concatenate((kiFilter[fftlen-smplShift:fftlen, :, :], kiFilter[:filterLen-smplShift, :, :]))

    return kiFilter
//  [python]
def kiFilterGen(k, posMic, posEst, filterLen=None, smplShift=None):
    """Kernel interpolation filter for estimating pressure distribution from measurements
    - N. Ueno, S. Koyama, and H. Saruwatari, “Kernel Ridge Regression With Constraint of Helmholtz Equation 
      for Sound Field Interpolation,” Proc. IWAENC, DOI: 10.1109/IWAENC.2018.8521334, 2018.
    - N. Ueno, S. Koyama, and H. Saruwatari, “Sound Field Recording Using Distributed Microphones Based on 
      Harmonic Analysis of Infinite Order,” IEEE SPL, DOI: 10.1109/LSP.2017.2775242, 2018.
    """
    numMic = posMic.shape[0]
    numEst = posEst.shape[0]
    numFreq = k.shape[0]
    fftlen = numFreq*2
    reg = 1e-3

    if filterLen is None:
        filterLen = numFreq+1
    if smplShift is None:
        smplShift = numFreq/2

    k = k[:, None, None]
    distMat = distfuncs.cdist(posMic, posMic)[None, :, :]
    K = special.spherical_jn(0, k * distMat)
    Kinv = np.linalg.inv(K + reg * np.eye(numMic)[None, :, :])
    distVec = np.transpose(distfuncs.cdist(posEst, posMic), (1, 0))[None, :, :]
    kappa = special.spherical_jn(0, k * distVec)
    kiTF = np.transpose(kappa, (0, 2, 1)) @ Kinv
    kiTF = np.concatenate((np.zeros((1, numEst, numMic)), kiTF, kiTF[int(fftlen/2)-2::-1, :, :].conj()))
    kiFilter = np.fft.ifft(kiTF, n=fftlen, axis=0).real
    kiFilter = np.concatenate((kiFilter[fftlen-smplShift:fftlen, :, :], kiFilter[:filterLen-smplShift, :, :]))

    return kiFilter
//  [python]
def pressure_release_sphere_simple(f,a,c):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    
    n = np.arange(0,round(ka+20,0)).astype(int)
    A_fun = lambda x: - s.spherical_jn(x,ka) / sphericalHankel(x,ka)
    A = list(map(A_fun,n))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def pressure_release_sphere_simple(f,a,c):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    
    n = np.arange(0,round(ka+20,0)).astype(int)
    A_fun = lambda x: - ss.spherical_jn(x,ka) / sphericalHankel(x,ka)
    A = list(map(A_fun,n))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def set_power_direct(self, power_direct_nonorm=None, **kwargs):
        """
        Set direct power spectrum.

        Parameters
        ----------
        power_direct_nonorm : array, default=None
            Direct estimation of power spectrum to be stored in :attr:`power_direct_nonorm`.

        **kwargs : dict
            ``corr_direct_nonorm`` and ``sep_direct`` can be provided, in which case
            :attr:`power_direct_nonorm` is computed as the Bessel transform of ``corr_direct_nonorm``.
        """
        for name in ['corr_direct_nonorm', 'sep_direct']:
            value = kwargs.get(name, None)
            if value is not None:
                setattr(self, name, np.asarray(value))
        if power_direct_nonorm is not None:
            self.power_direct_nonorm = np.asarray(power_direct_nonorm)
        elif self.corr_direct_nonorm is not None:
            _slab_npoints_max = 1000 * 1000
            nslabs = min(max(len(self.k) * len(self.sep_direct) // _slab_npoints_max, 1), len(self.k))
            power_nonorm = []
            for ill, ell in enumerate(self.ells):
                tmp = []
                for islab in range(nslabs):
                    sl = slice(islab * len(self.k) // nslabs, (islab + 1) * len(self.k) // nslabs)
                    tmp.append((-1j)**ell * np.sum(self.corr_direct_nonorm[ill] * s.spherical_jn(ell, self.k[sl, None] * self.sep_direct, derivative=False), axis=-1))
                power_nonorm.append(np.concatenate(tmp, axis=0))
            self.power_direct_nonorm = np.array(power_nonorm)
//  [python]
def set_power_direct(self, power_direct_nonorm=None, **kwargs):
        """
        Set direct power spectrum.

        Parameters
        ----------
        power_direct_nonorm : array, default=None
            Direct estimation of power spectrum to be stored in :attr:`power_direct_nonorm`.

        **kwargs : dict
            ``corr_direct_nonorm`` and ``sep_direct`` can be provided, in which case
            :attr:`power_direct_nonorm` is computed as the Bessel transform of ``corr_direct_nonorm``.
        """
        for name in ['corr_direct_nonorm', 'sep_direct']:
            value = kwargs.get(name, None)
            if value is not None:
                setattr(self, name, np.asarray(value))
        if power_direct_nonorm is not None:
            self.power_direct_nonorm = np.asarray(power_direct_nonorm)
        elif self.corr_direct_nonorm is not None:
            _slab_npoints_max = 1000 * 1000
            nslabs = min(max(len(self.k) * len(self.sep_direct) // _slab_npoints_max, 1), len(self.k))
            power_nonorm = []
            for ill, ell in enumerate(self.ells):
                tmp = []
                for islab in range(nslabs):
                    sl = slice(islab * len(self.k) // nslabs, (islab + 1) * len(self.k) // nslabs)
                    tmp.append((-1j)**ell * np.sum(self.corr_direct_nonorm[ill] * special.spherical_jn(ell, self.k[sl, None] * self.sep_direct, derivative=False), axis=-1))
                power_nonorm.append(np.concatenate(tmp, axis=0))
            self.power_direct_nonorm = np.array(power_nonorm)
//  [python]
def fluid_sphere_simple(f,r,a,c,h,g):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    
    #Internal fluid
    k1 = k(h*c,f) #Wavenumber internal fluid
    k1a = k1 * a  #Wavenumber internal fluid * radius
    #rho1 <- g *rho #density internal fluid
    Cn_fun = lambda x:((s.spherical_jn(x, k1a, derivative=True) * s.spherical_yn(x, ka))\
                       /(s.spherical_jn(x,k1a) * s.spherical_jn(x,ka,  derivative=True))\
                       - g * h * (s.spherical_yn(x,ka, derivative=True) \
                                  / s.spherical_jn(x,ka, derivative=True))) \
                       /((s.spherical_jn(x,k1a, derivative=True) * s.spherical_jn(x,ka))\
                         /(s.spherical_jn(x,k1a) * s.spherical_jn(x,ka, derivative=True))\
                         - g * h)
    n = np.arange(0,round(ka+20,0)).astype(int)
    Cn = list(map(Cn_fun,n))
    A = -1 / (1 + 1j * np.asarray(Cn))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def fluid_sphere_simple(f,r,a,c,h,g):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    
    #Internal fluid
    k1 = k(h*c,f) #Wavenumber internal fluid
    k1a = k1 * a  #Wavenumber internal fluid * radius
    #rho1 <- g *rho #density internal fluid
    Cn_fun = lambda x:((ss.spherical_jn(x, k1a, derivative=True) * ss.spherical_yn(x, ka))\
                       /(ss.spherical_jn(x,k1a) * ss.spherical_jn(x,ka,  derivative=True))\
                       - g * h * (ss.spherical_yn(x,ka, derivative=True) \
                                  / ss.spherical_jn(x,ka, derivative=True))) \
                       /((ss.spherical_jn(x,k1a, derivative=True) * ss.spherical_jn(x,ka))\
                         /(ss.spherical_jn(x,k1a) * ss.spherical_jn(x,ka, derivative=True))\
                         - g * h)
    n = np.arange(0,round(ka+20,0)).astype(int)
    Cn = list(map(Cn_fun,n))
    A = -1 / (1 + 1j * np.asarray(Cn))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def compute(
        self, n: int, ell: int, integrand_positions: Union[float, np.ndarray]
    ) -> Union[float, np.ndarray]:
        return s.spherical_jn(
            ell,
            integrand_positions * self.roots[ell, n] / self.integration_radius,
        )
//  [python]
def compute(
        self, n: int, ell: int, integrand_positions: Union[float, np.ndarray]
    ) -> Union[float, np.ndarray]:
        return scipy.special.spherical_jn(
            ell,
            integrand_positions * self.roots[ell, n] / self.integration_radius,
        )
//  [python]
def kiFilterGenDir(k, posMic, posEst, angSrc, betaSrc, filterLen=None, smplShift=None):
    """Kernel interpolation filter with directional weighting for estimating pressure distribution from measurements
    - N. Ueno, S. Koyama, and H. Saruwatari, “Directionally Weighted Wave Field Estimation Exploiting Prior 
      Information on Source Direction,” IEEE Trans. SP, DOI: 10.1109/TSP.2021.3070228, 2021.
    """
    numMic = posMic.shape[0]
    numEst = posEst.shape[0]
    numFreq = k.shape[0]
    fftlen = numFreq*2
    reg = 1e-3

    if filterLen is None:
        filterLen = numFreq+1
    if smplShift is None:
        smplShift = int(numFreq/2)

    thetaSrc = angSrc[0]
    phiSrc = angSrc[1]

    k = k[:, None, None]
    rDiffMat = (np.tile(posMic[:, None, :], (1, numMic, 1)) - np.tile(posMic[None, :, :], (numMic, 1, 1)))[None, :, :, :]
    distMat = np.sqrt((1j*betaSrc*np.sin(thetaSrc)*np.cos(phiSrc) - k*rDiffMat[:, :, :, 0])**2 + (1j*betaSrc*np.sin(thetaSrc)*np.sin(phiSrc) - k*rDiffMat[:, :, :, 1])**2 + (1j*betaSrc*np.cos(thetaSrc) - k*rDiffMat[:, :, :, 2])**2)
    K = s.spherical_jn(0, distMat)
    Kinv = np.linalg.inv(K + reg * np.eye(numMic)[None, :, :])
    rDiffVec = (np.tile(posEst[None, :, :], (numMic, 1, 1)) - np.tile(posMic[:, None, :], (1, numEst, 1)))[None, :, :, :]
    distVec = np.sqrt((1j*betaSrc*np.sin(thetaSrc)*np.cos(phiSrc) - k*rDiffVec[:, :, :, 0])**2 + (1j*betaSrc*np.sin(thetaSrc)*np.sin(phiSrc) - k*rDiffVec[:, :, :, 1])**2 + (1j*betaSrc*np.cos(thetaSrc) - k*rDiffVec[:, :, :, 2])**2)
    kappa = s.spherical_jn(0, distVec)
    kiTF = np.transpose(kappa, (0, 2, 1)) @ Kinv
    kiTF = np.concatenate((np.zeros((1, numEst, numMic)), kiTF, kiTF[int(fftlen/2)-2::-1, :, :].conj()))
    kiFilter = np.fft.ifft(kiTF, n=fftlen, axis=0).real
    kiFilter = np.concatenate((kiFilter[fftlen-smplShift:fftlen, :, :], kiFilter[:filterLen-smplShift, :, :]))

    return kiFilter
//  [python]
def kiFilterGenDir(k, posMic, posEst, angSrc, betaSrc, filterLen=None, smplShift=None):
    """Kernel interpolation filter with directional weighting for estimating pressure distribution from measurements
    - N. Ueno, S. Koyama, and H. Saruwatari, “Directionally Weighted Wave Field Estimation Exploiting Prior 
      Information on Source Direction,” IEEE Trans. SP, DOI: 10.1109/TSP.2021.3070228, 2021.
    """
    numMic = posMic.shape[0]
    numEst = posEst.shape[0]
    numFreq = k.shape[0]
    fftlen = numFreq*2
    reg = 1e-3

    if filterLen is None:
        filterLen = numFreq+1
    if smplShift is None:
        smplShift = int(numFreq/2)

    thetaSrc = angSrc[0]
    phiSrc = angSrc[1]

    k = k[:, None, None]
    rDiffMat = (np.tile(posMic[:, None, :], (1, numMic, 1)) - np.tile(posMic[None, :, :], (numMic, 1, 1)))[None, :, :, :]
    distMat = np.sqrt((1j*betaSrc*np.sin(thetaSrc)*np.cos(phiSrc) - k*rDiffMat[:, :, :, 0])**2 + (1j*betaSrc*np.sin(thetaSrc)*np.sin(phiSrc) - k*rDiffMat[:, :, :, 1])**2 + (1j*betaSrc*np.cos(thetaSrc) - k*rDiffMat[:, :, :, 2])**2)
    K = special.spherical_jn(0, distMat)
    Kinv = np.linalg.inv(K + reg * np.eye(numMic)[None, :, :])
    rDiffVec = (np.tile(posEst[None, :, :], (numMic, 1, 1)) - np.tile(posMic[:, None, :], (1, numEst, 1)))[None, :, :, :]
    distVec = np.sqrt((1j*betaSrc*np.sin(thetaSrc)*np.cos(phiSrc) - k*rDiffVec[:, :, :, 0])**2 + (1j*betaSrc*np.sin(thetaSrc)*np.sin(phiSrc) - k*rDiffVec[:, :, :, 1])**2 + (1j*betaSrc*np.cos(thetaSrc) - k*rDiffVec[:, :, :, 2])**2)
    kappa = special.spherical_jn(0, distVec)
    kiTF = np.transpose(kappa, (0, 2, 1)) @ Kinv
    kiTF = np.concatenate((np.zeros((1, numEst, numMic)), kiTF, kiTF[int(fftlen/2)-2::-1, :, :].conj()))
    kiFilter = np.fft.ifft(kiTF, n=fftlen, axis=0).real
    kiFilter = np.concatenate((kiFilter[fftlen-smplShift:fftlen, :, :], kiFilter[:filterLen-smplShift, :, :]))

    return kiFilter
//  [python]
def compute_derivative(
        self, n: int, ell: int, integrand_positions: Union[float, np.ndarray]
    ) -> Union[float, np.ndarray]:
        return (
            self.roots[ell, n]
            / self.integration_radius
            * scipy.special.spherical_jn(
                ell,
                integrand_positions * self.roots[ell, n] / self.integration_radius,
                derivative=True,
            )
        )
//  [python]
def rigid_sphere_simple(f,a,c):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    n = np.arange(0,round(ka+20,0)).astype(int)
    A_fun = lambda x: - s.spherical_jn(x, ka, derivative = True) / \
    sphericalHankel_deriv(x, ka)
    A = list(map(A_fun,n))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def rigid_sphere_simple(f,a,c):
    #External fluid
    k0 = k(c,f) #Wavenumber surrounding fluid
    ka = k0 * a #Wavenumber surrounding fluid * radius
    n = np.arange(0,round(ka+20,0)).astype(int)
    A_fun = lambda x: - ss.spherical_jn(x, ka, derivative = True) / \
    sphericalHankel_deriv(x, ka)
    A = list(map(A_fun,n))
    fbs = -1j / k0 * np.sum((-1)**n * (2*n +1) * A)
    TS = 10 * np.log10(abs(fbs)**2)
    return(TS)
//  [python]
def test_riccati_yn(self):
        ynrl = (special.sph_yn(1,.2)[0]*.2,special.sph_yn(1,.2)[0]+special.sph_yn(1,.2)[1]*.2)
        ricyn = special.riccati_yn(1,.2)
        assert_array_almost_equal(ricyn,ynrl,8)
//  [python]
def test_riccati_yn(self):
        ynrl = (special.spherical_yn(1,.2)[0]*.2,special.spherical_yn(1,.2)[0]+special.spherical_yn(1,.2)[1]*.2)
        ricyn = special.riccati_yn(1,.2)
        assert_array_almost_equal(ricyn,ynrl,8)
//  [python]
def sph_yn(n, z):
    return scipy.special.sph_yn(n, z)[0][-1]
//  [python]
def sph_yn(n, z):
    return scipy.special.spherical_yn(n, z)[0][-1]
//  [python]
def sph_yn_(n, x):
    return sph_yn(n.astype('l'), x)[0][-1]
//  [python]
def sph_yn_(n, x):
    return scipy.special.spherical_yn(n.astype('l'), x)[0][-1]
//  [python]
def test_riccati_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            ynrl = (special.sph_yn(1,.2)[0]*.2,special.sph_yn(1,.2)[0]+special.sph_yn(1,.2)[1]*.2)
        ricyn = special.riccati_yn(1,.2)
        assert_array_almost_equal(ricyn,ynrl,8)
//  [python]
def test_riccati_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            ynrl = (special.spherical_yn(1,.2)[0]*.2,special.spherical_yn(1,.2)[0]+special.spherical_yn(1,.2)[1]*.2)
        ricyn = special.riccati_yn(1,.2)
        assert_array_almost_equal(ricyn,ynrl,8)
//  [python]
def test_sph_yn(self):
        sy1 = special.sph_yn(2,.2)[0][2]
        sy2 = special.sph_yn(0,.2)[0][0]
        sphpy = (special.sph_yn(1,.2)[0][0]-2*special.sph_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        sy3 = special.sph_yn(1,.2)[1][1]
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_sph_yn(self):
        sy1 = special.spherical_yn(2,.2)[0][2]
        sy2 = special.spherical_yn(0,.2)[0][0]
        sphpy = (special.spherical_yn(1,.2)[0][0]-2*special.spherical_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        sy3 = special.spherical_yn(1,.2)[1][1]
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_sph_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            sy1 = special.sph_yn(2,.2)[0][2]
            sy2 = special.sph_yn(0,.2)[0][0]
            sy3 = special.sph_yn(1,.2)[1][1]
            sphpy = (special.sph_yn(1,.2)[0][0]-2*special.sph_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_sph_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            sy1 = special.spherical_yn(2,.2)[0][2]
            sy2 = special.spherical_yn(0,.2)[0][0]
            sy3 = special.spherical_yn(1,.2)[1][1]
            sphpy = (special.spherical_yn(1,.2)[0][0]-2*special.spherical_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_sph_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            sy1 = special.sph_yn(2,.2)[0][2]
            sy2 = special.sph_yn(0,.2)[0][0]
            sphpy = (special.sph_yn(1,.2)[0][0]-2*special.sph_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        sy3 = special.sph_yn(1,.2)[1][1]
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_sph_yn(self):
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            sy1 = special.spherical_yn(2,.2)[0][2]
            sy2 = special.spherical_yn(0,.2)[0][0]
            sphpy = (special.spherical_yn(1,.2)[0][0]-2*special.spherical_yn(2,.2)[0][2])/3  # correct derivative value
        assert_almost_equal(sy1,-377.52483,5)  # previous values in the system
        assert_almost_equal(sy2,-4.9003329,5)
        sy3 = special.spherical_yn(1,.2)[1][1]
        assert_almost_equal(sy3,sphpy,4)
//  [python]
def test_riccati_yn(self):
        N, x = 2, 0.2
        C = np.empty((N, N))
        for n in range(N):
            y = s.spherical_yn(n, x)
            yp = s.spherical_yn(n, x, derivative=True)
            C[0,n] = x*y
            C[1,n] = x*yp + y
        assert_array_almost_equal(C, s.riccati_yn(n, x), 8)
//  [python]
def test_riccati_yn(self):
        N, x = 2, 0.2
        C = np.empty((N, N))
        for n in range(N):
            y = special.spherical_yn(n, x)
            yp = special.spherical_yn(n, x, derivative=True)
            C[0,n] = x*y
            C[1,n] = x*yp + y
        assert_array_almost_equal(C, special.riccati_yn(n, x), 8)
//  [python]
def test_spherical_yn(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(lambda n, z: s.spherical_yn(int(n), z),
                            exception_to_nan(mp_spherical_yn),
                            [IntArg(0, 200), Arg(-1e10, 1e10)],
                            dps=100)
//  [python]
def test_spherical_yn(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(lambda n, z: sc.spherical_yn(int(n), z),
                            exception_to_nan(mp_spherical_yn),
                            [IntArg(0, 200), Arg(-1e10, 1e10)],
                            dps=100)
//  [python]
def test_spherical_yn_complex(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(lambda n, z: s.spherical_yn(int(n.real), z),
                            exception_to_nan(mp_spherical_yn),
                            [IntArg(0, 200), ComplexArg()])
//  [python]
def test_spherical_yn_complex(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(lambda n, z: sc.spherical_yn(int(n.real), z),
                            exception_to_nan(mp_spherical_yn),
                            [IntArg(0, 200), ComplexArg()])
//  [python]
def test_spherical_yn(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(
            lambda n, z: s.spherical_yn(int(n), z),
            exception_to_nan(mp_spherical_yn),
            [IntArg(0, 200), Arg(-1e10, 1e10)],
            dps=100,
        )
//  [python]
def test_spherical_yn(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(
            lambda n, z: sc.spherical_yn(int(n), z),
            exception_to_nan(mp_spherical_yn),
            [IntArg(0, 200), Arg(-1e10, 1e10)],
            dps=100,
        )
//  [python]
def test_spherical_yn_complex(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(
            lambda n, z: s.spherical_yn(int(n.real), z),
            exception_to_nan(mp_spherical_yn),
            [IntArg(0, 200), ComplexArg()],
        )
//  [python]
def test_spherical_yn_complex(self):
        def mp_spherical_yn(n, z):
            arg = mpmath.mpmathify(z)
            out = (mpmath.bessely(n + mpmath.mpf(1)/2, arg) /
                   mpmath.sqrt(2*arg/mpmath.pi))
            if arg.imag == 0:
                return out.real
            else:
                return out

        assert_mpmath_equal(
            lambda n, z: sc.spherical_yn(int(n.real), z),
            exception_to_nan(mp_spherical_yn),
            [IntArg(0, 200), ComplexArg()],
        )
//  [python]
def spherical_yn_(n, x):
    return s.spherical_yn(n.astype('l'), x)
//  [python]
def spherical_yn_(n, x):
    return spherical_yn(n.astype('l'), x)
//  [python]
def nl(l,x,d):
    '''
    Spherical Bessel function of the second kind
    '''
    return s.spherical_yn(l,x,derivative=d)
//  [python]
def nl(l,x,d):
    '''
    Spherical Bessel function of the second kind
    '''
    return scsp.spherical_yn(l,x,derivative=d)
//  [python]
def sy(n, q):
    return s.spherical_yn(n, q)
//  [python]
def sy(n, q):
    return sp.spherical_yn(n, q)
//  [python]
def dsy(n, q):
    return s.spherical_yn(n, q, derivative=True)
//  [python]
def dsy(n, q):
    return sp.spherical_yn(n, q, derivative=True)
//  [python]
def test_real(self):
        assert sp.spherical_yn(1, 3) == ssc.spherical_yn(1, 3)
//  [python]
def test_real(self):
        assert sc.spherical_yn(1, 3) == ssc.spherical_yn(1, 3)
//  [python]
def test_complex(self):
        assert s.spherical_yn(1, 3 + 1j) == ssc.spherical_yn(1, 3 + 1j)
//  [python]
def test_complex(self):
        assert sc.spherical_yn(1, 3 + 1j) == ssc.spherical_yn(1, 3 + 1j)
//  [python]
def dspneumann(n, kr):
    """Derivative spherical Neumann (Bessel second kind) of order n at kr.

    Parameters
    ----------
    n : array_like
        Order
    kr: array_like
        Argument

    Returns
    -------
    Yv' : complex float
        Derivative of spherical Neumann (Bessel second kind)
    """
    n, kr = scalar_broadcast_match(n, kr)
    if _np.any(n < 0) | _np.any(_np.mod(n, 1) != 0) | _np.any(_np.mod(kr, 1) != 0):
        return spneumann(n, kr) * n / kr - spneumann(n + 1, kr)
    else:
        return s.spherical_yn(
            n.astype(_np.int_), kr.astype(_np.complex_), derivative=True
        )
//  [python]
def dspneumann(n, kr):
    """Derivative spherical Neumann (Bessel second kind) of order n at kr.

    Parameters
    ----------
    n : array_like
        Order
    kr: array_like
        Argument

    Returns
    -------
    Yv' : complex float
        Derivative of spherical Neumann (Bessel second kind)
    """
    n, kr = scalar_broadcast_match(n, kr)
    if _np.any(n < 0) | _np.any(_np.mod(n, 1) != 0) | _np.any(_np.mod(kr, 1) != 0):
        return spneumann(n, kr) * n / kr - spneumann(n + 1, kr)
    else:
        return scy.spherical_yn(
            n.astype(_np.int_), kr.astype(_np.complex_), derivative=True
        )
//  [python]
def spherical_yn_d(n, z):
    """Derivative of the spherical Bessel function of the second kind.

    This is simply a wrapper for `scipy.special.spherical_yn(n, z, True)`, see
    :py:func:`scipy.special.spherical_jn`. It's here to have a consistent way of
    calling the derivative of a (spherical) Bessel or Hankel function.

    Args:
        n (int, array_like): Order
        z (float or complex, array_like): Argument

    Returns:
        float or complex

    References:
        - `DLMF 10.47 <https://dlmf.nist.gov/10.47>`_
        - `DLMF 10.51 <https://dlmf.nist.gov/10.51>`_
    """
    return s.spherical_yn(n, z, True)
//  [python]
def spherical_yn_d(n, z):
    """Derivative of the spherical Bessel function of the second kind.

    This is simply a wrapper for `scipy.special.spherical_yn(n, z, True)`, see
    :py:func:`scipy.special.spherical_jn`. It's here to have a consistent way of
    calling the derivative of a (spherical) Bessel or Hankel function.

    Args:
        n (int, array_like): Order
        z (float or complex, array_like): Argument

    Returns:
        float or complex

    References:
        - `DLMF 10.47 <https://dlmf.nist.gov/10.47>`_
        - `DLMF 10.51 <https://dlmf.nist.gov/10.51>`_
    """
    return spherical_yn(n, z, True)
//  [python]
def test_zero(self):
        assert isclose(sc.spherical_yn_d(0, 3), s.spherical_yn(0, 3, True))
//  [python]
def test_zero(self):
        assert isclose(sc.spherical_yn_d(0, 3), ssc.spherical_yn(0, 3, True))
//  [python]
def spneumann(n, kr):
    """Spherical Neumann (Bessel second kind) of order n at kr.

    Parameters
    ----------
    n : array_like
        Order
    kr: array_like
        Argument

    Returns
    -------
    Yv : complex float
        Spherical Neumann (Bessel second kind)
    """
    n, kr = scalar_broadcast_match(n, kr)

    if _np.any(n < 0) | _np.any(_np.mod(n, 1) != 0):
        Yv = _np.full(kr.shape, _np.nan, dtype=_np.complex_)

        kr_non_zero = kr != 0
        Yv[kr_non_zero] = _np.lib.scimath.sqrt(_np.pi / 2 / kr[kr_non_zero]) * neumann(
            n[kr_non_zero] + 0.5, kr[kr_non_zero]
        )
        Yv[kr < 0] = -Yv[kr < 0]
    else:
        Yv = s.spherical_yn(n.astype(_np.int_), kr)
        # return possible infs as nan to stay consistent
        Yv[_np.isinf(Yv)] = _np.nan
    return _np.squeeze(Yv)
//  [python]
def spneumann(n, kr):
    """Spherical Neumann (Bessel second kind) of order n at kr.

    Parameters
    ----------
    n : array_like
        Order
    kr: array_like
        Argument

    Returns
    -------
    Yv : complex float
        Spherical Neumann (Bessel second kind)
    """
    n, kr = scalar_broadcast_match(n, kr)

    if _np.any(n < 0) | _np.any(_np.mod(n, 1) != 0):
        Yv = _np.full(kr.shape, _np.nan, dtype=_np.complex_)

        kr_non_zero = kr != 0
        Yv[kr_non_zero] = _np.lib.scimath.sqrt(_np.pi / 2 / kr[kr_non_zero]) * neumann(
            n[kr_non_zero] + 0.5, kr[kr_non_zero]
        )
        Yv[kr < 0] = -Yv[kr < 0]
    else:
        Yv = scy.spherical_yn(n.astype(_np.int_), kr)
        # return possible infs as nan to stay consistent
        Yv[_np.isinf(Yv)] = _np.nan
    return _np.squeeze(Yv)
//  [python]
def test_non_zero(self):
        assert isclose(sc.spherical_yn_d(2, 3 + 4j), s.spherical_yn(2, 3 + 4j, True))
//  [python]
def test_non_zero(self):
        assert isclose(sc.spherical_yn_d(2, 3 + 4j), ssc.spherical_yn(2, 3 + 4j, True))
//  [python]
def test_interp2d_meshgrid_input(self):
        # Ticket #703
        x = linspace(0, 2, 16)
        y = linspace(0, pi, 21)
        z = sin(x[None,:] + y[:,None]/2.)
        I = interp2d(x, y, z)
        assert_almost_equal(I(1.0, 2.0), sin(2.0), decimal=2)
//  [python]
def test_interp2d_meshgrid_input(self):
        # Ticket #703
        x = linspace(0, 2, 16)
        y = linspace(0, pi, 21)
        z = sin(x[None,:] + y[:,None]/2.)
        I = bisplev(x, y, z)
        assert_almost_equal(I(1.0, 2.0), sin(2.0), decimal=2)
//  [python]
def test_interp2d(self):
        y, x = mgrid[0:2:20j, 0:pi:21j]
        z = sin(x+0.5*y)
        I = interp2d(x, y, z)
        assert_almost_equal(I(1.0, 2.0), sin(2.0), decimal=2)

        v,u = ogrid[0:2:24j, 0:pi:25j]
        assert_almost_equal(I(u.ravel(), v.ravel()), sin(u+0.5*v), decimal=2)
//  [python]
def test_interp2d(self):
        y, x = mgrid[0:2:20j, 0:pi:21j]
        z = sin(x+0.5*y)
        I = bisplev(x[:,0], y[0,:], z)
        assert_almost_equal(I(1.0, 2.0), sin(2.0), decimal=2)

        v,u = ogrid[0:2:24j, 0:pi:25j]
        assert_almost_equal(I(u.ravel(), v.ravel()), sin(u+0.5*v), decimal=2)
//  [python]
def test_interp2d_linear(self):
        # Ticket #898
        a = np.zeros([5, 5])
        a[2, 2] = 1.0
        x = y = np.arange(5)
        b = interp2d(x, y, a, 'linear')
        assert_almost_equal(b(2.0, 1.5), np.array([0.5]), decimal=2)
        assert_almost_equal(b(2.0, 2.5), np.array([0.5]), decimal=2)
//  [python]
def test_interp2d_linear(self):
        # Ticket #898
        a = np.zeros([5, 5])
        a[2, 2] = 1.0
        x = y = np.arange(5)
        b = RectBivariateSpline(x, y, a)
        assert_almost_equal(b(2.0, 1.5), np.array([0.5]), decimal=2)
        assert_almost_equal(b(2.0, 2.5), np.array([0.5]), decimal=2)
//  [python]
def test_interp2d_eval_unsorted(self):
        y, x = mgrid[0:2:20j, 0:pi:21j]
        z = sin(x + 0.5*y)
        func = interp2d(x, y, z)

        xe = np.array([3, 4, 5])
        ye = np.array([5.3, 7.1])
        assert_allclose(func(xe, ye), func(xe, ye[::-1]))

        assert_raises(ValueError, func, xe, ye[::-1], 0, 0, True)
//  [python]
def test_interp2d_eval_unsorted(self):
        y, x = mgrid[0:2:20j, 0:pi:21j]
        z = sin(x + 0.5*y)
        func = bisplev(x,y,z)

        xe = np.array([3, 4, 5])
        ye = np.array([5.3, 7.1])
        assert_allclose(func(xe, ye), func(xe, ye[::-1]))

        assert_raises(ValueError, func, xe, ye[::-1], 0, 0, True)
//  [python]
def test_spherical_bessel_y():
    if NumCpp.NUMCPP_NO_USE_BOOST and not NumCpp.STL_SPECIAL_FUNCTIONS:
        return

    order = np.random.randint(0, 10)
    value = np.random.rand(1).item()
    assert roundScalar(NumCpp.spherical_bessel_yn_Scalar(order, value), NUM_DECIMALS_ROUND) == roundScalar(
        sp.spherical_yn(order, value).item(), NUM_DECIMALS_ROUND
    )

    shapeInput = np.random.randint(
        20,
        100,
        [
            2,
        ],
    )
    shape = NumCpp.Shape(shapeInput[0].item(), shapeInput[1].item())
    cArray = NumCpp.NdArray(shape)
    order = np.random.randint(0, 10)
    data = np.random.rand(shape.rows, shape.cols)
    cArray.setArray(data)
    assert np.array_equal(
        roundArray(NumCpp.spherical_bessel_yn_Array(order, cArray), NUM_DECIMALS_ROUND),
        roundArray(sp.spherical_yn(order, data), NUM_DECIMALS_ROUND),
    )
//  [python]
def test_interp2d_meshgrid_input_unsorted(self):
        np.random.seed(1234)
        x = linspace(0, 2, 16)
        y = linspace(0, pi, 21)

        z = sin(x[None,:] + y[:,None]/2.)
        ip1 = interp2d(x.copy(), y.copy(), z, kind='cubic')

        np.random.shuffle(x)
        z = sin(x[None,:] + y[:,None]/2.)
        ip2 = interp2d(x.copy(), y.copy(), z, kind='cubic')

        np.random.shuffle(x)
        np.random.shuffle(y)
        z = sin(x[None,:] + y[:,None]/2.)
        ip3 = interp2d(x, y, z, kind='cubic')

        x = linspace(0, 2, 31)
        y = linspace(0, pi, 30)

        assert_equal(ip1(x, y), ip2(x, y))
        assert_equal(ip1(x, y), ip3(x, y))
//  [python]
def test_interp2d_meshgrid_input_unsorted(self):
        np.random.seed(1234)
        x = linspace(0, 2, 16)
        y = linspace(0, pi, 21)

        z = sin(x[None,:] + y[:,None]/2.)
        ip1 = bisplev(x, y, z)

        np.random.shuffle(x)
        z = sin(x[None,:] + y[:,None]/2.)
        ip2 = bisplev(x, y, z)

        np.random.shuffle(x)
        np.random.shuffle(y)
        z = sin(x[None,:] + y[:,None]/2.)
        ip3 = bisplev(x, y, z)

        x = linspace(0, 2, 31)
        y = linspace(0, pi, 30)

        assert_equal(ip1(x, y), ip2(x, y))
        assert_equal(ip1(x, y), ip3(x, y))
//  [python]
def test_interp2d_bounds(self):
        x = np.linspace(0, 1, 5)
        y = np.linspace(0, 2, 7)
        z = x[None, :]**2 + y[:, None]

        ix = np.linspace(-1, 3, 31)
        iy = np.linspace(-1, 3, 33)

        b = interp2d(x, y, z, bounds_error=True)
        assert_raises(ValueError, b, ix, iy)

        b = interp2d(x, y, z, fill_value=np.nan)
        iz = b(ix, iy)
        mx = (ix < 0) | (ix > 1)
        my = (iy < 0) | (iy > 2)
        assert_(np.isnan(iz[my,:]).all())
        assert_(np.isnan(iz[:,mx]).all())
        assert_(np.isfinite(iz[~my,:][:,~mx]).all())
//  [python]
def test_interp2d_bounds(self):
        x = np.linspace(0, 1, 5)
        y = np.linspace(0, 2, 7)
        z = x[None, :]**2 + y[:, None]

        ix = np.linspace(-1, 3, 31)
        iy = np.linspace(-1, 3, 33)

        tck = bisplev(x, y, z)
        b = lambda x, y: bisplev(x, y, tck)

        assert_raises(ValueError, b, ix, iy)

        b = lambda x, y: bisplev(x, y, tck, fill_value=np.nan)
        iz = b(ix, iy)
        mx = (ix < 0) | (ix > 1)
        my = (iy < 0) | (iy > 2)
        assert_(np.isnan(iz[my,:]).all())
        assert_(np.isnan(iz[:,mx]).all())
        assert_(np.isfinite(iz[~my,:][:,~mx]).all())
//  [python]
def interp2d_pairs(*args,**kwargs):
    """ Same interface as interp2d but the returned interpolant will evaluate its inputs as pairs of values.
    """
    # Internal function, that evaluates pairs of values, output has the same shape as input
    def interpolant(x,y,f):
        x,y = np.asarray(x), np.asarray(y)
        return (si.dfitpack.bispeu(f.tck[0], f.tck[1], f.tck[2], f.tck[3], f.tck[4], x.ravel(), y.ravel())[0]).reshape(x.shape)
    # Wrapping the scipy interp2 function to call out interpolant instead
    return lambda x,y: interpolant(x,y,si.interp2d(*args,**kwargs))