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()
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()
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()