Ejemplo n.º 1
0
def test_complex_bessel(ctx_factory, ref_src):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    if not has_double_support(ctx.devices[0]):
        from pytest import skip
        skip(
            "no double precision support--cannot test complex bessel function")

    v = 40
    n = 10**5

    np.random.seed(13)
    z = (np.logspace(-5, 2, n) * np.exp(1j * 2 * np.pi * np.random.rand(n)))

    if ref_src == "pyfmmlib":
        pyfmmlib = pytest.importorskip("pyfmmlib")

        jv_ref = np.zeros(len(z), 'complex')

        vin = v + 1

        for i in range(len(z)):
            ier, fjs, _, _ = pyfmmlib.jfuns2d(vin, z[i], 1, 0, 10000)
            assert ier == 0
            jv_ref[i] = fjs[v]

    elif ref_src == "scipy":
        spec = pytest.importorskip("scipy.special")
        jv_ref = spec.jv(v, z)

    else:
        raise ValueError("ref_src")

    z_dev = cl_array.to_device(queue, z)

    jv_dev = clmath.bessel_jn(v, z_dev)

    abs_err_jv = np.abs(jv_dev.get() - jv_ref)
    abs_jv_ref = np.abs(jv_ref)
    rel_err_jv = abs_err_jv / abs_jv_ref

    # use absolute error instead if the function value itself is too small
    tiny = 1e-300
    ind = abs_jv_ref < tiny
    rel_err_jv[ind] = abs_err_jv[ind]

    # if the reference value is inf or nan, set the error to zero
    ind1 = np.isinf(abs_jv_ref)
    ind2 = np.isnan(abs_jv_ref)

    rel_err_jv[ind1] = 0
    rel_err_jv[ind2] = 0

    if 0:
        print(abs(z))
        print(np.abs(jv_ref))
        print(np.abs(jv_dev.get()))
        print(rel_err_jv)

    max_err = np.max(rel_err_jv)
    assert max_err <= 2e-13, max_err

    print("Jv", np.max(rel_err_jv))

    if 0:
        import matplotlib.pyplot as pt
        pt.loglog(np.abs(z), rel_err_jv)
        pt.show()
Ejemplo n.º 2
0
def test_bessel_j(ctx_factory):
    try:
        import scipy.special as spec
    except ImportError:
        from py.test import skip

        skip("scipy not present--cannot test Bessel function")

    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    if not has_double_support(ctx.devices[0]):
        from py.test import skip

        skip("no double precision support--cannot test bessel function")

    nterms = 30

    try:
        from hellskitchen._native import jfuns2d
    except ImportError:
        use_hellskitchen = False
    else:
        use_hellskitchen = True

    if use_hellskitchen:
        a = np.logspace(-3, 3, 10 ** 6)
    else:
        a = np.logspace(-5, 5, 10 ** 6)

    if use_hellskitchen:
        hellskitchen_result = np.empty((len(a), nterms), dtype=np.complex128)
        for i, a_i in enumerate(a):
            if i % 10000 == 0:
                print "%.1f %%" % (100 * i / len(a))
            ier, fjs, _, _ = jfuns2d(nterms, a_i, 1, 0, 10000)
            hellskitchen_result[i] = fjs[:nterms]
        assert ier == 0

    a_dev = cl_array.to_device(queue, a)

    for n in range(0, nterms):
        cl_bessel = clmath.bessel_jn(n, a_dev).get()
        scipy_bessel = spec.jn(n, a)

        error_scipy = np.max(np.abs(cl_bessel - scipy_bessel))
        assert error_scipy < 1e-10, error_scipy

        if use_hellskitchen:
            hk_bessel = hellskitchen_result[:, n]
            error_hk = np.max(np.abs(cl_bessel - hk_bessel))
            assert error_hk < 1e-10, error_hk
            error_hk_scipy = np.max(np.abs(scipy_bessel - hk_bessel))
            print (n, error_scipy, error_hk, error_hk_scipy)
        else:
            print (n, error_scipy)

        assert not np.isnan(cl_bessel).any()

        if 0 and n == 15:
            import matplotlib.pyplot as pt

            # pt.plot(scipy_bessel)
            # pt.plot(cl_bessel)

            pt.loglog(a, np.abs(cl_bessel - scipy_bessel), label="vs scipy")
            if use_hellskitchen:
                pt.loglog(a, np.abs(cl_bessel - hk_bessel), label="vs hellskitchen")
            pt.legend()
            pt.show()
Ejemplo n.º 3
0
def test_complex_bessel(ctx_factory, ref_src):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    if not has_double_support(ctx.devices[0]):
        from pytest import skip
        skip("no double precision support--cannot test complex bessel function")

    v = 40
    n = 10**5

    np.random.seed(13)
    z = (
        np.logspace(-5, 2, n)
        * np.exp(1j * 2 * np.pi * np.random.rand(n)))

    if ref_src == "pyfmmlib":
        pyfmmlib = pytest.importorskip("pyfmmlib")

        jv_ref = np.zeros(len(z), 'complex')

        vin = v+1

        for i in range(len(z)):
            ier, fjs, _, _ = pyfmmlib.jfuns2d(vin, z[i], 1, 0, 10000)
            assert ier == 0
            jv_ref[i] = fjs[v]

    elif ref_src == "scipy":
        spec = pytest.importorskip("scipy.special")
        jv_ref = spec.jv(v, z)

    else:
        raise ValueError("ref_src")

    z_dev = cl_array.to_device(queue, z)

    jv_dev = clmath.bessel_jn(v, z_dev)

    abs_err_jv = np.abs(jv_dev.get() - jv_ref)
    abs_jv_ref = np.abs(jv_ref)
    rel_err_jv = abs_err_jv/abs_jv_ref

    # use absolute error instead if the function value itself is too small
    tiny = 1e-300
    ind = abs_jv_ref < tiny
    rel_err_jv[ind] = abs_err_jv[ind]

    # if the reference value is inf or nan, set the error to zero
    ind1 = np.isinf(abs_jv_ref)
    ind2 = np.isnan(abs_jv_ref)

    rel_err_jv[ind1] = 0
    rel_err_jv[ind2] = 0

    if 0:
        print(abs(z))
        print(np.abs(jv_ref))
        print(np.abs(jv_dev.get()))
        print(rel_err_jv)

    max_err = np.max(rel_err_jv)
    assert max_err <= 2e-13, max_err

    print("Jv", np.max(rel_err_jv))

    if 0:
        import matplotlib.pyplot as pt
        pt.loglog(np.abs(z), rel_err_jv)
        pt.show()