def test_identity_basics(self): """Test identity tf.""" # gd = HortonLiner(100) rtf = IdentityRTransform() assert rtf.transform(0.0) == 0.0 assert rtf.transform(99.0) == 99.0 self.check_consistency(rtf) self.check_deriv(rtf)
def test_cubicspline_and_interp(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad_grid = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad_grid, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values) # same result from points and interpolation assert_allclose( interp, values[atgrid.indices[i]:atgrid.indices[i + 1]]) # test random x, y, z for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) # xyz /= np.linalg.norm(xyz, axis=-1)[:, None] # rad = np.random.normal() * np.random.randint(1, 11) # xyz *= rad ref_value = self.helper_func_power(xyz) interp = atgrid.interpolate(xyz, values) assert_allclose(interp, ref_value)
def test_cubicspline_and_deriv(self): """Test spline for derivation.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values, deriv=1, ) # same result from points and interpolation ref_deriv = self.helper_func_power_deriv( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]]) assert_allclose(interp, ref_deriv) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power_deriv(xyz) interp = atgrid.interpolate(xyz, values, deriv=1) assert_allclose(interp, ref_value)
def test_spline_with_sph_harms(self): """Test spline projection the same as spherical harmonics.""" rad = IdentityRTransform().transform_grid(HortonLinear(10)) rad._points += 1 atgrid = AtomicGrid.special_init(rad, 1, scales=[], degs=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 0], sph_coor[:, 1]) result = spline_with_sph_harms( r_sph, values, atgrid.weights, atgrid.indices, rad.points ) # generate ref # for shell in range(1, 11): for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) r = np.linalg.norm(sh_grid._points, axis=1) theta = np.arctan2(sh_grid._points[:, 1], sh_grid._points[:, 0]) phi = np.arccos(sh_grid._points[:, 2] / r) r_sph = generate_real_sph_harms(l_max, theta, phi) r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) assert_allclose(r_sph_proj, result(shell), atol=1e-10)
def test_spline_with_sph_harms(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) # generate ref for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) # Convert to spherical harmonics r = np.linalg.norm(sh_grid._points, axis=1) theta = np.arctan2(sh_grid._points[:, 1], sh_grid._points[:, 0]) phi = np.arccos(sh_grid._points[:, 2] / r) # General all spherical harmonics up to l_max r_sph = generate_real_sph_harms(l_max, theta, phi) # Project the function 2x^2 + 3y^2 + 4z^2 r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) # Check the actual projection against the cubic spline interpolation. assert_allclose(r_sph_proj, result(shell), atol=1e-10)
def test_interpolation_of_laplacian_with_spherical_harmonic(self): r"""Test the interpolation of Laplacian of spherical harmonic is eigenvector.""" odg = OneDGrid(np.linspace(0.0, 10, num=2000), np.ones(2000), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) degree = 6 * 2 + 2 atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) def func(sph_points): # Spherical harmonic of order 6 and magnetic 0 r, phi, theta = sph_points.T return (np.sqrt(2.0) * np.sqrt(13) / (np.sqrt(np.pi) * 32) * (231 * np.cos(theta)**6.0 - 315 * np.cos(theta)**4.0 + 105 * np.cos(theta)**2.0 - 5.0)) # Get spherical points from atomic grid spherical_pts = atgrid.convert_cartesian_to_spherical(atgrid.points) func_values = func(spherical_pts) laplacian = atgrid.interpolate_laplacian(func_values) # Test on the same points used for interpolation and random points. for grid in [atgrid.points, np.random.uniform(-0.75, 0.75, (250, 3))]: actual = laplacian(grid) spherical_pts = atgrid.convert_cartesian_to_spherical(grid) # Eigenvector spherical harmonic times l(l + 1) / r^2 with np.errstate(divide="ignore", invalid="ignore"): desired = (-func(spherical_pts) * 6 * (6 + 1) / spherical_pts[:, 0]**2.0) desired[spherical_pts[:, 0]**2.0 < 1e-10] = 0.0 assert_almost_equal(actual, desired, decimal=3)
def test_transform_coeff(self): """Test coefficient transform with r.""" # d^2y / dx^2 = 1 itf = IdentityRTransform() inv_tf = InverseTF(itf) derivs_fun = [inv_tf.deriv, inv_tf.deriv2, inv_tf.deriv3] coeff = np.array([0, 0, 1]) x = np.linspace(0, 1, 10) coeff_b = ODE._transformed_coeff_ode_with_r(coeff, derivs_fun, x) # compute transformed coeffs assert_allclose(coeff_b, np.zeros((3, 10), dtype=float) + coeff[:, None])
def test_cubicspline_and_interp_mol(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) result = spline_with_atomic_grid(atgrid, values) sph_coor = atgrid.convert_cart_to_sph() semi_sph_c = sph_coor[atgrid.indices[5] : atgrid.indices[6]] interp = interpolate(result, rad.points[5], semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5] : atgrid.indices[6]])
def test_cubicspline_and_interp_mol(self): """Test cubicspline interpolation values.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): interp = atgrid.interpolate( atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]], values) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[i]:atgrid.indices[i + 1]])
def test_derivative_of_interpolate_given_splines(self): """Test the spline interpolating derivative of function in radial coordinate.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=1) # same result from points and interpolation ref_deriv = self.helper_func_power_deriv( atgrid.points[atgrid.indices[5]:atgrid.indices[6]]) assert_allclose(interp, ref_deriv) # test random x, y, z with fd xyz = np.random.rand(1, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power_deriv(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate_given_splines(result, np.abs(rad), theta, phi, deriv=1) assert_allclose(interp, ref_value) with self.assertRaises(ValueError): interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=4) with self.assertRaises(ValueError): interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2], deriv=-1)
def test_transformation_of_ode_with_identity_transform(): """Test transformation of ODE with identity transform.""" # Checks that the identity transform x -> x results in the same answer. # Obtain identity trasnform and derivatives. itf = IdentityRTransform() inv_tf = InverseRTransform(itf) derivs_fun = [inv_tf.deriv, inv_tf.deriv2, inv_tf.deriv3] # d^2y / dx^2 = 1 coeff = np.array([0, 0, 1]) x = np.linspace(0, 1, 10) # compute transformed coeffs coeff_b = _transform_ode_from_derivs(coeff, derivs_fun, x) # f_x = 0 * x + 1 # 1 for every assert_allclose(coeff_b, np.zeros((3, 10), dtype=float) + coeff[:, None])
def test_interpolate_given_splines(self): """Test points to interpolate to is the same as original function values.""" # Construct grid odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) # Construct the function values and splies. values = self.helper_func_power(atgrid.points) result = spline_with_atomic_grid(atgrid, values) # Obtain the spherical coordinates and interpolate from indices[5] to indices[6] sph_coor = atgrid.convert_cart_to_sph() semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, rad.points[5], semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5]:atgrid.indices[6]])
def test_value_fitting(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) spls = atgrid.fit(values) assert len(spls) == 16 for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) r = np.linalg.norm(sh_grid._points, axis=1) theta = np.arctan2(sh_grid._points[:, 1], sh_grid._points[:, 0]) phi = np.arccos(sh_grid._points[:, 2] / r) l_max = atgrid.l_max // 2 r_sph = atgrid._generate_real_sph_harm(l_max, theta, phi) r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) assert_allclose(r_sph_proj, [spl(shell) for spl in spls], atol=1e-10)
def test_cubicspline_and_deriv(self): """Test spline for derivation.""" rad = IdentityRTransform().transform_grid(HortonLinear(10)) rad._points += 1 atgrid = AtomicGrid.special_init(rad, 1, scales=[], degs=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 0], sph_coor[:, 1]) result = spline_with_sph_harms( r_sph, values, atgrid.weights, atgrid.indices, rad.points ) semi_sph_c = sph_coor[atgrid.indices[5] : atgrid.indices[6]] interp = interpolate(result, 6, semi_sph_c[:, 0], semi_sph_c[:, 1], deriv=1) # same result from points and interpolation ref_deriv = self.helper_func_power_deriv( atgrid.points[atgrid.indices[5] : atgrid.indices[6]] ) assert_allclose(interp, ref_deriv) # test random x, y, z with fd xyz = np.random.rand(1, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power_deriv(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate(result, np.abs(rad), theta, phi, deriv=1) assert_allclose(interp, ref_value) with self.assertRaises(ValueError): interp = interpolate(result, 6, semi_sph_c[:, 0], semi_sph_c[:, 1], deriv=4) with self.assertRaises(ValueError): interp = interpolate( result, 6, semi_sph_c[:, 0], semi_sph_c[:, 1], deriv=-1 )
def test_interpolate_given_splines_at_random_points(self): """Test interpolation given splines at random points.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 1], sph_coor[:, 2]) result = spline_with_sph_harms(r_sph, values, atgrid.weights, atgrid.indices, rad) semi_sph_c = sph_coor[atgrid.indices[5]:atgrid.indices[6]] interp = interpolate_given_splines(result, 6, semi_sph_c[:, 1], semi_sph_c[:, 2]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5]:atgrid.indices[6]]) # random multiple interpolation test for _ in range(100): indices = np.random.randint(1, 11, np.random.randint(1, 10)) interp = interpolate_given_splines(result, indices, semi_sph_c[:, 1], semi_sph_c[:, 2]) for i, j in enumerate(indices): assert_allclose( interp[i], values[atgrid.indices[j - 1]:atgrid.indices[j]]) # test random x, y, z xyz = np.random.rand(10, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate_given_splines(result, np.abs(rad), theta, phi) assert_allclose(interp, ref_value)
def test_interpolate_and_its_derivatives(self): """Test interpolation of derivative of polynomial function.""" odg = OneDGrid(np.linspace(0.01, 10, num=50), np.ones(50), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) for _ in range(10): degree = np.random.randint(5, 20) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[degree]) values = self.helper_func_power(atgrid.points) # spls = atgrid.fit_values(values) for i in range(10): points = atgrid.points[atgrid.indices[i]:atgrid.indices[i + 1]] interp_func = atgrid.interpolate(values) # same result from points and interpolation ref_deriv = self.helper_func_power(points, deriv=1) assert_almost_equal(interp_func(points, deriv=1), ref_deriv) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power(xyz, deriv=1) interp_func = atgrid.interpolate(values) interp = interp_func(xyz, deriv=1) assert_allclose(interp, ref_value) # test random x, y, z with fd for _ in range(10): xyz = np.random.rand(10, 3) * np.random.uniform(1, 6) ref_value = self.helper_func_power_deriv(xyz) interp_func = atgrid.interpolate(values) interp = interp_func(xyz, deriv=1, only_radial_derivs=True) assert_allclose(interp, ref_value) with self.assertRaises(ValueError): # Raise error since it can't do derivative beyond one. interp_func(xyz, deriv=3)
def test_cubicspline_and_interp(self): """Test cubicspline interpolation values.""" rad = IdentityRTransform().transform_grid(HortonLinear(10)) rad._points += 1 atgrid = AtomicGrid.special_init(rad, 1, scales=[], degs=[7]) sph_coor = atgrid.convert_cart_to_sph() values = self.helper_func_power(atgrid.points) l_max = atgrid.l_max // 2 r_sph = generate_real_sph_harms(l_max, sph_coor[:, 0], sph_coor[:, 1]) result = spline_with_sph_harms( r_sph, values, atgrid.weights, atgrid.indices, rad.points ) semi_sph_c = sph_coor[atgrid.indices[5] : atgrid.indices[6]] interp = interpolate(result, 6, semi_sph_c[:, 0], semi_sph_c[:, 1]) # same result from points and interpolation assert_allclose(interp, values[atgrid.indices[5] : atgrid.indices[6]]) # random multiple interpolation test for _ in range(100): indices = np.random.randint(1, 11, np.random.randint(1, 10)) interp = interpolate(result, indices, semi_sph_c[:, 0], semi_sph_c[:, 1]) for i, j in enumerate(indices): assert_allclose( interp[i], values[atgrid.indices[j - 1] : atgrid.indices[j]] ) # test random x, y, z xyz = np.random.rand(10, 3) xyz /= np.linalg.norm(xyz, axis=-1)[:, None] rad = np.random.normal() * np.random.randint(1, 11) xyz *= rad ref_value = self.helper_func_power(xyz) r = np.linalg.norm(xyz, axis=-1) theta = np.arctan2(xyz[:, 1], xyz[:, 0]) phi = np.arccos(xyz[:, 2] / r) interp = interpolate(result, np.abs(rad), theta, phi) assert_allclose(interp, ref_value)
def test_value_fitting(self): """Test spline projection the same as spherical harmonics.""" odg = OneDGrid(np.arange(10) + 1, np.ones(10), (0, np.inf)) rad = IdentityRTransform().transform_1d_grid(odg) atgrid = AtomGrid.from_pruned(rad, 1, sectors_r=[], sectors_degree=[7]) values = self.helper_func_power(atgrid.points) spls = atgrid.radial_component_splines(values) assert len(spls) == 16 for shell in range(1, 11): sh_grid = atgrid.get_shell_grid(shell - 1, r_sq=False) spherical_pts = atgrid.convert_cartesian_to_spherical( sh_grid.points) _, theta, phi = spherical_pts.T l_max = atgrid.l_max // 2 r_sph = generate_real_spherical_harmonics(l_max, theta, phi) r_sph_proj = np.sum( r_sph * self.helper_func_power(sh_grid.points) * sh_grid.weights, axis=-1, ) assert_allclose(r_sph_proj, [spl(shell) for spl in spls], atol=1e-10)
return self._exp * x**(self._exp - 1) def deriv2(self, x): """Compute 2nd order deriv of TF.""" return (self._exp - 1) * (self._exp) * x**(self._exp - 2) def deriv3(self, x): """Compute 3rd order deriv of TF.""" return (self._exp - 2) * (self._exp - 1) * (self._exp) * x**(self._exp - 3) @pytest.mark.parametrize( "transform, fx, coeffs", [ [IdentityRTransform(), fx_ones, [-1, 1, 1]], [SqTF(), fx_ones, np.random.uniform(-100, 100, (3, ))], [ KnowlesRTransform(0.01, 1, 5), fx_ones, np.random.uniform(-10, 10, (3, )) ], [ BeckeRTransform(0.1, 100.0), fx_ones, np.random.uniform(0, 100, (3, )) ], [SqTF(1, 3), fx_complicated_example, np.random.uniform(0, 100, (3, ))], [SqTF(3, 1), fx_complicated_example, [2, 3, 2]], [SqTF(), fx_quadratic, np.random.uniform(-100, 100, (3, ))], [
def test_domain(self): """Test domain errors.""" rad = GaussLegendre(10) with self.assertRaises(ValueError): tf = IdentityRTransform() tf.transform_1d_grid(rad) with self.assertRaises(ValueError): tf = LinearInfiniteRTransform(0.1, 1.5) tf.transform_1d_grid(rad) with self.assertRaises(ValueError): tf = ExpRTransform(0.1, 1e1) tf.transform_1d_grid(rad) with self.assertRaises(ValueError): tf = PowerRTransform(1e-3, 1e2) tf.transform_1d_grid(rad) with self.assertRaises(ValueError): tf = HyperbolicRTransform(0.4 / 450, 1.0 / 450) tf.transform_1d_grid(rad)