ffsim.linalg.double_factorized

ffsim.linalg.double_factorized(two_body_tensor, *, tol=1e-08, max_vecs=None, optimize=False, diag_coulomb_indices=None, return_optimize_result=False, cholesky=True, **optimize_kwargs)[source]

Double-factorized decomposition of a two-body tensor.

Overloads:

The double-factorized decomposition is a representation of a two-body tensor \(h_{pqrs}\) as

\[h_{pqrs} = \sum_{t=0}^{L - 1} \sum_{k\ell} Z^{(t)}_{k\ell} U^{(t)}_{pk} U^{(t)}_{qk} U^{(t)}_{r\ell} U^{(t)}_{s\ell},\]

where each \(Z^{(t)}\) is a real symmetric matrix representing a diagonal Coulomb operator and each \(U^{(t)}\) is a unitary matrix representing an orbital rotation.

The number of terms \(L\) in the decomposition depends on the allowed error threshold. A larger error threshold may yield a smaller number of terms. Furthermore, the max_vecs parameter specifies an optional upper bound on \(L\). The max_vecs parameter is always respected, so if it is too small, then the error of the decomposition may exceed the specified error threshold.

This routine performs a straightforward “exact” factorization of the two-body tensor based on a nested eigenvalue decomposition, and then truncates the terms based on the values of tol and max_vecs. To further optimize the resulting tensors to reduce the error in the factorization, pass them to double_factorized_compressed().

Warning

The optimize, diag_coulomb_indices, return_optimize_result, and optimize_kwargs arguments are deprecated. Instead, call double_factorized_compressed() on the output of this function.

References

Note: Currently, only real-valued two-body tensors are supported.

Parameters:
  • two_body_tensor (ndarray) – The two-body tensor to decompose.

  • tol (float) – Tolerance for error in the decomposition. The error is defined as the maximum absolute difference between an element of the original tensor and the corresponding element of the reconstructed tensor.

  • max_vecs (int | None) – An optional limit on the number of terms to keep in the decomposition of the two-body tensor. This argument overrides tol.

  • optimize (bool) – Deprecated. Whether to optimize the tensors returned by the decomposition to minimize the error in the factorization.

  • diag_coulomb_indices (list[tuple[int, int]] | None) – Deprecated. Allowed indices for nonzero values of the diagonal Coulomb matrices when optimize is set to True. See double_factorized_compressed().

  • return_optimize_result (bool) – Deprecated. Whether to also return the OptimizeResult returned by scipy.optimize.minimize(). If no optimization is performed, None is returned in its place.

  • cholesky (bool) – Whether to perform the factorization using a modified Cholesky decomposition. If False, a full eigenvalue decomposition is used instead, which can be much more expensive. This argument is ignored if optimize is set to True.

  • optimize_kwargs – Deprecated. Keyword arguments to pass to scipy.optimize.minimize() when optimize is set to True.

Returns:

The diagonal Coulomb matrices and the orbital rotations. Each list of matrices is collected into a Numpy array, so this method returns a tuple of two Numpy arrays, the first containing the diagonal Coulomb matrices and the second containing the orbital rotations. Each Numpy array will have shape (L, n, n) where L is the number of terms in the decomposition and n is the number of orbitals. If return_optimize_result is set to True, the OptimizeResult returned by scipy.optimize.minimize() is also returned, or None if no optimization was performed. No optimization is performed if optimize is set to False, or if the two-body tensor has zero orbitals.

Raises:
  • ValueError – The two-body tensor is complex-valued.

  • ValueError – optimize is True, the two-body tensor has at least one orbital, and the factorization has no terms.

  • ValueError – optimize is True, the two-body tensor has at least one orbital, and diag_coulomb_indices contains lower triangular indices.