Ejemplo n.º 1
0
def test_contruct_array_lincomb():
    """Test BaseOneIndex.construct_array_lincomb."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    sph_transform = generate_transformation(
        1, contractions.angmom_components_cart, contractions.angmom_components_sph, "left"
    )
    orb_transform = np.random.rand(3, 3)

    Test = disable_abstract(  # noqa: N806
        BaseOneIndex,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont, a=2: np.arange(
                9, dtype=float
            ).reshape(1, 3, 3)
            * a
        },
    )
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "cartesian"),
        orb_transform.dot(np.arange(9).reshape(3, 3)) * 2,
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical"),
        orb_transform.dot(sph_transform).dot(np.arange(9).reshape(3, 3)) * 2,
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical", a=3),
        orb_transform.dot(sph_transform).dot(np.arange(9).reshape(3, 3)) * 3,
    )
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "bad")
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "spherical", bad_keyword=3)

    orb_transform = np.random.rand(3, 6)
    test = Test([contractions, contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical"),
        orb_transform.dot(
            np.vstack([sph_transform.dot(np.arange(9, dtype=float).reshape(3, 3)) * 2] * 2)
        ),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, ["spherical", "cartesian"]),
        orb_transform.dot(
            np.vstack(
                [
                    sph_transform.dot(np.arange(9, dtype=float).reshape(3, 3)) * 2,
                    np.arange(9, dtype=float).reshape(3, 3) * 2,
                ]
            )
        ),
    )
Ejemplo n.º 2
0
    def construct_array_spherical(self, **kwargs):
        """Return the array associated with contracted spherical Gaussians (atomic orbitals).

        Parameters
        ----------
        kwargs : dict
            Other keyword arguments that will be used to construct the array.
            These keyword arguments are passed entirely to `construct_array_contraction`. See
            `construct_array_contraction` for details on the keyword arguments.

        Returns
        -------
        array : np.ndarray(K_sph, ...)
            Array associated with the atomic orbitals associated with the given set of contracted
            Cartesian Gaussians.
            Dimension 0 is associated with the contracted spherical Gaussian. `K_sph` is the
            total number of Cartesian contractions within the instance.

        """
        matrices_spherical = []
        for cont in self.contractions:
            # get transformation from cartesian to spherical (applied to left)
            transform = generate_transformation(cont.angmom,
                                                cont.angmom_components_cart,
                                                cont.angmom_components_sph,
                                                "left")
            # evaluate the function at the given points
            matrix_contraction = self.construct_array_contraction(
                cont, **kwargs)
            # normalize contractions
            matrix_contraction *= cont.norm_cont.reshape(
                *matrix_contraction.shape[:2],
                *[1 for _ in matrix_contraction.shape[2:]])
            # transform
            # ASSUME array always has shape (M, L, ...)
            matrix_contraction = np.tensordot(transform, matrix_contraction,
                                              (1, 1))
            matrix_contraction = np.concatenate(np.swapaxes(
                matrix_contraction, 0, 1),
                                                axis=0)
            # store
            matrices_spherical.append(matrix_contraction)

        return np.concatenate(matrices_spherical, axis=0)
Ejemplo n.º 3
0
    def construct_array_mix(self, coord_types, **kwargs):
        """Return the array associated with set of Gaussians of the given coordinate systems.

        Parameters
        ----------
        coord_types : list/tuple of str
            Types of the coordinate system for each GeneralizedContractionShell.
            Each entry must be one of "cartesian" or "spherical".
        kwargs : dict
            Other keyword arguments that will be used to construct the array.

        Returns
        -------
        array : np.ndarray(K_cont, K_cont, ...)
            Array associated with the atomic orbitals associated with the given set of contracted
            Cartesian Gaussians.
            First and second indices of the array are associated with two contractions in the given
            coordinate system. `K_cont` is the total number of contractions within the instance.

        Raises
        ------
        TypeError
            If `coord_types` is not a list/tuple.
        ValueError
            If `coord_types` has an entry that is not "cartesian" or "spherical".
            If `coord_types` has different number of entries as the number of
            GeneralizedContractionShell (`contractions`) in instance.

        """
        if not isinstance(coord_types, (list, tuple)):
            raise TypeError("`coord_types` must be a list or a tuple.")
        if not all(i in ["cartesian", "spherical"] for i in coord_types):
            raise ValueError(
                "Each entry of `coord_types` must be one of 'cartesian' or 'spherical'."
            )
        if len(coord_types) != len(self.contractions):
            raise ValueError(
                "`coord_types` must have the same number of entries as the number of "
                "GeneralizedContractionShell in the instance.")

        triu_blocks = []
        for i, (cont_one,
                type_one) in enumerate(zip(self.contractions, coord_types)):
            # get transformation from cartesian to spherical (applied to left)
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            for cont_two, type_two in zip(self.contractions[i:],
                                          coord_types[i:]):
                transform_two = generate_transformation(
                    cont_two.angmom,
                    cont_two.angmom_components_cart,
                    cont_two.angmom_components_sph,
                    "left",
                )
                # evaluate
                block = self.construct_array_contraction(
                    cont_one, cont_two, **kwargs)
                # normalize contractions
                block *= cont_one.norm_cont.reshape(
                    *block.shape[:2], *[1 for i in block.shape[2:]])
                block *= cont_two.norm_cont.reshape(
                    1, 1, *block.shape[2:4], *[1 for i in block.shape[4:]])
                # assume array has shape (M_1, L_1, M_2, L_2, ...)
                if type_one == "spherical":
                    # transform
                    block = np.tensordot(transform_one, block, (1, 1))
                    block = np.swapaxes(block, 0, 1)
                block = np.concatenate(block, axis=0)
                # array now has shape (M_1 L_1, M_2, L_2, ...)
                if type_two == "spherical":
                    block = np.tensordot(transform_two, block, (1, 2))
                    block = np.swapaxes(np.swapaxes(block, 0, 1), 0, 2)
                else:
                    block = np.swapaxes(np.swapaxes(block, 0, 1), 1, 2)
                block = np.concatenate(block, axis=0)
                block = np.swapaxes(block, 0, 1)
                # array now has shape (M_1 L_1, M_2 L_2, ...)
                # store
                triu_blocks.append(block)
        # use numpy triu and tril indices to create blocks
        num_blocks_side = len(self.contractions)
        all_blocks = np.zeros((num_blocks_side, num_blocks_side), dtype=object)
        all_blocks[np.triu_indices(num_blocks_side)] = triu_blocks
        all_blocks[np.tril_indices(num_blocks_side)] = [
            np.swapaxes(block, 0, 1)
            for block in all_blocks.T[np.tril_indices(num_blocks_side)]
        ]
        # concatenate
        return np.concatenate(
            [np.concatenate(row_blocks, axis=1) for row_blocks in all_blocks],
            axis=0)
Ejemplo n.º 4
0
    def construct_array_spherical(self, **kwargs):
        """Return the array associated with two contracted spherical Gaussians (atomic orbitals).

        Parameters
        ----------
        kwargs : dict
            Other keyword arguments that will be used to construct the array.
            These keyword arguments are passed entirely to `construct_array_contraction`. See
            `construct_array_contraction` for details on the keyword arguments.

        Returns
        -------
        array : np.ndarray(K_sph, K_sph, ...)
            Array associated with the atomic orbitals associated with the given set(s) of contracted
            Cartesian Gaussians.
            First and second indices of the array are associated with two contracted spherical
            Gaussians (atomic orbitals). `K_sph` is the total number of spherical contractions
            within the instance.

        Notes
        -----
        The blocks along the diagonal, i.e. blocks where the first two axes belong to the same
        set of contractions, are transposed in the process of constructing the whole array.
        It is assumed that the array returned from `construct_array_contraction` is symmetric with
        respect to the swapping of the first and second axes.

        """
        triu_blocks = []
        for i, cont_one in enumerate(self.contractions):
            # get transformation from cartesian to spherical (applied to left)
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            for cont_two in self.contractions[i:]:
                transform_two = generate_transformation(
                    cont_two.angmom,
                    cont_two.angmom_components_cart,
                    cont_two.angmom_components_sph,
                    "left",
                )
                # evaluate
                block_sph = self.construct_array_contraction(
                    cont_one, cont_two, **kwargs)
                # normalize contractions
                block_sph *= cont_one.norm_cont.reshape(
                    *block_sph.shape[:2], *[1 for i in block_sph.shape[2:]])
                block_sph *= cont_two.norm_cont.reshape(
                    1, 1, *block_sph.shape[2:4],
                    *[1 for i in block_sph.shape[4:]])
                # assume array has shape (M_1, L_1, M_2, L_2, ...)
                # transform
                block_sph = np.tensordot(transform_one, block_sph, (1, 1))
                block_sph = np.concatenate(np.swapaxes(block_sph, 0, 1),
                                           axis=0)
                # array now has shape (M_1 L_1, M_2, L_2, ...)
                block_sph = np.tensordot(transform_two, block_sph, (1, 2))
                block_sph = np.swapaxes(np.swapaxes(block_sph, 0, 1), 0, 2)
                block_sph = np.concatenate(block_sph, axis=0)
                block_sph = np.swapaxes(block_sph, 0, 1)
                # array now has shape (M_1 L_1, M_2 L_2, ...)
                # store
                triu_blocks.append(block_sph)
        # use numpy triu and tril indices to create blocks
        num_blocks_side = len(self.contractions)
        all_blocks = np.zeros((num_blocks_side, num_blocks_side), dtype=object)
        all_blocks[np.triu_indices(num_blocks_side)] = triu_blocks
        all_blocks[np.tril_indices(num_blocks_side)] = [
            np.swapaxes(block, 0, 1)
            for block in all_blocks.T[np.tril_indices(num_blocks_side)]
        ]
        # concatenate
        return np.concatenate(
            [np.concatenate(row_blocks, axis=1) for row_blocks in all_blocks],
            axis=0)
Ejemplo n.º 5
0
    def construct_array_mix(self, coord_types_one, coord_types_two, **kwargs):
        """Return the array associated with set of Gaussians of the given coordinate systems.

        Parameters
        ----------
        coord_types_one : list/tuple of str
            Types of the coordinate system for GeneralizedContractionShell associated with the
            first index of the array.
            Each entry must be one of "cartesian" or "spherical".
        coord_types_two : list/tuple of str
            Types of the coordinate system for GeneralizedContractionShell associated with the
            second index of the array.
            Each entry must be one of "cartesian" or "spherical".
        kwargs : dict
            Other keyword arguments that will be used to construct the array.

        Returns
        -------
        array : np.ndarray(K_cont, K_cont, ...)
            Array associated with the atomic orbitals associated with the given set of contracted
            Cartesian Gaussians.
            First and second indices of the array are associated with two contractions in the given
            coordinate system. `K_cont` is the total number of contractions within the instance.

        Raises
        ------
        TypeError
            If `coord_types_one` is not a list/tuple.
            If `coord_types_two` is not a list/tuple.
        ValueError
            If `coord_types_one` has an entry that is not "cartesian" or "spherical".
            If `coord_types_one` has different number of entries as the number of
            GeneralizedContractionShell (`contractions`) in instance.
            If `coord_types_two` has an entry that is not "cartesian" or "spherical".
            If `coord_types_two` has different number of entries as the number of
            GeneralizedContractionShell (`contractions`) in instance.

        """
        if not isinstance(coord_types_one, (list, tuple)):
            raise TypeError("`coord_types_one` must be a list or a tuple.")
        if not isinstance(coord_types_two, (list, tuple)):
            raise TypeError("`coord_types_two` must be a list or a tuple.")
        if not all(i in ["cartesian", "spherical"] for i in coord_types_one):
            raise ValueError(
                "Each entry of `coord_types_one` must be one of 'cartesian' or 'spherical'."
            )
        if not all(i in ["cartesian", "spherical"] for i in coord_types_two):
            raise ValueError(
                "Each entry of `coord_types_two` must be two of 'cartesian' or 'spherical'."
            )
        if len(coord_types_one) != len(self.contractions_one):
            raise ValueError(
                "`coord_types_one` must have the same number of entries as the number of "
                "GeneralizedContractionShell in the instance.")
        if len(coord_types_two) != len(self.contractions_two):
            raise ValueError(
                "`coord_types_two` must have the same number of entries as the number of "
                "GeneralizedContractionShell in the instance.")

        matrices_spherical = []
        for cont_one, type_one in zip(self.contractions_one, coord_types_one):
            # get transformation from cartesian to spherical for the first index (applied to left)
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            matrices_spherical_cols = []
            for cont_two, type_two in zip(self.contractions_two,
                                          coord_types_two):
                # get transformation from cartesian to spherical for the first index (applied to
                # left)
                transform_two = generate_transformation(
                    cont_two.angmom,
                    cont_two.angmom_components_cart,
                    cont_two.angmom_components_sph,
                    "left",
                )
                # evaluate
                block = self.construct_array_contraction(
                    cont_one, cont_two, **kwargs)
                # normalize contractions
                block *= cont_one.norm_cont.reshape(
                    *block.shape[:2], *[1 for i in block.shape[2:]])
                block *= cont_two.norm_cont.reshape(
                    1, 1, *block.shape[2:4], *[1 for i in block.shape[4:]])
                # transform
                # assume array always has shape (M_1, L_1, M_2, L_2, ...)
                if type_one == "spherical":
                    block = np.tensordot(transform_one, block, (1, 1))
                    block = np.swapaxes(block, 0, 1)
                block = np.concatenate(block, axis=0)
                # array now has shape (M_1 L_1, M_2, L_2, ...)
                if type_two == "spherical":
                    block = np.tensordot(transform_two, block, (1, 2))
                    block = np.swapaxes(np.swapaxes(block, 0, 1), 0, 2)
                else:
                    block = np.swapaxes(np.swapaxes(block, 0, 1), 1, 2)
                block = np.concatenate(block, axis=0)
                block = np.swapaxes(block, 0, 1)
                # array now has shape (M_1 L_1, M_2 L_2, ...)
                # store
                matrices_spherical_cols.append(block)
            matrices_spherical.append(
                np.concatenate(matrices_spherical_cols, axis=1))
        return np.concatenate(matrices_spherical, axis=0)
Ejemplo n.º 6
0
    def construct_array_spherical(self, **kwargs):
        """Return the array associated with two contracted spherical Gaussians (atomic orbitals).

        Parameters
        ----------
        kwargs : dict
            Other keyword arguments that will be used to construct the array.
            These keyword arguments are passed entirely to `construct_array_contraction`. See
            `construct_array_contraction` for details on the keyword arguments.

        Returns
        -------
        array : np.ndarray(K_sph_1, K_sph_2, ...)
            Array associated with the atomic orbitals associated with the given set(s) of contracted
            Cartesian Gaussians.
            First index corresponds to the spherical contraction within the `contractions_one`.
            `K_sph_1` is the total number of spherical contractions within the `contractions_one`.
            Second index corresponds to the spherical contraction within the `contractions_two`.
            `K_sph_2` is the total number of spherical contractions within the `contractions_two`.

        """
        matrices_spherical = []
        for cont_one in self.contractions_one:
            # get transformation from cartesian to spherical for the first index (applied to left)
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            matrices_spherical_cols = []
            for cont_two in self.contractions_two:
                # get transformation from cartesian to spherical for the first index (applied to
                # left)
                transform_two = generate_transformation(
                    cont_two.angmom,
                    cont_two.angmom_components_cart,
                    cont_two.angmom_components_sph,
                    "left",
                )
                # evaluate
                matrix_contraction = self.construct_array_contraction(
                    cont_one, cont_two, **kwargs)
                # normalize contractions
                matrix_contraction *= cont_one.norm_cont.reshape(
                    *matrix_contraction.shape[:2],
                    *[1 for i in matrix_contraction.shape[2:]])
                matrix_contraction *= cont_two.norm_cont.reshape(
                    1, 1, *matrix_contraction.shape[2:4],
                    *[1 for i in matrix_contraction.shape[4:]])
                # transform
                # assume array always has shape (M_1, L_1, M_2, L_2, ...)
                matrix_contraction = np.tensordot(transform_one,
                                                  matrix_contraction, (1, 1))
                matrix_contraction = np.concatenate(np.swapaxes(
                    matrix_contraction, 0, 1),
                                                    axis=0)
                # array now has shape (M_1 L_1, M_2, L_2, ...)
                matrix_contraction = np.tensordot(transform_two,
                                                  matrix_contraction, (1, 2))
                matrix_contraction = np.swapaxes(
                    np.swapaxes(matrix_contraction, 0, 1), 0, 2)
                matrix_contraction = np.concatenate(matrix_contraction, axis=0)
                matrix_contraction = np.swapaxes(matrix_contraction, 0, 1)
                # array now has shape (M_1 L_1, M_2 L_2, ...)
                # store
                matrices_spherical_cols.append(matrix_contraction)
            matrices_spherical.append(
                np.concatenate(matrices_spherical_cols, axis=1))
        return np.concatenate(matrices_spherical, axis=0)
Ejemplo n.º 7
0
def test_contruct_array_spherical():
    """Test BaseOneIndex.construct_array_spherical."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    transform = generate_transformation(
        1, contractions.angmom_components_cart, contractions.angmom_components_sph, "left"
    )

    Test = disable_abstract(  # noqa: N806
        BaseOneIndex,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont, a=2: np.arange(
                9, dtype=float
            ).reshape(1, 3, 3)
            * a
        },
    )
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_spherical(), transform.dot(np.arange(9).reshape(3, 3)) * 2
    )
    assert np.allclose(
        test.construct_array_spherical(a=3), transform.dot(np.arange(9).reshape(3, 3)) * 3
    )
    with pytest.raises(TypeError):
        test.construct_array_spherical(bad_keyword=3)

    test = Test([contractions, contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack([transform.dot(np.arange(9).reshape(3, 3)) * 2] * 2),
    )

    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones((1, 2)), np.ones(1))
    Test = disable_abstract(  # noqa: N806
        BaseOneIndex,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont, a=2: np.arange(18, dtype=float).reshape(2, 3, 3) * a
            )
        },
    )
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack(
            [
                transform.dot(np.arange(9).reshape(3, 3)),
                transform.dot(np.arange(9, 18).reshape(3, 3)),
            ]
        )
        * 2,
    )
    assert np.allclose(
        test.construct_array_spherical(a=3),
        np.vstack(
            [
                transform.dot(np.arange(9).reshape(3, 3)),
                transform.dot(np.arange(9, 18).reshape(3, 3)),
            ]
        )
        * 3,
    )

    test = Test([contractions, contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack(
            [
                transform.dot(np.arange(9).reshape(3, 3)),
                transform.dot(np.arange(9, 18).reshape(3, 3)),
            ]
            * 2
        )
        * 2,
    )
Ejemplo n.º 8
0
def test_contruct_array_spherical():
    """Test BaseTwoIndexAsymmetric.construct_array_spherical."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]),
                                               np.ones(1), np.ones(1))
    transform = generate_transformation(1, contractions.angmom_components_cart,
                                        contractions.angmom_components_sph,
                                        "left")

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexAsymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, a=2: np.arange(9, dtype=float).reshape(1, 3, 1, 3)
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))

    test = Test([contractions], [contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        transform.dot(np.arange(9).reshape(3, 3)).dot(transform.T) * 2,
    )
    assert np.allclose(
        test.construct_array_spherical(a=3),
        transform.dot(np.arange(9).reshape(3, 3)).dot(transform.T) * 3,
    )
    with pytest.raises(TypeError):
        test.construct_array_spherical(bad_keyword=3)

    test = Test([contractions, contractions], [contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack(
            [transform.dot(np.arange(9).reshape(3, 3).dot(transform.T)) * 2] *
            2),
    )

    matrix = np.arange(36, dtype=float).reshape(2, 3, 2, 3)
    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexAsymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, a=2: matrix * a
        },
    )
    contractions.norm_cont = np.ones((2, 3))
    test = Test([contractions], [contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack([
            np.hstack([
                transform.dot(matrix[0, :, 0, :]).dot(transform.T),
                transform.dot(matrix[0, :, 1, :]).dot(transform.T),
            ]),
            np.hstack([
                transform.dot(matrix[1, :, 0, :]).dot(transform.T),
                transform.dot(matrix[1, :, 1, :]).dot(transform.T),
            ]),
        ]) * 2,
    )
    test = Test([contractions, contractions], [contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack([
            np.hstack([
                transform.dot(matrix[0, :, 0, :]).dot(transform.T),
                transform.dot(matrix[0, :, 1, :]).dot(transform.T),
            ]),
            np.hstack([
                transform.dot(matrix[1, :, 0, :]).dot(transform.T),
                transform.dot(matrix[1, :, 1, :]).dot(transform.T),
            ]),
        ] * 2) * 2,
    )
Ejemplo n.º 9
0
    def construct_array_spherical(self, **kwargs):
        """Return the array associated with four contracted spherical Gaussians (atomic orbitals).

        Parameters
        ----------
        kwargs : dict
            Other keyword arguments that will be used to construct the array.
            These keyword arguments are passed entirely to `construct_array_contraction`. See
            `construct_array_contraction` for details on the keyword arguments.

        Returns
        -------
        array : np.ndarray(K_sph, K_sph, K_sph, K_sph, ...)
            Array associated with the atomic orbitals associated with the given set(s) of contracted
            Cartesian Gaussians.
            Dimensions 0, 1, 2 and 3 of the array are associated with four contracted spherical
            Gaussians (atomic orbitals). `K_sph` is the total number of spherical contractions
            within the instance.

        Notes
        -----
        The blocks along the diagonal, i.e. blocks where the first two axes belong to the same
        set of contractions, are transposed in the process of constructing the whole array.
        It is assumed that the array returned from `construct_array_contraction` is symmetric with
        respect to the swapping of the axes 0 and 1.

        """
        # pylint: disable=C0103,R0914
        all_blocks = np.zeros((len(self.contractions),) * 4, dtype=object)
        # NOTE: we get list of unique pairs of (index, contraction_instance) to avoid double
        # counting the ij and kl. e.g. 0, 1, 0, 0 and 0, 0, 0, 1 will both be present with the
        # previous approach
        pair_i_cont = list(it.combinations_with_replacement(enumerate(self.contractions), 2))
        for pair_ind, ((i, cont_one), (j, cont_two)) in enumerate(pair_i_cont):
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            transform_two = generate_transformation(
                cont_two.angmom,
                cont_two.angmom_components_cart,
                cont_two.angmom_components_sph,
                "left",
            )
            for (k, cont_three), (l, cont_four) in pair_i_cont[pair_ind:]:
                transform_three = generate_transformation(
                    cont_three.angmom,
                    cont_three.angmom_components_cart,
                    cont_three.angmom_components_sph,
                    "left",
                )
                transform_four = generate_transformation(
                    cont_four.angmom,
                    cont_four.angmom_components_cart,
                    cont_four.angmom_components_sph,
                    "left",
                )

                block = self.construct_array_contraction(
                    cont_one, cont_two, cont_three, cont_four, **kwargs
                )
                # normalize contractions
                block *= cont_one.norm_cont.reshape(*block.shape[:2], *[1 for _ in block.shape[2:]])
                block *= cont_two.norm_cont.reshape(
                    1, 1, *block.shape[2:4], *[1 for _ in block.shape[4:]]
                )
                block *= cont_three.norm_cont.reshape(
                    1, 1, 1, 1, *block.shape[4:6], *[1 for _ in block.shape[6:]]
                )
                block *= cont_four.norm_cont.reshape(
                    1, 1, 1, 1, 1, 1, *block.shape[6:8], *[1 for _ in block.shape[8:]]
                )

                # transform
                block = np.tensordot(transform_one, block, (1, 1))
                block = np.swapaxes(block, 0, 1)
                block = np.tensordot(transform_two, block, (1, 3))
                block = np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3)
                block = np.tensordot(transform_three, block, (1, 5))
                block = np.swapaxes(
                    np.swapaxes(
                        np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3), 3, 4
                    ),
                    4,
                    5,
                )
                block = np.tensordot(transform_four, block, (1, 7))
                block = np.swapaxes(
                    np.swapaxes(
                        np.swapaxes(
                            np.swapaxes(
                                np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3), 3, 4
                            ),
                            4,
                            5,
                        ),
                        5,
                        6,
                    ),
                    6,
                    7,
                )

                # array has shape (M_1, L_1, M_2, L_2, M_3, L_3, M_4, L_4, ..)
                block = block.reshape(
                    block.shape[0] * block.shape[1],
                    block.shape[2] * block.shape[3],
                    block.shape[4] * block.shape[5],
                    block.shape[6] * block.shape[7],
                    *block.shape[8:],
                )
                # array now has shape (M_1 L_1, M_2 L_2, M_3, L_3, M_4, L_4, ...)
                all_blocks[i, j, k, l] = block
                all_blocks[i, j, l, k] = np.swapaxes(block, 2, 3)
                all_blocks[j, i, k, l] = np.swapaxes(block, 0, 1)
                all_blocks[j, i, l, k] = np.swapaxes(np.swapaxes(block, 2, 3), 0, 1)
                all_blocks[k, l, i, j] = np.swapaxes(np.swapaxes(block, 1, 3), 0, 2)
                all_blocks[l, k, i, j] = np.swapaxes(
                    np.swapaxes(np.swapaxes(block, 1, 3), 0, 2), 0, 1
                )
                all_blocks[k, l, j, i] = np.swapaxes(
                    np.swapaxes(np.swapaxes(block, 1, 3), 0, 2), 2, 3
                )
                all_blocks[l, k, j, i] = np.swapaxes(np.swapaxes(block, 1, 2), 0, 3)

        # concatenate
        return np.concatenate(
            [
                np.concatenate(
                    [
                        np.concatenate(
                            [np.concatenate(blocks_three, axis=3) for blocks_three in blocks_two],
                            axis=2,
                        )
                        for blocks_two in blocks_one
                    ],
                    axis=1,
                )
                for blocks_one in all_blocks
            ],
            axis=0,
        )
Ejemplo n.º 10
0
def test_contruct_array_lincomb():
    """Test BaseTwoIndexSymmetric.construct_array_lincomb."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]),
                                               np.ones(1), np.ones(1))
    sph_transform = generate_transformation(
        1, contractions.angmom_components_cart,
        contractions.angmom_components_sph, "left")
    orb_transform = np.random.rand(3, 3)

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, a=2: np.arange(9, dtype=float).reshape(1, 3, 1, 3)
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "cartesian"),
        (orb_transform.dot(np.arange(9).reshape(3, 3)).dot(orb_transform.T).T *
         2),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical"),
        (orb_transform.dot(sph_transform).dot(np.arange(9).reshape(3, 3)).dot(
            sph_transform.T).dot(orb_transform.T).T * 2),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical", a=3),
        (orb_transform.dot(sph_transform).dot(np.arange(9).reshape(3, 3)).dot(
            sph_transform.T).dot(orb_transform.T).T * 3),
    )
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "spherical", bad_keyword=3)
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "bad", keyword=3)

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, a=2: (
                np.arange(cont_one.num_cart * cont_two.num_cart * 2, dtype=float).reshape(
                    1, cont_one.num_cart, 1, cont_two.num_cart, 2
                )
                * a
            )
        },
    )
    cont_one = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1),
                                           np.ones(1))
    cont_two = GeneralizedContractionShell(2, np.array([1, 2, 3]), np.ones(1),
                                           np.ones(1))
    cont_one.norm_cont = np.ones((1, cont_one.num_cart))
    cont_two.norm_cont = np.ones((1, cont_two.num_cart))
    test = Test([cont_one, cont_two])
    sph_transform_one = generate_transformation(
        1, cont_one.angmom_components_cart, cont_one.angmom_components_sph,
        "left")
    sph_transform_two = generate_transformation(
        2, cont_two.angmom_components_cart, cont_two.angmom_components_sph,
        "left")
    orb_transform = np.random.rand(8, 8)
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical", a=4),
        np.swapaxes(
            np.tensordot(
                orb_transform,
                np.tensordot(
                    orb_transform,
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.tensordot(
                                        sph_transform_one,
                                        np.tensordot(
                                            sph_transform_one,
                                            np.arange(18).reshape(3, 3, 2),
                                            (1, 0),
                                        ),
                                        (1, 1),
                                    ) * 4,
                                    np.swapaxes(
                                        np.tensordot(
                                            sph_transform_two,
                                            np.tensordot(
                                                sph_transform_one,
                                                np.arange(36).reshape(3, 6, 2),
                                                (1, 0),
                                            ),
                                            (1, 1),
                                        ),
                                        0,
                                        1,
                                    ) * 4,
                                ],
                                axis=1,
                            ),
                            np.concatenate(
                                [
                                    np.tensordot(
                                        sph_transform_two,
                                        np.tensordot(
                                            sph_transform_one,
                                            np.arange(36).reshape(3, 6, 2),
                                            (1, 0),
                                        ),
                                        (1, 1),
                                    ) * 4,
                                    np.tensordot(
                                        sph_transform_two,
                                        np.tensordot(
                                            sph_transform_two,
                                            np.arange(72).reshape(6, 6, 2),
                                            (1, 0),
                                        ),
                                        (1, 1),
                                    ) * 4,
                                ],
                                axis=1,
                            ),
                        ],
                        axis=0,
                    ),
                    (1, 0),
                ),
                (1, 1),
            ),
            0,
            1,
        ),
    )
    orb_transform = np.random.rand(9, 9)
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, ("spherical", "cartesian"),
                                     a=4),
        np.swapaxes(
            np.tensordot(
                orb_transform,
                np.tensordot(
                    orb_transform,
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.tensordot(
                                        sph_transform_one,
                                        np.tensordot(
                                            sph_transform_one,
                                            np.arange(18).reshape(3, 3, 2),
                                            (1, 0),
                                        ),
                                        (1, 1),
                                    ) * 4,
                                    np.tensordot(
                                        sph_transform_one,
                                        np.arange(36).reshape(3, 6, 2),
                                        (1, 0)) * 4,
                                ],
                                axis=1,
                            ),
                            np.concatenate(
                                [
                                    np.swapaxes(
                                        np.tensordot(
                                            sph_transform_one,
                                            np.arange(36).reshape(3, 6, 2),
                                            (1, 0),
                                        ),
                                        0,
                                        1,
                                    ) * 4,
                                    np.swapaxes(
                                        np.arange(72).reshape(6, 6, 2), 0, 1) *
                                    4,
                                ],
                                axis=1,
                            ),
                        ],
                        axis=0,
                    ),
                    (1, 0),
                ),
                (1, 1),
            ),
            0,
            1,
        ),
    )
Ejemplo n.º 11
0
def test_contruct_array_spherical():
    """Test BaseTwoIndexSymmetric.construct_array_spherical."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]),
                                               np.ones(1), np.ones(1))
    transform = generate_transformation(1, contractions.angmom_components_cart,
                                        contractions.angmom_components_sph,
                                        "left")

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, a=2: np.arange(9, dtype=float).reshape(1, 3, 1, 3)
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_spherical(),
        (transform.dot(np.arange(9).reshape(3, 3)).dot(transform.T)).T * 2,
    )
    assert np.allclose(
        test.construct_array_spherical(a=3),
        (transform.dot(np.arange(9).reshape(3, 3)).dot(transform.T)).T * 3,
    )
    with pytest.raises(TypeError):
        test.construct_array_spherical(bad_keyword=3)

    cont_one = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1),
                                           np.ones(1))
    cont_two = GeneralizedContractionShell(2, np.array([1, 2, 3]), np.ones(1),
                                           np.ones(1))
    transform_one = generate_transformation(1, cont_one.angmom_components_cart,
                                            cont_one.angmom_components_sph,
                                            "left")
    transform_two = generate_transformation(2, cont_two.angmom_components_cart,
                                            cont_two.angmom_components_sph,
                                            "left")

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, a=2: (
                np.arange(cont_one.num_cart * cont_two.num_cart * 2, dtype=float).reshape(
                    1, cont_one.num_cart, 1, cont_two.num_cart, 2
                )
                * a
            )
        },
    )
    cont_one.norm_cont = np.ones((1, cont_one.num_cart))
    cont_two.norm_cont = np.ones((1, cont_two.num_cart))
    test = Test([cont_one, cont_two])
    assert np.allclose(
        test.construct_array_spherical(a=4),
        np.concatenate(
            [
                np.concatenate(
                    [
                        np.tensordot(
                            transform_one,
                            np.tensordot(transform_one,
                                         np.arange(18).reshape(3, 3, 2),
                                         (1, 0)),
                            (1, 1),
                        ) * 4,
                        np.swapaxes(
                            np.tensordot(
                                transform_two,
                                np.tensordot(transform_one,
                                             np.arange(36).reshape(3, 6, 2),
                                             (1, 0)),
                                (1, 1),
                            ),
                            0,
                            1,
                        ) * 4,
                    ],
                    axis=1,
                ),
                np.concatenate(
                    [
                        np.tensordot(
                            transform_two,
                            np.tensordot(transform_one,
                                         np.arange(36).reshape(3, 6, 2),
                                         (1, 0)),
                            (1, 1),
                        ) * 4,
                        np.tensordot(
                            transform_two,
                            np.tensordot(transform_two,
                                         np.arange(72).reshape(6, 6, 2),
                                         (1, 0)),
                            (1, 1),
                        ) * 4,
                    ],
                    axis=1,
                ),
            ],
            axis=0,
        ),
    )

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, a=2: (
                np.arange(2 * cont_one.num_cart * 2 * cont_two.num_cart, dtype=float).reshape(
                    2, cont_one.num_cart, 2, cont_two.num_cart
                )
                * a
            )
        },
    )
    cont_one.norm_cont = np.ones((2, cont_one.num_cart))
    cont_two.norm_cont = np.ones((2, cont_two.num_cart))
    test = Test([cont_one, cont_two])

    matrix_11 = np.arange(2 * cont_one.num_cart * 2 *
                          cont_one.num_cart).reshape(2, cont_one.num_cart, 2,
                                                     cont_one.num_cart)
    matrix_11 = np.swapaxes(np.tensordot(transform_one, matrix_11, (1, 1)), 0,
                            1)
    matrix_11 = np.moveaxis(np.tensordot(transform_one, matrix_11, (1, 3)), 0,
                            3)
    matrix_12 = np.arange(2 * cont_one.num_cart * 2 *
                          cont_two.num_cart).reshape(2, cont_one.num_cart, 2,
                                                     cont_two.num_cart)
    matrix_12 = np.swapaxes(np.tensordot(transform_one, matrix_12, (1, 1)), 0,
                            1)
    matrix_12 = np.moveaxis(np.tensordot(transform_two, matrix_12, (1, 3)), 0,
                            3)
    matrix_22 = np.arange(2 * cont_two.num_cart * 2 *
                          cont_two.num_cart).reshape(2, cont_two.num_cart, 2,
                                                     cont_two.num_cart)
    matrix_22 = np.swapaxes(np.tensordot(transform_two, matrix_22, (1, 1)), 0,
                            1)
    matrix_22 = np.moveaxis(np.tensordot(transform_two, matrix_22, (1, 3)), 0,
                            3)
    assert np.allclose(
        test.construct_array_spherical(),
        np.vstack([
            np.hstack([
                np.vstack([
                    np.hstack([matrix_11[0, :, 0, :], matrix_11[0, :, 1, :]]),
                    np.hstack([matrix_11[1, :, 0, :], matrix_11[1, :, 1, :]]),
                ]).T,
                np.vstack([
                    np.hstack([matrix_12[0, :, 0, :], matrix_12[0, :, 1, :]]),
                    np.hstack([matrix_12[1, :, 0, :], matrix_12[1, :, 1, :]]),
                ]),
            ]),
            np.hstack([
                np.vstack([
                    np.hstack([matrix_12[0, :, 0, :], matrix_12[0, :, 1, :]]),
                    np.hstack([matrix_12[1, :, 0, :], matrix_12[1, :, 1, :]]),
                ]).T,
                np.vstack([
                    np.hstack([matrix_22[0, :, 0, :], matrix_22[0, :, 1, :]]),
                    np.hstack([matrix_22[1, :, 0, :], matrix_22[1, :, 1, :]]),
                ]).T,
            ]),
        ]) * 2,
    )
Ejemplo n.º 12
0
def test_generate_transformation_horton_high_angmom():
    """Test spherical.generate_transformation using horton reference for high angular momentum.

    Answer obtained from https://github.com/theochem/horton/blob/master/horton/gbasis/cartpure.cpp.

    """
    # taken from HORTON's gbasis/cartpure.cpp
    horton_transform = [
        [0, 0, 0.375],
        [0, 3, 0.21957751641341996535],
        [0, 5, -0.87831006565367986142],
        [0, 10, 0.375],
        [0, 12, -0.87831006565367986142],
        [0, 14, 1.0],
        [1, 2, -0.89642145700079522998],
        [1, 7, -0.40089186286863657703],
        [1, 9, 1.19522860933439364],
        [2, 4, -0.40089186286863657703],
        [2, 11, -0.89642145700079522998],
        [2, 13, 1.19522860933439364],
        [3, 0, -0.5590169943749474241],
        [3, 5, 0.9819805060619657157],
        [3, 10, 0.5590169943749474241],
        [3, 12, -0.9819805060619657157],
        [4, 1, -0.42257712736425828875],
        [4, 6, -0.42257712736425828875],
        [4, 8, 1.1338934190276816816],
        [5, 2, 0.790569415042094833],
        [5, 7, -1.0606601717798212866],
        [6, 4, 1.0606601717798212866],
        [6, 11, -0.790569415042094833],
        [7, 0, 0.73950997288745200532],
        [7, 3, -1.2990381056766579701],
        [7, 10, 0.73950997288745200532],
        [8, 1, 1.1180339887498948482],
        [8, 6, -1.1180339887498948482],
    ]
    answer = np.zeros((9, 15))
    for i in horton_transform:
        answer[i[0], i[1]] = i[2]

    assert np.allclose(
        generate_transformation(
            4,
            np.array([
                [4, 0, 0],
                [3, 1, 0],
                [3, 0, 1],
                [2, 2, 0],
                [2, 1, 1],
                [2, 0, 2],
                [1, 3, 0],
                [1, 2, 1],
                [1, 1, 2],
                [1, 0, 3],
                [0, 4, 0],
                [0, 3, 1],
                [0, 2, 2],
                [0, 1, 3],
                [0, 0, 4],
            ]),
            (0, 1, -1, 2, -2, 3, -3, 4, -4),
            "left",
        ),
        answer,
    )

    # taken from HORTON's gbasis/cartpure.cpp
    horton_transform = [
        [0, 2, 0.625],
        [0, 7, 0.36596252735569994226],
        [0, 9, -1.0910894511799619063],
        [0, 16, 0.625],
        [0, 18, -1.0910894511799619063],
        [0, 20, 1.0],
        [1, 0, 0.48412291827592711065],
        [1, 3, 0.21128856368212914438],
        [1, 5, -1.2677313820927748663],
        [1, 10, 0.16137430609197570355],
        [1, 12, -0.56694670951384084082],
        [1, 14, 1.2909944487358056284],
        [2, 1, 0.16137430609197570355],
        [2, 6, 0.21128856368212914438],
        [2, 8, -0.56694670951384084082],
        [2, 15, 0.48412291827592711065],
        [2, 17, -1.2677313820927748663],
        [2, 19, 1.2909944487358056284],
        [3, 2, -0.85391256382996653193],
        [3, 9, 1.1180339887498948482],
        [3, 16, 0.85391256382996653193],
        [3, 18, -1.1180339887498948482],
        [4, 4, -0.6454972243679028142],
        [4, 11, -0.6454972243679028142],
        [4, 13, 1.2909944487358056284],
        [5, 0, -0.52291251658379721749],
        [5, 3, 0.22821773229381921394],
        [5, 5, 0.91287092917527685576],
        [5, 10, 0.52291251658379721749],
        [5, 12, -1.2247448713915890491],
        [6, 1, -0.52291251658379721749],
        [6, 6, -0.22821773229381921394],
        [6, 8, 1.2247448713915890491],
        [6, 15, 0.52291251658379721749],
        [6, 17, -0.91287092917527685576],
        [7, 2, 0.73950997288745200532],
        [7, 7, -1.2990381056766579701],
        [7, 16, 0.73950997288745200532],
        [8, 4, 1.1180339887498948482],
        [8, 11, -1.1180339887498948482],
        [9, 0, 0.7015607600201140098],
        [9, 3, -1.5309310892394863114],
        [9, 10, 1.169267933366856683],
        [10, 1, 1.169267933366856683],
        [10, 6, -1.5309310892394863114],
        [10, 15, 0.7015607600201140098],
    ]
    answer = np.zeros((11, 21))
    for i in horton_transform:
        answer[i[0], i[1]] = i[2]

    assert np.allclose(
        generate_transformation(
            5,
            np.array([(i.count(0), i.count(1), i.count(2))
                      for i in it.combinations_with_replacement(range(3), 5)]),
            (0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5),
            "left",
        ),
        answer,
    )
Ejemplo n.º 13
0
def test_generate_transformation_horton():
    """Test spherical.generate_transformation using horton reference.

    Answer obtained from https://theochem.github.io/horton/2.0.1/tech_ref_gaussian_basis.html.

    """
    answer = np.array([[1]])
    assert np.allclose(
        generate_transformation(0, np.array([[0, 0, 0]]), (0, ), "left"),
        answer)

    answer = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]])
    assert np.allclose(
        generate_transformation(1, np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
                                (0, 1, -1), "left"),
        answer,
    )

    answer = np.array([
        [-0.5, 0, 0, -0.5, 0, 1],
        [0, 0, 1, 0, 0, 0],
        [0, 0, 0, 0, 1, 0],
        [0.5 * 3**0.5, 0, 0, -0.5 * 3**0.5, 0, 0],
        [0, 1, 0, 0, 0, 0],
    ])
    assert np.allclose(
        generate_transformation(
            2,
            np.array([[2, 0, 0], [1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1],
                      [0, 0, 2]]),
            (0, 1, -1, 2, -2),
            "left",
        ),
        answer,
    )

    answer = np.array([
        [0, 0, -3 / 10 * 5**0.5, 0, 0, 0, 0, -3 / 10 * 5**0.5, 0, 1],
        [
            -1 / 4 * 6**0.5, 0, 0, -1 / 20 * 30**0.5, 0, 1 / 5 * 30**0.5, 0, 0,
            0, 0
        ],
        [
            0, -1 / 20 * 30**0.5, 0, 0, 0, 0, -1 / 4 * 6**0.5, 0,
            1 / 5 * 30**0.5, 0
        ],
        [0, 0, 1 / 2 * 3**0.5, 0, 0, 0, 0, -1 / 2 * 3**0.5, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
        [1 / 4 * 10**0.5, 0, 0, -3 / 4 * 2**0.5, 0, 0, 0, 0, 0, 0],
        [0, 3 / 4 * 2**0.5, 0, 0, 0, 0, -1 / 4 * 10**0.5, 0, 0, 0],
    ])
    # shuffle to have correct order
    assert np.allclose(
        generate_transformation(
            3,
            np.array([
                [3, 0, 0],
                [2, 1, 0],
                [2, 0, 1],
                [1, 2, 0],
                [1, 1, 1],
                [1, 0, 2],
                [0, 3, 0],
                [0, 2, 1],
                [0, 1, 2],
                [0, 0, 3],
            ]),
            (0, 1, -1, 2, -2, 3, -3),
            "left",
        ),
        answer,
    )
Ejemplo n.º 14
0
def test_generate_transformation():
    """Test spherical.generate_transformation."""
    assert np.array_equal(
        generate_transformation(0, np.array([(0, 0, 0)]), (0, ), "right"),
        np.array([[1.0]]))
    assert np.array_equal(
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), "right"),
        np.array([[0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]),
    )
    assert np.array_equal(
        generate_transformation(0, np.array([(0, 0, 0)]), (0, ), "right").T,
        generate_transformation(0, np.array([(0, 0, 0)]), (0, ), "left"),
    )
    assert np.array_equal(
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), "right").T,
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), "left"),
    )
    with pytest.raises(TypeError):
        generate_transformation(0.0, np.array([(0, 0, 0)]), (0, ), "right")
    with pytest.raises(TypeError):
        generate_transformation(0, 0, (0, ), "right")
    with pytest.raises(ValueError):
        generate_transformation(-1, np.array([(1, 0, 0), (0, 1, 0),
                                              (0, 0, 1)]), (-1, 0, 1), "right")
    with pytest.raises(ValueError):
        generate_transformation(0, np.array([(0, 0, 0, 0)]), (0, ), "right")
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 1)]),
                                (-1, 0, 1), "right")
    with pytest.raises(ValueError):
        generate_transformation(
            1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 0, 0)]),
            (-1, 0, 1), "right")
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0)]),
                                (-1, 0, 1), "right")
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 0, 0), (0, 0, 2)]),
                                (-1, 0, 1), "right")
    with pytest.raises(TypeError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), 1)
    with pytest.raises(TypeError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), None)
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), "up")
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1), "")
    # check angmom_components_sph type
    with pytest.raises(TypeError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                np.array([-1, 0, 1]), "left")
    with pytest.raises(TypeError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                {-1, 0, 1}, "left")
    with pytest.raises(TypeError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                [-1, 0, 1.0], "left")
    # check angmom_components_sph value
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 0, 1, 1), "left")
    with pytest.raises(ValueError):
        generate_transformation(1, np.array([(1, 0, 0), (0, 1, 0), (0, 0, 1)]),
                                (-1, 2, 1), "left")
Ejemplo n.º 15
0
def test_contruct_array_lincomb():
    """Test BaseTwoIndexAsymmetric.construct_array_lincomb."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]),
                                               np.ones(1), np.ones(1))
    sph_transform = generate_transformation(
        1, contractions.angmom_components_cart,
        contractions.angmom_components_sph, "left")
    orb_transform_one = np.random.rand(3, 3)
    orb_transform_two = np.random.rand(3, 3)

    Test = disable_abstract(  # noqa: N806
        BaseTwoIndexAsymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, a=2: np.arange(9, dtype=float).reshape(1, 3, 1, 3)
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))
    test = Test([contractions], [contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "cartesian", "cartesian"),
        orb_transform_one.dot(np.arange(9).reshape(3, 3)).dot(
            orb_transform_two.T) * 2,
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "spherical", "spherical"),
        (orb_transform_one.dot(sph_transform).dot(np.arange(9).reshape(
            3, 3)).dot(sph_transform.T).dot(orb_transform_two.T) * 2),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "cartesian", "spherical"),
        (orb_transform_one.dot(np.arange(9).reshape(3, 3)).dot(
            sph_transform.T).dot(orb_transform_two.T) * 2),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "spherical", "cartesian"),
        (orb_transform_one.dot(sph_transform).dot(np.arange(9).reshape(
            3, 3)).dot(orb_transform_two.T) * 2),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one,
                                     orb_transform_two,
                                     "spherical",
                                     "spherical",
                                     a=3),
        (orb_transform_one.dot(sph_transform).dot(np.arange(9).reshape(
            3, 3)).dot(sph_transform.T).dot(orb_transform_two.T) * 3),
    )
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform_one,
                                     orb_transform_two,
                                     "spherical",
                                     "spherical",
                                     bad_keyword=3)
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform_one,
                                     orb_transform_two,
                                     "bad",
                                     "spherical",
                                     keyword=3)
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform_one,
                                     orb_transform_two,
                                     "cartesian",
                                     "bad",
                                     keyword=3)

    orb_transform_one = np.random.rand(3, 6)
    orb_transform_two = np.random.rand(3, 3)
    test = Test([contractions, contractions], [contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "spherical", "spherical"),
        orb_transform_one.dot(
            np.vstack([
                sph_transform.dot(np.arange(9).reshape(3, 3)).dot(
                    sph_transform.T) * 2
            ] * 2).dot(orb_transform_two.T)),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     ["spherical", "cartesian"], "spherical"),
        orb_transform_one.dot(
            np.vstack([
                sph_transform.dot(np.arange(9).reshape(3, 3)).dot(
                    sph_transform.T) * 2,
                (np.arange(9).reshape(3, 3)).dot(sph_transform.T) * 2,
            ]).dot(orb_transform_two.T)),
    )
    orb_transform_one = np.random.rand(3, 3)
    orb_transform_two = np.random.rand(3, 6)
    test = Test([contractions], [contractions, contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, orb_transform_two,
                                     "cartesian", ["spherical", "cartesian"]),
        orb_transform_one.dot(
            np.hstack([
                (np.arange(9).reshape(3, 3)).dot(sph_transform.T) * 2,
                np.arange(9).reshape(3, 3) * 2,
            ]).dot(orb_transform_two.T)),
    )
    assert np.allclose(
        test.construct_array_lincomb(None, orb_transform_two, "cartesian",
                                     ["spherical", "cartesian"]),
        np.hstack([(np.arange(9).reshape(3, 3)).dot(sph_transform.T) * 2,
                   np.arange(9).reshape(3, 3) * 2]).dot(orb_transform_two.T),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform_one, None, "cartesian",
                                     ["spherical", "cartesian"]),
        orb_transform_one.dot(
            np.hstack([
                (np.arange(9).reshape(3, 3)).dot(sph_transform.T) * 2,
                np.arange(9).reshape(3, 3) * 2,
            ])),
    )
    assert np.allclose(
        test.construct_array_lincomb(None, None, "cartesian",
                                     ["spherical", "cartesian"]),
        np.hstack([(np.arange(9).reshape(3, 3)).dot(sph_transform.T) * 2,
                   np.arange(9).reshape(3, 3) * 2]),
    )
Ejemplo n.º 16
0
def test_construct_array_lincomb():
    """Test BaseFourIndexSymmetric.construct_array_lincomb."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    sph_transform = generate_transformation(
        1, contractions.angmom_components_cart, contractions.angmom_components_sph, "left"
    )
    orb_transform = np.random.rand(3, 3)

    Test = disable_abstract(  # noqa: N806
        BaseFourIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, cont_three, cont_four, a=2: np.arange(
                    81, dtype=float
                ).reshape(1, 3, 1, 3, 1, 3, 1, 3)
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))
    test = Test([contractions])
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "cartesian"),
        np.einsum(
            "ijkl,ai,bj,ck,dl->abcd",
            np.einsum("ijkl->lkji", np.arange(81).reshape(3, 3, 3, 3)) * 2,
            orb_transform,
            orb_transform,
            orb_transform,
            orb_transform,
        ),
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical"),
        np.einsum(
            "ijkl,ai,bj,ck,dl->abcd",
            np.einsum(
                "ijkl,ai,bj,ck,dl->abcd",
                np.einsum("ijkl->lkji", np.arange(81).reshape(3, 3, 3, 3)) * 2,
                sph_transform,
                sph_transform,
                sph_transform,
                sph_transform,
            ),
            orb_transform,
            orb_transform,
            orb_transform,
            orb_transform,
        ),
    )
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "spherical", bad_keyword=3)
    with pytest.raises(TypeError):
        test.construct_array_lincomb(orb_transform, "bad", keyword=3)

    Test = disable_abstract(  # noqa: N806
        BaseFourIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, cont_three, cont_four: (
                np.arange(
                    cont_one.num_cart
                    * cont_two.num_cart
                    * cont_three.num_cart
                    * cont_four.num_cart,
                    dtype=float,
                ).reshape(
                    1,
                    cont_one.num_cart,
                    1,
                    cont_two.num_cart,
                    1,
                    cont_three.num_cart,
                    1,
                    cont_four.num_cart,
                )
            )
        },
    )
    cont_one = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    cont_two = GeneralizedContractionShell(2, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    cont_one.norm_cont = np.ones((1, cont_one.num_cart))
    cont_two.norm_cont = np.ones((1, cont_two.num_cart))
    test = Test([cont_one, cont_two])

    sph_transform_one = generate_transformation(
        1, cont_one.angmom_components_cart, cont_one.angmom_components_sph, "left"
    )
    sph_transform_two = generate_transformation(
        2, cont_two.angmom_components_cart, cont_two.angmom_components_sph, "left"
    )
    orb_transform = np.random.rand(8, 8)
    # NOTE: since the test subarray (output of construct_array_contraction) does not satisfy the
    # symmetries of the two electron integral, only the last permutation is used. If this output
    # satisfies the symmetries of two electron integrals, then all these permutations should result
    # in the same array.
    # FIXME: not a good test
    sph_array = np.concatenate(
        [
            np.concatenate(
                [
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 3).reshape(3, 3, 3, 3),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jikl",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 6 * 6).reshape(3, 3, 6, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->klji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->klij",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->klji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->ijlk",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                ],
                axis=1,
            ),
            np.concatenate(
                [
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkij",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_one,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 6 * 6).reshape(3, 3, 6, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkij",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(6 * 6 * 6 * 6).reshape(6, 6, 6, 6),
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                            sph_transform_two,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                ],
                axis=1,
            ),
        ]
    )

    assert np.allclose(
        test.construct_array_lincomb(orb_transform, "spherical"),
        np.einsum(
            "ijkl,ai,bj,ck,dl->abcd",
            sph_array,
            orb_transform,
            orb_transform,
            orb_transform,
            orb_transform,
        ),
    )

    orb_transform = np.random.rand(9, 9)
    sph_cart_array = np.concatenate(
        [
            np.concatenate(
                [
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck,dl->abcd",
                                            np.arange(3 * 3 * 3 * 3).reshape(3, 3, 3, 3),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jikl",
                                        np.einsum(
                                            "ijkl,ai,bj,ck->abcl",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai,bj,ck->abcl",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai,bj->abkl",
                                            np.arange(3 * 3 * 6 * 6).reshape(3, 3, 6, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->klji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck->abcl",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->klij",
                                        np.einsum(
                                            "ijkl,ai,ck->ajcl",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->klji",
                                        np.einsum(
                                            "ijkl,ai,ck->ajcl",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->ijlk",
                                        np.einsum(
                                            "ijkl,ai->ajkl",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                ],
                axis=1,
            ),
            np.concatenate(
                [
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj,ck->abcl",
                                            np.arange(3 * 3 * 3 * 6).reshape(3, 3, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkij",
                                        np.einsum(
                                            "ijkl,ai,ck->ajcl",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,ck->ajcl",
                                            np.arange(3 * 6 * 3 * 6).reshape(3, 6, 3, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->jilk",
                                        np.einsum(
                                            "ijkl,ai->ajkl",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                    np.concatenate(
                        [
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai,bj->abkl",
                                            np.arange(3 * 3 * 6 * 6).reshape(3, 3, 6, 6),
                                            sph_transform_one,
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkij",
                                        np.einsum(
                                            "ijkl,ai->ajkl",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                        ),
                                    ),
                                ],
                                axis=3,
                            ),
                            np.concatenate(
                                [
                                    np.einsum(
                                        "ijkl->lkji",
                                        np.einsum(
                                            "ijkl,ai->ajkl",
                                            np.arange(3 * 6 * 6 * 6).reshape(3, 6, 6, 6),
                                            sph_transform_one,
                                        ),
                                    ),
                                    np.einsum(
                                        "ijkl->lkji", np.arange(6 * 6 * 6 * 6).reshape(6, 6, 6, 6)
                                    ),
                                ],
                                axis=3,
                            ),
                        ],
                        axis=2,
                    ),
                ],
                axis=1,
            ),
        ]
    )
    assert np.allclose(
        test.construct_array_lincomb(orb_transform, ("spherical", "cartesian")),
        np.einsum(
            "ijkl,ai,bj,ck,dl->abcd",
            sph_cart_array,
            orb_transform,
            orb_transform,
            orb_transform,
            orb_transform,
        ),
    )
Ejemplo n.º 17
0
def test_construct_array_spherical():
    """Test BaseFourIndexSymmetric.construct_array_spherical."""
    contractions = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    transform = generate_transformation(
        1, contractions.angmom_components_cart, contractions.angmom_components_sph, "left"
    )

    # make symmetric
    array = np.arange(81, dtype=float).reshape(3, 3, 3, 3)
    array += np.einsum("ijkl->jikl", array)
    array += np.einsum("ijkl->ijlk", array)
    array += np.einsum("ijkl->klij", array)
    Test = disable_abstract(  # noqa: N806
        BaseFourIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": (
                lambda self, cont_one, cont_two, cont_three, cont_four, a=2: array.reshape(
                    1, 3, 1, 3, 1, 3, 1, 3
                )
                * a
            )
        },
    )
    contractions.norm_cont = np.ones((1, 3))
    test = Test([contractions])

    assert np.allclose(
        test.construct_array_spherical(),
        np.einsum("ijkl,ai,bj,ck,dl->abcd", array, transform, transform, transform, transform) * 2,
    )

    assert np.allclose(
        test.construct_array_spherical(a=3),
        np.einsum("ijkl,ai,bj,ck,dl->abcd", array, transform, transform, transform, transform) * 3,
    )
    with pytest.raises(TypeError):
        test.construct_array_spherical(bad_keyword=3)

    cont_one = GeneralizedContractionShell(1, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    cont_two = GeneralizedContractionShell(2, np.array([1, 2, 3]), np.ones(1), np.ones(1))
    transform_one = generate_transformation(
        1, cont_one.angmom_components_cart, cont_one.angmom_components_sph, "left"
    )
    transform_two = generate_transformation(
        2, cont_two.angmom_components_cart, cont_two.angmom_components_sph, "left"
    )

    Test = disable_abstract(  # noqa: N806
        BaseFourIndexSymmetric,
        dict_overwrite={
            "construct_array_contraction": lambda self, cont_one, cont_two, cont_three, cont_four: (
                np.arange(
                    cont_one.num_cart
                    * cont_two.num_cart
                    * cont_three.num_cart
                    * cont_four.num_cart
                    * 2,
                    dtype=float,
                ).reshape(
                    1,
                    cont_one.num_cart,
                    1,
                    cont_two.num_cart,
                    1,
                    cont_three.num_cart,
                    1,
                    cont_four.num_cart,
                    2,
                )
            )
        },
    )
    cont_one.norm_cont = np.ones((1, cont_one.num_cart))
    cont_two.norm_cont = np.ones((1, cont_two.num_cart))
    test = Test([cont_one, cont_two])
    # NOTE: since the test subarray (output of construct_array_contraction) does not satisfy the
    # symmetries of the two electron integral, only the last permutation is used. If this output
    # satisfies the symmetries of two electron integrals, then all these permutations should result
    # in the same array.
    # FIXME: not a good test
    assert np.allclose(
        test.construct_array_spherical()[:3, :3, :3, :3],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 3 * 3 * 2).reshape(3, 3, 3, 3, 2),
                transform_one,
                transform_one,
                transform_one,
                transform_one,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, :3, :3, 3:],
        np.einsum(
            "ijklm->jiklm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 3 * 6 * 2).reshape(3, 3, 3, 6, 2),
                transform_one,
                transform_one,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, :3, 3:, :3],
        np.einsum(
            "ijklm->jilkm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 3 * 6 * 2).reshape(3, 3, 3, 6, 2),
                transform_one,
                transform_one,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, :3, 3:, 3:],
        np.einsum(
            "ijklm->jilkm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 6 * 6 * 2).reshape(3, 3, 6, 6, 2),
                transform_one,
                transform_one,
                transform_two,
                transform_two,
            ),
        ),
    )

    assert np.allclose(
        test.construct_array_spherical()[:3, 3:, :3, :3],
        np.einsum(
            "ijklm->kljim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 3 * 6 * 2).reshape(3, 3, 3, 6, 2),
                transform_one,
                transform_one,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, 3:, :3, 3:],
        np.einsum(
            "ijklm->klijm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 3 * 6 * 2).reshape(3, 6, 3, 6, 2),
                transform_one,
                transform_two,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, 3:, 3:, :3],
        np.einsum(
            "ijklm->kljim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 3 * 6 * 2).reshape(3, 6, 3, 6, 2),
                transform_one,
                transform_two,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[:3, 3:, 3:, 3:],
        np.einsum(
            "ijklm->ijlkm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 6 * 6 * 2).reshape(3, 6, 6, 6, 2),
                transform_one,
                transform_two,
                transform_two,
                transform_two,
            ),
        ),
    )

    assert np.allclose(
        test.construct_array_spherical()[3:, :3, :3, :3],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 3 * 6 * 2).reshape(3, 3, 3, 6, 2),
                transform_one,
                transform_one,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, :3, :3, 3:],
        np.einsum(
            "ijklm->lkijm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 3 * 6 * 2).reshape(3, 6, 3, 6, 2),
                transform_one,
                transform_two,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, :3, 3:, :3],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 3 * 6 * 2).reshape(3, 6, 3, 6, 2),
                transform_one,
                transform_two,
                transform_one,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, :3, 3:, 3:],
        np.einsum(
            "ijklm->jilkm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 6 * 6 * 2).reshape(3, 6, 6, 6, 2),
                transform_one,
                transform_two,
                transform_two,
                transform_two,
            ),
        ),
    )

    assert np.allclose(
        test.construct_array_spherical()[3:, 3:, :3, :3],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 3 * 6 * 6 * 2).reshape(3, 3, 6, 6, 2),
                transform_one,
                transform_one,
                transform_two,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, 3:, :3, 3:],
        np.einsum(
            "ijklm->lkijm",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 6 * 6 * 2).reshape(3, 6, 6, 6, 2),
                transform_one,
                transform_two,
                transform_two,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, 3:, 3:, :3],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(3 * 6 * 6 * 6 * 2).reshape(3, 6, 6, 6, 2),
                transform_one,
                transform_two,
                transform_two,
                transform_two,
            ),
        ),
    )
    assert np.allclose(
        test.construct_array_spherical()[3:, 3:, 3:, 3:],
        np.einsum(
            "ijklm->lkjim",
            np.einsum(
                "ijklm,ai,bj,ck,dl->abcdm",
                np.arange(6 * 6 * 6 * 6 * 2).reshape(6, 6, 6, 6, 2),
                transform_two,
                transform_two,
                transform_two,
                transform_two,
            ),
        ),
    )
Ejemplo n.º 18
0
    def construct_array_mix(self, coord_types, **kwargs):
        """Return the array associated with all of the contractions in the given coordinate system.

        Parameters
        ----------
        coord_types : list/tuple of str
            Types of the coordinate system for each GeneralizedContractionShell.
            Each entry must be one of "cartesian" or "spherical".
        kwargs : dict
            Other keyword arguments that will be used to construct the array.
            These keyword arguments are passed entirely to `construct_array_contraction`. See
            `construct_array_contraction` for details on the keyword arguments.

        Returns
        -------
        array : np.ndarray(K_cont, ...)
            Array associated with the spherical contrations of the basis set.
            Dimension 0 is associated with each spherical contraction in the basis set.
            `K_cont` is the total number of contractions within the given basis set.

        Raises
        ------
        TypeError
            If `coord_types` is not a list/tuple.
        ValueError
            If `coord_types` has an entry that is not "cartesian" or "spherical".
            If `coord_types` has different number of entries as the number of
            `GeneralizedContractionShell` (`contractions`) in instance.

        """
        if not isinstance(coord_types, (list, tuple)):
            raise TypeError("`coord_types` must be a list or a tuple.")
        if not all(i in ["cartesian", "spherical"] for i in coord_types):
            raise ValueError(
                "Each entry of `coord_types` must be one of 'cartesian' or 'spherical'."
            )
        if len(coord_types) != len(self.contractions):
            raise ValueError(
                "`coord_types` must have the same number of entries as the number of "
                "`GeneralizedContractionShell` in the instance.")

        matrices = []
        for cont, coord_type in zip(self.contractions, coord_types):
            # get transformation from cartesian to spherical (applied to left)
            transform = generate_transformation(cont.angmom,
                                                cont.angmom_components_cart,
                                                cont.angmom_components_sph,
                                                "left")
            # evaluate the function at the given points
            matrix_contraction = self.construct_array_contraction(
                cont, **kwargs)
            # normalize contractions
            matrix_contraction *= cont.norm_cont.reshape(
                *matrix_contraction.shape[:2],
                *[1 for _ in matrix_contraction.shape[2:]])
            # transform
            # ASSUME array always has shape (M, L, ...)
            if coord_type == "spherical":
                matrix_contraction = np.tensordot(transform,
                                                  matrix_contraction, (1, 1))
                matrix_contraction = np.swapaxes(matrix_contraction, 0, 1)
            matrix_contraction = np.concatenate(matrix_contraction, axis=0)
            # store
            matrices.append(matrix_contraction)

        return np.concatenate(matrices, axis=0)
Ejemplo n.º 19
0
    def construct_array_mix(self, coord_types, **kwargs):
        """Return the array associated with a set of Gaussians of the given coordinate systems.

        Parameters
        ----------
        coord_types : list/tuple of str
            Types of the coordinate system for each `GeneralizedContractionShell`.
            Each entry must be one of "cartesian" or "spherical".
        kwargs : dict
            Other keyword arguments that will be used to construct the array.

        Returns
        -------
        array : np.ndarray(K_cont, K_cont, K_cont, K_cont, ...)
            Array associated with the atomic orbitals associated with the given set of contracted
            Cartesian Gaussians.
            Dimensions 0, 1, 2 and 3 of the array are associated with two contractions in the given
            coordinate system. `K_cont` is the total number of contractions within the
            instance.

        Raises
        ------
        TypeError
            If `coord_types` is not a list/tuple.
        ValueError
            If `coord_types` has an entry that is not "cartesian" or "spherical".
            If `coord_types` has different number of entries as the number of
            `GeneralizedContractionShell` (`contractions`) in instance.

        """
        # pylint: disable=C0103,R0914
        if not isinstance(coord_types, (list, tuple)):
            raise TypeError("`coord_types` must be a list or a tuple.")
        if not all(i in ["cartesian", "spherical"] for i in coord_types):
            raise ValueError(
                "Each entry of `coord_types` must be one of 'cartesian' or 'spherical'."
            )
        if len(coord_types) != len(self.contractions):
            raise ValueError(
                "`coord_types` must have the same number of entries as the number of "
                "`GeneralizedContractionShell` in the instance."
            )

        all_blocks = np.zeros((len(self.contractions),) * 4, dtype=object)
        pair_i_cont = list(
            it.combinations_with_replacement(
                zip(range(len(self.contractions)), self.contractions, coord_types), 2
            )
        )
        for pair_ind, ((i, cont_one, type_one), (j, cont_two, type_two)) in enumerate(pair_i_cont):
            transform_one = generate_transformation(
                cont_one.angmom,
                cont_one.angmom_components_cart,
                cont_one.angmom_components_sph,
                "left",
            )
            transform_two = generate_transformation(
                cont_two.angmom,
                cont_two.angmom_components_cart,
                cont_two.angmom_components_sph,
                "left",
            )
            for (k, cont_three, type_three), (l, cont_four, type_four) in pair_i_cont[pair_ind:]:
                transform_three = generate_transformation(
                    cont_three.angmom,
                    cont_three.angmom_components_cart,
                    cont_three.angmom_components_sph,
                    "left",
                )
                transform_four = generate_transformation(
                    cont_four.angmom,
                    cont_four.angmom_components_cart,
                    cont_four.angmom_components_sph,
                    "left",
                )

                block = self.construct_array_contraction(
                    cont_one, cont_two, cont_three, cont_four, **kwargs
                )
                # normalize contractions
                block *= cont_one.norm_cont.reshape(*block.shape[:2], *[1 for _ in block.shape[2:]])
                block *= cont_two.norm_cont.reshape(
                    1, 1, *block.shape[2:4], *[1 for _ in block.shape[4:]]
                )
                block *= cont_three.norm_cont.reshape(
                    1, 1, 1, 1, *block.shape[4:6], *[1 for _ in block.shape[6:]]
                )
                block *= cont_four.norm_cont.reshape(
                    1, 1, 1, 1, 1, 1, *block.shape[6:8], *[1 for _ in block.shape[8:]]
                )

                # transform
                if type_one == "spherical":
                    block = np.tensordot(transform_one, block, (1, 1))
                    block = np.swapaxes(block, 0, 1)
                if type_two == "spherical":
                    block = np.tensordot(transform_two, block, (1, 3))
                    block = np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3)
                if type_three == "spherical":
                    block = np.tensordot(transform_three, block, (1, 5))
                    block = np.swapaxes(
                        np.swapaxes(
                            np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3), 3, 4
                        ),
                        4,
                        5,
                    )
                if type_four == "spherical":
                    block = np.tensordot(transform_four, block, (1, 7))
                    block = np.swapaxes(
                        np.swapaxes(
                            np.swapaxes(
                                np.swapaxes(
                                    np.swapaxes(np.swapaxes(np.swapaxes(block, 0, 1), 1, 2), 2, 3),
                                    3,
                                    4,
                                ),
                                4,
                                5,
                            ),
                            5,
                            6,
                        ),
                        6,
                        7,
                    )

                # array has shape (M_1, L_1, M_2, L_2, M_3, L_3, M_4, L_4, ..)
                block = block.reshape(
                    block.shape[0] * block.shape[1],
                    block.shape[2] * block.shape[3],
                    block.shape[4] * block.shape[5],
                    block.shape[6] * block.shape[7],
                    *block.shape[8:],
                )
                # array now has shape (M_1 L_1, M_2 L_2, M_3, L_3, M_4, L_4, ...)
                all_blocks[i, j, k, l] = block
                all_blocks[i, j, l, k] = np.swapaxes(block, 2, 3)
                all_blocks[j, i, k, l] = np.swapaxes(block, 0, 1)
                all_blocks[j, i, l, k] = np.swapaxes(np.swapaxes(block, 2, 3), 0, 1)
                all_blocks[k, l, i, j] = np.swapaxes(np.swapaxes(block, 1, 3), 0, 2)
                all_blocks[l, k, i, j] = np.swapaxes(
                    np.swapaxes(np.swapaxes(block, 1, 3), 0, 2), 0, 1
                )
                all_blocks[k, l, j, i] = np.swapaxes(
                    np.swapaxes(np.swapaxes(block, 1, 3), 0, 2), 2, 3
                )
                all_blocks[l, k, j, i] = np.swapaxes(np.swapaxes(block, 1, 2), 0, 3)

        # concatenate
        return np.concatenate(
            [
                np.concatenate(
                    [
                        np.concatenate(
                            [np.concatenate(blocks_three, axis=3) for blocks_three in blocks_two],
                            axis=2,
                        )
                        for blocks_two in blocks_one
                    ],
                    axis=1,
                )
                for blocks_one in all_blocks
            ],
            axis=0,
        )
Ejemplo n.º 20
0
def test_generate_transformation_horton_negative_components():
    """Test spherical.generate_transformation using horton reference and ORCA-style conventions.

    Conventions obtained from `IOData.formats.molden._fix_obasis_orca`.

    """
    # Answer obtained from https://theochem.github.io/horton/2.0.1/tech_ref_gaussian_basis.html.
    answer = np.array([
        [0, 0, -3 / 10 * 5**0.5, 0, 0, 0, 0, -3 / 10 * 5**0.5, 0, 1],
        [
            -1 / 4 * 6**0.5, 0, 0, -1 / 20 * 30**0.5, 0, 1 / 5 * 30**0.5, 0, 0,
            0, 0
        ],
        [
            0, -1 / 20 * 30**0.5, 0, 0, 0, 0, -1 / 4 * 6**0.5, 0,
            1 / 5 * 30**0.5, 0
        ],
        [0, 0, 1 / 2 * 3**0.5, 0, 0, 0, 0, -1 / 2 * 3**0.5, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
        [-1 / 4 * 10**0.5, 0, 0, 3 / 4 * 2**0.5, 0, 0, 0, 0, 0, 0],
        [0, -3 / 4 * 2**0.5, 0, 0, 0, 0, 1 / 4 * 10**0.5, 0, 0, 0],
    ])
    assert np.allclose(
        generate_transformation(
            3,
            np.array([
                [3, 0, 0],
                [2, 1, 0],
                [2, 0, 1],
                [1, 2, 0],
                [1, 1, 1],
                [1, 0, 2],
                [0, 3, 0],
                [0, 2, 1],
                [0, 1, 2],
                [0, 0, 3],
            ]),
            ("c0", "c1", "s1", "c2", "s2", "-c3", "-s3"),
            "left",
        ),
        answer,
    )
    # taken from HORTON's gbasis/cartpure.cpp
    horton_transform = [
        [0, 0, 0.375],
        [0, 3, 0.21957751641341996535],
        [0, 5, -0.87831006565367986142],
        [0, 10, 0.375],
        [0, 12, -0.87831006565367986142],
        [0, 14, 1.0],
        [1, 2, -0.89642145700079522998],
        [1, 7, -0.40089186286863657703],
        [1, 9, 1.19522860933439364],
        [2, 4, -0.40089186286863657703],
        [2, 11, -0.89642145700079522998],
        [2, 13, 1.19522860933439364],
        [3, 0, -0.5590169943749474241],
        [3, 5, 0.9819805060619657157],
        [3, 10, 0.5590169943749474241],
        [3, 12, -0.9819805060619657157],
        [4, 1, -0.42257712736425828875],
        [4, 6, -0.42257712736425828875],
        [4, 8, 1.1338934190276816816],
        [5, 2, 0.790569415042094833],
        [5, 7, -1.0606601717798212866],
        [6, 4, 1.0606601717798212866],
        [6, 11, -0.790569415042094833],
        [7, 0, 0.73950997288745200532],
        [7, 3, -1.2990381056766579701],
        [7, 10, 0.73950997288745200532],
        [8, 1, 1.1180339887498948482],
        [8, 6, -1.1180339887498948482],
    ]
    answer = np.zeros((9, 15))
    for i in horton_transform:
        # Negative of c3, s3, c4, s4
        if i[0] > 4:
            answer[i[0], i[1]] = -i[2]
        else:
            answer[i[0], i[1]] = i[2]
    assert np.allclose(
        generate_transformation(
            4,
            np.array([
                [4, 0, 0],
                [3, 1, 0],
                [3, 0, 1],
                [2, 2, 0],
                [2, 1, 1],
                [2, 0, 2],
                [1, 3, 0],
                [1, 2, 1],
                [1, 1, 2],
                [1, 0, 3],
                [0, 4, 0],
                [0, 3, 1],
                [0, 2, 2],
                [0, 1, 3],
                [0, 0, 4],
            ]),
            ("c0", "c1", "s1", "c2", "s2", "-c3", "-s3", "-c4", "-s4"),
            "left",
        ),
        answer,
    )