def test_exceptions(self): """Test the derivative interface.""" soap = SOAP( species=[1, 8], rcut=3, nmax=2, lmax=0, sparse=False, ) positions = [[0.0, 0.0, 0.0]] # Test that trying to get analytical derivatives with averaged output # raises an exception soap.sparse = False soap.average = "inner" with self.assertRaises(ValueError): soap.derivatives(H2, positions=positions, method="analytical") soap.average = "off" # Test that trying to get analytical derivatives with polynomial basis # raises an exception, but the numerical ones work. soap_poly = SOAP( species=[1, 8], rcut=3, nmax=2, lmax=0, rbf="polynomial", sparse=False, ) with self.assertRaises(ValueError): soap_poly.derivatives(H2, positions=positions, method="analytical") soap_poly.derivatives(H2, positions=positions, method="numerical") # Test that trying to provide both include and exclude raises an error with self.assertRaises(ValueError): soap.derivatives(H2, include=[0], exclude=[1]) # Test that trying to get derivatives with periodicicity on raises an # exception soap = SOAP( species=[1, 8], rcut=3, nmax=2, lmax=0, rbf="gto", sparse=False, periodic=True, ) with self.assertRaises(ValueError): soap.derivatives(H2, positions=positions, method="analytical") with self.assertRaises(ValueError): soap.derivatives(H2, positions=positions, method="numerical")
def test_sparse(self): """Test that the sparse values are identical to the dense ones.""" positions = H2O.get_positions() soap = SOAP( species=["H", "O"], rcut=3, nmax=1, lmax=1, sparse=False, crossover=False, ) D_dense, d_dense = soap.derivatives(H2O, positions=positions, method="analytical") soap.sparse = True D_sparse, d_sparse = soap.derivatives(H2O, positions=positions, method="analytical") self.assertTrue(np.allclose(D_dense, D_sparse.todense())) self.assertTrue(np.allclose(d_dense, d_sparse.todense()))
def test_parallel(self): """Tests parallel output validity for both dense and sparse output.""" for sparse in [False, True]: desc = SOAP( species=[1, 6, 7, 8], rcut=5, nmax=3, lmax=3, sigma=1, periodic=False, crossover=True, average="off", sparse=sparse, ) n_features = desc.get_number_of_features() samples = [molecule("CO"), molecule("NO"), molecule("OH")] centers = [[0], [0], [0]] # Determining number of jobs based on the amount of CPUs # desc.derivatives(system=samples, n_jobs=-1, only_physical_cores=False) # desc.derivatives(system=samples, n_jobs=-1, only_physical_cores=True) # Perhaps most common scenario: more systems than jobs, using all # centers and indices der, des = desc.derivatives( system=samples, n_jobs=2, ) self.assertTrue(der.shape == (3, 2, 2, 3, n_features)) self.assertTrue(des.shape == (3, 2, n_features)) assumed_der = np.empty((3, 2, 2, 3, n_features)) assumed_des = np.empty((3, 2, n_features)) desc.sparse = False assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # More systems than jobs, using all centers and indices, not requesting # descriptors der = desc.derivatives( system=samples, return_descriptor=False, n_jobs=2, ) self.assertTrue(der.shape == (3, 2, 2, 3, n_features)) assumed_der = np.empty((3, 2, 2, 3, n_features)) desc._sparse = False assumed_der[0, :] = desc.derivatives(samples[0], n_jobs=1, return_descriptor=False) assumed_der[1, :] = desc.derivatives(samples[1], n_jobs=1, return_descriptor=False) assumed_der[2, :] = desc.derivatives(samples[2], n_jobs=1, return_descriptor=False) desc._sparse = sparse if sparse: der = der.todense() self.assertTrue(np.allclose(assumed_der, der)) # More systems than jobs, using custom indices as centers der, des = desc.derivatives( system=samples, positions=centers, n_jobs=2, ) self.assertTrue(der.shape == (3, 1, 2, 3, n_features)) self.assertTrue(des.shape == (3, 1, n_features)) assumed_der = np.empty((3, 1, 2, 3, n_features)) assumed_des = np.empty((3, 1, n_features)) desc._sparse = False assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0], centers[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1], centers[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2], centers[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # More systems than jobs, using custom cartesian centers centers = [[[0, 1, 2]], [[2, 1, 0]], [[1, 2, 0]]] der, des = desc.derivatives( system=samples, positions=centers, n_jobs=2, ) self.assertTrue(der.shape == (3, 1, 2, 3, n_features)) self.assertTrue(des.shape == (3, 1, n_features)) assumed_der = np.empty((3, 1, 2, 3, n_features)) assumed_des = np.empty((3, 1, n_features)) desc._sparse = False assumed_der[0, :], assumed_des[0, :] = desc.derivatives(samples[0], centers[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives(samples[1], centers[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives(samples[2], centers[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # Includes includes = [[0], [0], [0]] der, des = desc.derivatives( system=samples, include=includes, n_jobs=2, ) self.assertTrue(der.shape == (3, 2, 1, 3, n_features)) self.assertTrue(des.shape == (3, 2, n_features)) assumed_der = np.empty((3, 2, 1, 3, n_features)) assumed_des = np.empty((3, 2, n_features)) desc._sparse = False assumed_der[0, :], assumed_des[0, :] = desc.derivatives( samples[0], include=includes[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives( samples[1], include=includes[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives( samples[2], include=includes[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # Excludes excludes = [[0], [0], [0]] der, des = desc.derivatives( system=samples, exclude=excludes, n_jobs=2, ) self.assertTrue(der.shape == (3, 2, 1, 3, n_features)) self.assertTrue(des.shape == (3, 2, n_features)) assumed_der = np.empty((3, 2, 1, 3, n_features)) assumed_des = np.empty((3, 2, n_features)) desc._sparse = False assumed_der[0, :], assumed_des[0, :] = desc.derivatives( samples[0], exclude=excludes[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives( samples[1], exclude=excludes[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives( samples[2], exclude=excludes[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # Test averaged output desc.average = "inner" positions = [[0], [0, 1], [1]] der, des = desc.derivatives( system=samples, positions=positions, n_jobs=2, ) self.assertTrue(der.shape == (3, 1, 2, 3, n_features)) self.assertTrue(des.shape == (3, 1, n_features)) desc._sparse = False assumed_der = np.empty((3, 1, 2, 3, n_features)) assumed_des = np.empty((3, 1, n_features)) assumed_der[0, :], assumed_des[0, :] = desc.derivatives( samples[0], positions=positions[0], n_jobs=1) assumed_der[1, :], assumed_des[1, :] = desc.derivatives( samples[1], positions=positions[1], n_jobs=1) assumed_der[2, :], assumed_des[2, :] = desc.derivatives( samples[2], positions=positions[2], n_jobs=1) desc._sparse = sparse if sparse: der = der.todense() des = des.todense() self.assertTrue(np.allclose(assumed_der, der)) self.assertTrue(np.allclose(assumed_des, des)) # Variable size list output, as the systems have a different size desc.average = "off" samples = [molecule("CO"), molecule("NO2"), molecule("OH")] der, des = desc.derivatives( system=samples, n_jobs=2, ) self.assertTrue(isinstance(der, list)) self.assertTrue(der[0].shape == (2, 2, 3, n_features)) self.assertTrue(der[1].shape == (3, 3, 3, n_features)) self.assertTrue(der[2].shape == (2, 2, 3, n_features)) desc._sparse = False for i in range(len(samples)): assumed_der, assumed_des = desc.derivatives(samples[i], n_jobs=1) i_der = der[i] i_des = des[i] if sparse: i_der = i_der.todense() i_des = i_des.todense() self.assertTrue(np.allclose(assumed_der, i_der)) self.assertTrue(np.allclose(assumed_des, i_des)) desc._sparse = sparse