def construct_array_contraction(contractions, points): """Return the evaluations of the given contractions at the given coordinates. Parameters ---------- contractions : GeneralizedContractionShell Contracted Cartesian Gaussians (of the same shell) that will be used to construct an array. points : np.ndarray(N, 3) Coordinates of the points in space (in atomic units) where the basis functions are evaluated. Rows correspond to the points and columns correspond to the x, y, and z components. Returns ------- array_contraction : np.ndarray(M, L_cart, N) Evaluations of the given Cartesian contractions at the given coordinates. First index corresponds to segmented contractions within the given generalized contraction (same exponents and angular momentum, but different coefficients). `M` is the number of segmented contractions with the same exponents (and angular momentum). Second index corresponds to angular momentum vector. `L_cart` is the number of Cartesian contractions for the given angular momentum. Third index corresponds to coordinates at which the contractions are evaluated. `N` is the number of coordinates at which the contractions are evaluated. Raises ------ TypeError If contractions is not a GeneralizedContractionShell instance. If points is not a two-dimensional numpy array with 3 columns. Note ---- Since all of the keyword arguments of `construct_array_cartesian`, `construct_array_spherical`, and `construct_array_lincomb` are ultimately passed down to this method, all of the mentioned methods must be called with the keyword arguments `points` and `orders`. """ if not isinstance(contractions, GeneralizedContractionShell): raise TypeError( "`contractions` must be a GeneralizedContractionShell instance." ) if not (isinstance(points, np.ndarray) and points.ndim == 2 and points.shape[1] == 3): raise TypeError( "`points` must be given as a two-dimensional numpy array with 3 columnms." ) alphas = contractions.exps prim_coeffs = contractions.coeffs angmom_comps = contractions.angmom_components_cart center = contractions.coord norm_prim_cart = contractions.norm_prim_cart output = _eval_deriv_contractions(points, np.zeros(3), center, angmom_comps, alphas, prim_coeffs, norm_prim_cart) return output
def test_evaluate_construct_array_contraction(): """Test gbasis.evals.eval.Eval.construct_array_contraction.""" test = GeneralizedContractionShell(1, np.array([0.5, 1, 1.5]), np.array([1.0, 2.0]), np.array([0.1, 0.01])) answer = np.array([ _eval_deriv_contractions( np.array([[2, 3, 4]]), np.array([0, 0, 0]), np.array([0.5, 1, 1.5]), np.array([angmom_comp]), np.array([0.1, 0.01]), np.array([1, 2]), np.array([[ (2 * 0.1 / np.pi)**(3 / 4) * (4 * 0.1)**(1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), (2 * 0.01 / np.pi)**(3 / 4) * (4 * 0.01)**(1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), ]]), ) for angmom_comp in test.angmom_components_cart ]).reshape(3, 1) assert np.allclose( Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions=test), answer) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions=None) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions={1: 2}) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([2, 3, 4]), contractions=test) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[3, 4]]), contractions=test)
def evaluate_deriv_prim(coord, orders, center, angmom_comps, alpha): """Return the evaluation of the derivative of a Gaussian primitive. Parameters ---------- coord : np.ndarray(3,) Point in space where the derivative of the Gaussian primitive is evaluated. orders : np.ndarray(3,) Orders of the derivative. Negative orders are treated as zero orders. center : np.ndarray(3,) Center of the Gaussian primitive. angmom_comps : np.ndarray(3,) Component of the angular momentum that corresponds to this dimension. alpha : float Value of the exponential in the Guassian primitive. Returns ------- derivative : float Evaluation of the derivative. Note ---- If you want to evaluate the derivative of the contractions of the primitive, then use `gbasis.evals._deriv.evaluate_deriv_contraction` instead. """ return _eval_deriv_contractions( coord.reshape(1, 3), orders, center, angmom_comps.reshape(1, 3), np.array([alpha]), np.array([1.0]), np.array([[1]]), )[0]
def test_evaluate_deriv_construct_array_contraction(): """Test gbasis.evals.evaluate_deriv.EvalDeriv.construct_array_contraction.""" points = np.array([[2, 3, 4]]) orders = np.array([0, 0, 0]) contractions = GeneralizedContractionShell( 1, np.array([0.5, 1, 1.5]), np.array([1.0, 2.0]), np.array([0.1, 0.01]) ) with pytest.raises(TypeError): EvalDeriv.construct_array_contraction( points=[[2, 3, 4]], orders=orders, contractions=contractions ) with pytest.raises(TypeError): EvalDeriv.construct_array_contraction( points=points, orders=[0, 0, 0], contractions=contractions ) with pytest.raises(TypeError): EvalDeriv.construct_array_contraction( points=points, orders=orders, contractions=contractions.__dict__ ) with pytest.raises(TypeError): EvalDeriv.construct_array_contraction( points=points.reshape(3, 1), orders=orders, contractions=contractions ) with pytest.raises(TypeError): EvalDeriv.construct_array_contraction( points=points, orders=orders.reshape(1, 3), contractions=contractions ) with pytest.raises(ValueError): EvalDeriv.construct_array_contraction( points=points, orders=np.array([-1, 0, 0]), contractions=contractions ) with pytest.raises(ValueError): EvalDeriv.construct_array_contraction( points=points, orders=np.array([0.0, 0, 0]), contractions=contractions ) # first order for k in range(3): orders = np.zeros(3, dtype=int) orders[k] = 1 test = GeneralizedContractionShell( 1, np.array([0.5, 1, 1.5]), np.array([1.0, 2.0]), np.array([0.1, 0.01]) ) answer = np.array( [ _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([angmom_comp]), np.array([0.1, 0.01]), np.array([1, 2]), np.array( [ [ (2 * 0.1 / np.pi) ** (3 / 4) * (4 * 0.1) ** (1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), (2 * 0.01 / np.pi) ** (3 / 4) * (4 * 0.01) ** (1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), ] ] ), ) for angmom_comp in test.angmom_components_cart ] ).reshape(3, 1) assert np.allclose( EvalDeriv.construct_array_contraction( points=np.array([[2, 3, 4]]), orders=orders, contractions=test ), answer, ) # second order for k, l in it.product(range(3), range(3)): orders = np.zeros(3, dtype=int) orders[k] += 1 orders[l] += 1 test = GeneralizedContractionShell( 1, np.array([0.5, 1, 1.5]), np.array([1.0, 2.0]), np.array([0.1, 0.01]) ) answer = np.array( [ _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([angmom_comp]), np.array([0.1, 0.01]), np.array([1, 2]), np.array( [ [ (2 * 0.1 / np.pi) ** (3 / 4) * (4 * 0.1) ** (1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), (2 * 0.01 / np.pi) ** (3 / 4) * (4 * 0.01) ** (1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), ] ] ), ) for angmom_comp in test.angmom_components_cart ] ).reshape(3, 1) assert np.allclose( EvalDeriv.construct_array_contraction( points=np.array([[2, 3, 4]]), orders=orders, contractions=test ), answer, )
def construct_array_contraction(contractions, points, orders): r"""Return the array associated with a set of contracted Cartesian Gaussians. Parameters ---------- contractions : GeneralizedContractionShell Contracted Cartesian Gaussians (of the same shell) that will be used to construct an array. points : np.ndarray(N, 3) Cartesian coordinates of the points in space (in atomic units) where the basis functions are evaluated. Rows correspond to the points and columns correspond to the :math:`x, y, \text{and} z` components. orders : np.ndarray(3,) Orders of the derivative. Returns ------- array_contraction : np.ndarray(M, L_cart, N) Array associated with the given instance(s) of GeneralizedContractionShell. Dimension 0 corresponds to segmented contractions within the given generalized contraction (same exponents and angular momentum, but different coefficients). `M` is the number of segmented contractions with the same exponents (and angular momentum). Dimension 1 corresponds to angular momentum vector. `L_cart` is the number of Cartesian contractions for the given angular momentum. Dimension 2 corresponds to coordinates at which the contractions are evaluated. `N` is the number of coordinates at which the contractions are evaluated. Raises ------ TypeError If contractions is not a `GeneralizedContractionShell` instance. If points is not a two-dimensional `numpy` array with 3 columns. If orders is not a one-dimensional `numpy` array with 3 elements. ValueError If orders has any negative numbers. If orders does not have `dtype` int. Note ---- Since all of the keyword arguments of `construct_array_cartesian`, `construct_array_spherical`, and `construct_array_lincomb` are ultimately passed down to this method, all of the mentioned methods must be called with the keyword arguments `points` and `orders`. """ if not isinstance(contractions, GeneralizedContractionShell): raise TypeError( "`contractions` must be a `GeneralizedContractionShell` instance." ) if not (isinstance(points, np.ndarray) and points.ndim == 2 and points.shape[1] == 3): raise TypeError( "`points` must be given as a two-dimensional `numpy` array with 3 columns." ) if not (isinstance(orders, np.ndarray) and orders.shape == (3, )): raise TypeError( "Orders of the derivatives must be a one-dimensional `numpy` array with 3 elements." ) if np.any(orders < 0): raise ValueError("Negative order of derivative is not supported.") if orders.dtype != int: raise ValueError( "Orders of the derivatives must be given as integers.") alphas = contractions.exps prim_coeffs = contractions.coeffs angmom_comps = contractions.angmom_components_cart center = contractions.coord norm_prim_cart = contractions.norm_prim_cart output = _eval_deriv_contractions(points, orders, center, angmom_comps, alphas, prim_coeffs, norm_prim_cart) return output
def test_evaluate_deriv_generalized_contraction(): """Test gbasis.evals._deriv._eval_deriv_contractions for generalized contractions.""" for k, l in it.product(range(3), range(3)): orders = np.zeros(3, dtype=int) orders[k] += 1 orders[l] += 1 for x, y, z in it.product(range(4), range(4), range(4)): # only contraction assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z]]), np.array([1, 2]), np.array([[3, 4, 5], [6, 7, 8]]), np.array([[1, 1]]), ), np.array( [ 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 6 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 7 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), 5 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 8 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), ] ).reshape(3, 1, 1), ) # contraction + multiple angular momentums assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z], [x - 1, y + 2, z + 1]]), np.array([1, 2]), np.array([[3, 4, 5], [6, 7, 8]]), np.array([[1, 1]]), ), np.array( [ [ 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 6 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 1, ) + 6 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 2, ), ], [ 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 7 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 1, ) + 7 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 2, ), ], [ 5 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1, ) + 8 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2, ), 5 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 1, ) + 8 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 2, ), ], ] ), )
def test_eval_deriv_contractions(): """Test gbasis.evals._deriv._eval_deriv_contractions.""" # first order for k in range(3): orders = np.zeros(3, dtype=int) orders[k] = 1 for x, y, z in it.product(range(3), range(3), range(3)): # only contraction assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z]]), np.array([1, 2]), np.array([3, 4]), np.array([[1, 1]]), ), 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1 ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2 ), ) # contraction + multiple angular momentums assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z], [x - 1, y + 2, z + 1]]), np.array([1, 2]), np.array([3, 4]), np.array([[1, 1]]), ), [ 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1 ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2 ), 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 1, ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 2, ), ], ) # second order for k, l in it.product(range(3), range(3)): orders = np.zeros(3, dtype=int) orders[k] += 1 orders[l] += 1 for x, y, z in it.product(range(4), range(4), range(4)): assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z]]), np.array([1]), np.array([1]), np.array([[1]]), ), evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1 ), ) # only contraction assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z]]), np.array([1, 2]), np.array([3, 4]), np.array([[1, 1]]), ), 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1 ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2 ), ) # contraction + multiple angular momentums assert np.allclose( _eval_deriv_contractions( np.array([[2, 3, 4]]), orders, np.array([0.5, 1, 1.5]), np.array([[x, y, z], [x - 1, y + 2, z + 1]]), np.array([1, 2]), np.array([3, 4]), np.array([[1, 1]]), ), [ 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 1 ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x, y, z]), 2 ), 3 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 1, ) + 4 * evaluate_deriv_prim( np.array([2, 3, 4]), orders, np.array([0.5, 1, 1.5]), np.array([x - 1, y + 2, z + 1]), 2, ), ], )
def test_evaluate_contractions(): """Test gbasis.evals._deriv._evaluate_deriv_contraction without derivatization.""" # angular momentum: 0 assert np.allclose( _eval_deriv_contractions( np.array([[0, 0, 0]]), np.array([0, 0, 0]), np.array([0, 0, 0]), np.array([[0, 0, 0]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), 1, ) assert np.allclose( _eval_deriv_contractions( np.array([[1.0, 0, 0]]), np.array([0, 0, 0]), np.array([0, 0, 0]), np.array([[0, 0, 0]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), np.exp(-1), ) assert np.allclose( _eval_deriv_contractions( np.array([[1.0, 2.0, 0]]), np.array([0, 0, 0]), np.array([0, 0, 0]), np.array([[0, 0, 0]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), np.exp(-1) * np.exp(-4), ) assert np.allclose( _eval_deriv_contractions( np.array([[1.0, 2.0, 3.0]]), np.array([0, 0, 0]), np.array([0, 0, 0]), np.array([[0, 0, 0]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), np.exp(-1) * np.exp(-4) * np.exp(-9), ) # angular momentum 1 assert np.allclose( _eval_deriv_contractions( np.array([[2.0, 0, 0]]), np.array([0, 0, 0]), np.array([0, 0, 0]), np.array([[1, 0, 0]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), 2 * np.exp(-2 ** 2), ) # other angular momentum assert np.allclose( _eval_deriv_contractions( np.array([[2.0, 0, 0]]), np.array([0, 0, 0]), np.array([0, 3, 4]), np.array([[2, 1, 3]]), np.array([1.0]), np.array([1.0]), np.array([[1.0]]), ), 4 * 3 * 4 ** 3 * np.exp(-(2 ** 2 + 3 ** 2 + 4 ** 2)), ) # contraction assert np.allclose( _eval_deriv_contractions( np.array([[2, 0, 0]]), np.array([0, 0, 0]), np.array([0, 3, 4]), np.array([[2, 1, 3]]), np.array([0.1, 0.001]), np.array([3, 4]), np.array([[1.0, 1.0]]), ), 3 * (2 ** 2 * (-3) ** 1 * (-4) ** 3 * np.exp(-0.1 * (2 ** 2 + 3 ** 2 + 4 ** 2))) + 4 * (2 ** 2 * (-3) ** 1 * (-4) ** 3 * np.exp(-0.001 * (2 ** 2 + 3 ** 2 + 4 ** 2))), ) # contraction + multiple angular momentums assert np.allclose( _eval_deriv_contractions( np.array([[2, 0, 0]]), np.array([0, 0, 0]), np.array([0, 3, 4]), np.array([[2, 1, 3], [1, 3, 4]]), np.array([0.1, 0.001]), np.array([3, 4]), np.array([[1.0, 1.0], [1.0, 1.0]]), ), [ [ 3 * (2 ** 2 * (-3) ** 1 * (-4) ** 3 * np.exp(-0.1 * (2 ** 2 + 3 ** 2 + 4 ** 2))) + 4 * (2 ** 2 * (-3) ** 1 * (-4) ** 3 * np.exp(-0.001 * (2 ** 2 + 3 ** 2 + 4 ** 2))) ], [ 3 * (2 ** 1 * (-3) ** 3 * (-4) ** 4 * np.exp(-0.1 * (2 ** 2 + 3 ** 2 + 4 ** 2))) + 4 * (2 ** 1 * (-3) ** 3 * (-4) ** 4 * np.exp(-0.001 * (2 ** 2 + 3 ** 2 + 4 ** 2))) ], ], )