Exemple #1
0
 def __init__(self,
              wfn,
              blocks=False,
              precondition='denom',
              tda=False,
              triplet=False):
     blocks = False
     if not wfn.same_a_b_orbs():
         raise ValidationError("TDSCF is RHF only")
     self.wfn = wfn
     self.jk = wfn.jk()
     self.C = wfn.Ca()
     self.Co = wfn.Ca_subset("SO", "OCC")
     self.Cv = wfn.Ca_subset("SO", "VIR")
     self.noccpi = wfn.nalphapi()
     self.nmopi = wfn.nmopi()
     self.nirrep = wfn.nirrep()
     self.nvirpi = core.Dimension([
         mo - occ
         for mo, occ in zip(self.noccpi.to_tuple(), self.nmopi.to_tuple())
     ])
     self.nocc = wfn.nalphapi().sum()
     self.nmo = wfn.nmopi().sum()
     self.nvir = self.nmo - self.nocc
     self.nov = self.nocc * self.nvir
     self.Fab = core.Matrix.triplet(self.Cv, self.wfn.Fa(), self.Cv, True,
                                    False, False)
     self.Fij = core.Matrix.triplet(self.Co, self.wfn.Fb(), self.Co, True,
                                    False, False)
     self.e_ia = np.zeros((self.nocc, self.nvir))
     for i in range(self.nocc):
         for a in range(self.nvir):
             self.e_ia[i, a] = self.Fab.np[a, a] - self.Fij.np[i, i]
     self.blocks = blocks
     self.triplet = triplet
Exemple #2
0
def _dimension_from_list(
    self,
    dims: Union[Tuple[int], List[int], np.ndarray, core.Dimension],
    name="New Dimension",
) -> core.Dimension:
    """
    Builds a Dimension object from a Python list or tuple. If a
    :class:`~psi4.core.Dimension` object is passed, a copy will be returned.

    Parameters
    ----------
    dims
        Iterable of integers defining irrep dimensions.
    name
        Name for new instance.

    """
    if isinstance(dims, (tuple, list, np.ndarray)):
        irreps = len(dims)
    elif isinstance(dims, core.Dimension):
        irreps = dims.n()
    else:
        raise ValidationError("Dimension from list: Type '%s' not understood" %
                              type(dims))

    ret = core.Dimension(irreps, name)
    for i in range(irreps):
        ret[i] = dims[i]
    return ret
Exemple #3
0
def _dimension_from_list(self, dims, name="New Dimension"):
    """
    Builds a core.Dimension object from a python list or tuple. If a dimension
    object is passed a copy will be returned.
    """

    if isinstance(dims, (tuple, list, np.ndarray)):
        irreps = len(dims)
    elif isinstance(dims, core.Dimension):
        irreps = dims.n()
    else:
        raise ValidationError("Dimension from list: Type '%s' not understood" % type(dims))

    ret = core.Dimension(irreps, name)
    for i in range(irreps):
        ret[i] = dims[i]
    return ret
Exemple #4
0
def _ROHF_orbital_gradient(self, save_fock: bool,
                           max_diis_vectors: int) -> float:
    # Only the inact-act, inact-vir, and act-vir rotations are non-redundant
    dim_zero = core.Dimension(self.nirrep(), "Zero Dim")
    noccpi = self.doccpi() + self.soccpi()
    row_slice = core.Slice(dim_zero, noccpi)
    col_slice = core.Slice(self.doccpi(), self.nmopi())
    MOgradient = self.moFeff().get_block(row_slice, col_slice)

    # Zero the active-active block
    for h in range(MOgradient.nirrep()):
        socc = self.soccpi()[h]
        docc = self.doccpi()[h]

        MOgradient.nph[h][docc:docc + socc, 0:socc] = 0

    # Grab inact-act and act-vir orbs
    # Ct is (nmo x nmo), not the (nso x nmo) you would expect
    row_slice = core.Slice(dim_zero, self.nmopi())
    col_slice = core.Slice(dim_zero, noccpi)
    Cia = self.Ct().get_block(row_slice, col_slice)
    col_slice = core.Slice(self.doccpi(), self.nmopi())
    Cav = self.Ct().get_block(row_slice, col_slice)

    # Back transform MOgradient
    gradient = core.triplet(Cia, MOgradient, Cav, False, False, True)

    if save_fock:
        if not self.initialized_diis_manager_:
            self.diis_manager_ = core.DIISManager(max_diis_vectors,
                                                  "HF DIIS vector",
                                                  RemovalPolicy.LargestError,
                                                  StoragePolicy.OnDisk)
            self.diis_manager_.set_error_vector_size(gradient)
            self.diis_manager_.set_vector_size(self.soFeff())
            self.initialized_diis_manager_ = True

        self.diis_manager_.add_entry(gradient, self.soFeff())

    if self.options().get_bool("DIIS_RMS_ERROR"):
        return gradient.rms()
    else:
        return gradient.absmax()
Exemple #5
0
def array_to_matrix(self, arr, name="New Matrix", dim1=None, dim2=None):
    """
    Converts a numpy array or list of numpy arrays into a Psi4 Matrix (irreped if list).

    Parameters
    ----------
    arr : array or list of arrays
        Numpy array or list of arrays to use as the data for a new core.Matrix
    name : str
        Name to give the new core.Matrix
    dim1 : list, tuple, or core.Dimension (optional)
        If a single dense numpy array is given, a dimension can be supplied to
        apply irreps to this array. Note that this discards all extra information
        given in the matrix besides the diagonal blocks determined by the passed
        dimension.
    dim2 :
        Same as dim1 only if using a Psi4.Dimension object.

    Returns
    -------
    ret : core.Vector or core.Matrix
       Returns the given Psi4 object

    Notes
    -----
    This is a generalized function to convert a NumPy array to a Psi4 object

    Examples
    --------

    >>> data = np.random.rand(20)
    >>> vector = array_to_matrix(data)

    >>> irrep_data = [np.random.rand(2, 2), np.empty(shape=(0,3)), np.random.rand(4, 4)]
    >>> matrix = array_to_matrix(irrep_data)
    >>> print matrix.rowspi().to_tuple()
    >>> (2, 0, 4)
    """

    # What type is it? MRO can help.
    arr_type = self.__mro__[0]

    # Irreped case
    if isinstance(arr, (list, tuple)):
        if (dim1 is not None) or (dim2 is not None):
            raise ValidationError(
                "Array_to_Matrix: If passed input is list of arrays dimension cannot be specified."
            )

        irreps = len(arr)
        if arr_type == core.Matrix:
            sdim1 = core.Dimension(irreps)
            sdim2 = core.Dimension(irreps)

            for i in range(irreps):
                d1, d2 = _find_dim(arr[i], 2)
                sdim1[i] = d1
                sdim2[i] = d2

            ret = self(name, sdim1, sdim2)

        elif arr_type == core.Vector:
            sdim1 = core.Dimension(irreps)

            for i in range(irreps):
                d1 = _find_dim(arr[i], 1)
                sdim1[i] = d1[0]

            ret = self(name, sdim1)
        else:
            raise ValidationError(
                "Array_to_Matrix: type '%s' is not recognized." %
                str(arr_type))

        for view, vals in zip(ret.nph, arr):
            if 0 in view.shape: continue
            view[:] = vals

        return ret

    # No irreps implied by list
    else:
        if arr_type == core.Matrix:

            # Build an irreped array back out
            if dim1 is not None:
                if dim2 is None:
                    raise ValidationError(
                        "Array_to_Matrix: If dim1 is supplied must supply dim2 also"
                    )

                dim1 = core.Dimension.from_list(dim1)
                dim2 = core.Dimension.from_list(dim2)

                if dim1.n() != dim2.n():
                    raise ValidationError(
                        "Array_to_Matrix: Length of passed dim1 must equal length of dim2."
                    )

                ret = self(name, dim1, dim2)

                start1 = 0
                start2 = 0
                for num, interface in enumerate(ret.nph):
                    d1 = dim1[num]
                    d2 = dim2[num]
                    if (d1 == 0) or (d2 == 0):
                        continue

                    view = np.asarray(interface)
                    view[:] = arr[start1:start1 + d1, start2:start2 + d2]
                    start1 += d1
                    start2 += d2

                return ret

            # Simple case without irreps
            else:
                ret = self(name, arr.shape[0], arr.shape[1])
                ret_view = np.asarray(numpy_holder(ret.array_interface(0)))
                ret_view[:] = arr
                return ret

        elif arr_type == core.Vector:
            # Build an irreped array back out
            if dim1 is not None:
                if dim2 is not None:
                    raise ValidationError(
                        "Array_to_Matrix: If dim2 should not be supplied for 1D vectors."
                    )

                dim1 = core.Dimension.from_list(dim1)
                ret = self(name, dim1)

                start1 = 0
                for num, interface in enumerate(ret.nph):
                    d1 = dim1[num]
                    if (d1 == 0):
                        continue

                    view = np.asarray(interface)
                    view[:] = arr[start1:start1 + d1]
                    start1 += d1

                return ret

            # Simple case without irreps
            else:
                ret = self(name, arr.shape[0])
                ret.np[:] = arr
                return ret

        else:
            raise ValidationError(
                "Array_to_Matrix: type '%s' is not recognized." %
                str(arr_type))
Exemple #6
0
def array_to_matrix(
    self: Union[core.Matrix, core.Vector],
    arr: Union[np.ndarray, List[np.ndarray]],
    name: str = "New Matrix",
    dim1: Optional[Union[List, Tuple, core.Dimension]] = None,
    dim2: Optional[core.Dimension] = None,
) -> Union[core.Matrix, core.Vector]:
    """
    Converts a `NumPy array
    <https://numpy.org/doc/stable/reference/arrays.ndarray.html>`_ or list of
    NumPy arrays into a |PSIfour| :class:`~psi4.core.Matrix` or
    :class:`~psi4.core.Vector` (irreped if list).

    Parameters
    ----------
    self
        Matrix or Vector class.
    arr
        NumPy array or list of arrays to use as the data for a new
        :class:`~psi4.core.Matrix` or :class:`~psi4.core.Vector`.
    name
        Name to give the new :class:`~psi4.core.Matrix`.
    dim1
        If a single dense NumPy array is given, a dimension can be supplied to
        apply irreps to this array. Note that this discards all extra information
        given in the matrix besides the diagonal blocks determined by the passed
        dimension.
    dim2
        Same as `dim1` only if using a :class:`~psi4.core.Dimension` object.

    Returns
    -------
    Matrix or Vector
       Returns the given (`self`) Psi4 object.

    Notes
    -----
    This is a generalized function to convert a NumPy array to a Psi4 object

    Examples
    --------

    >>> data = np.random.rand(20,1)
    >>> vector = psi4.core.Matrix.from_array(data)

    >>> irrep_data = [np.random.rand(2, 2), np.empty(shape=(0,3)), np.random.rand(4, 4)]
    >>> matrix = psi4.core.Matrix.from_array(irrep_data)
    >>> print(matrix.rowdim().to_tuple())
    (2, 0, 4)
    """

    # What type is it? MRO can help.
    arr_type = self.__mro__[0]

    # Irreped case
    if isinstance(arr, (list, tuple)):
        if (dim1 is not None) or (dim2 is not None):
            raise ValidationError(
                "Array_to_Matrix: If passed input is list of arrays dimension cannot be specified."
            )

        irreps = len(arr)
        if arr_type == core.Matrix:
            sdim1 = core.Dimension(irreps)
            sdim2 = core.Dimension(irreps)

            for i in range(irreps):
                d1, d2 = _find_dim(arr[i], 2)
                sdim1[i] = d1
                sdim2[i] = d2

            ret = self(name, sdim1, sdim2)

        elif arr_type == core.Vector:
            sdim1 = core.Dimension(irreps)

            for i in range(irreps):
                d1 = _find_dim(arr[i], 1)
                sdim1[i] = d1[0]

            ret = self(name, sdim1)
        else:
            raise ValidationError(
                "Array_to_Matrix: type '%s' is not recognized." %
                str(arr_type))

        for view, vals in zip(ret.nph, arr):
            if 0 in view.shape: continue
            view[:] = vals

        return ret

    # No irreps implied by list
    else:
        if arr_type == core.Matrix:

            # Build an irreped array back out
            if dim1 is not None:
                if dim2 is None:
                    raise ValidationError(
                        "Array_to_Matrix: If dim1 is supplied must supply dim2 also"
                    )

                dim1 = core.Dimension.from_list(dim1)
                dim2 = core.Dimension.from_list(dim2)

                if dim1.n() != dim2.n():
                    raise ValidationError(
                        "Array_to_Matrix: Length of passed dim1 must equal length of dim2."
                    )

                ret = self(name, dim1, dim2)

                start1 = 0
                start2 = 0
                for num, interface in enumerate(ret.nph):
                    d1 = dim1[num]
                    d2 = dim2[num]
                    if (d1 == 0) or (d2 == 0):
                        continue

                    view = np.asarray(interface)
                    view[:] = arr[start1:start1 + d1, start2:start2 + d2]
                    start1 += d1
                    start2 += d2

                return ret

            # Simple case without irreps
            else:
                ret = self(name, arr.shape[0], arr.shape[1])
                ret.np[:] = arr
                return ret

        elif arr_type == core.Vector:
            # Build an irreped array back out
            if dim1 is not None:
                if dim2 is not None:
                    raise ValidationError(
                        "Array_to_Matrix: If dim2 should not be supplied for 1D vectors."
                    )

                dim1 = core.Dimension.from_list(dim1)
                ret = self(name, dim1)

                start1 = 0
                for num, interface in enumerate(ret.nph):
                    d1 = dim1[num]
                    if (d1 == 0):
                        continue

                    view = np.asarray(interface)
                    view[:] = arr[start1:start1 + d1]
                    start1 += d1

                return ret

            # Simple case without irreps
            else:
                ret = self(name, arr.shape[0])
                ret.np[:] = arr
                return ret

        else:
            raise ValidationError(
                "Array_to_Matrix: type '%s' is not recognized." %
                str(arr_type))