ffsim.linalg.double_factorized_compressed

ffsim.linalg.double_factorized_compressed(two_body_tensor, *, initial_guess=None, max_vecs=None, diag_coulomb_indices=None, **optimize_kwargs)[source]

Compress a double-factorized decomposition of a two-body tensor.

Optimizes the diagonal Coulomb matrices and orbital rotations of a double-factorized decomposition (see double_factorized()) with scipy.optimize.minimize() to reduce the error in the factorization. The optimization starts from the factorization given by initial_guess. If it is not specified, the exact factorization computed by double_factorized() with the default tolerance is used. To use a different tolerance, call double_factorized() yourself and pass its output as initial_guess. If max_vecs is specified, then only the first max_vecs terms of the initial guess are kept.

The diagonal Coulomb matrices returned by the optimization can be optionally constrained to have only certain elements allowed to be nonzero. This is achieved by passing the diag_coulomb_indices parameter, which is a list of matrix entry indices (integer pairs) specifying where the diagonal Coulomb matrices are allowed to be nonzero. Since the diagonal Coulomb matrices are symmetric, only upper triangular indices should be given, i.e., pairs \((i, j)\) where \(i \leq j\).

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

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

  • initial_guess (tuple[ndarray, ndarray] | None) – The initial guess for the optimization, as a tuple of the diagonal Coulomb matrices and the orbital rotations, each a Numpy array of shape (L, norb, norb). Both arrays must be real-valued. Typically, this is the output of double_factorized(). If not specified, the exact factorization computed by double_factorized() with the default tolerance is used.

  • max_vecs (int | None) – An optional limit on the number of terms to keep in the decomposition. If not specified, all the terms of the initial guess are kept.

  • diag_coulomb_indices (list[tuple[int, int]] | None) – Allowed indices for nonzero values of the diagonal Coulomb matrices. Matrix entries corresponding to indices not in this list will be set to zero. This list should contain only upper triangular indices, i.e., pairs \((i, j)\) where \(i \leq j\).

  • optimize_kwargs – Keyword arguments to pass to scipy.optimize.minimize(). The default method is "L-BFGS-B".

Return type:

tuple[ndarray, ndarray, OptimizeResult]

Returns:

  • The optimized diagonal Coulomb matrices, as a Numpy array of shape (L, norb, norb).

  • The optimized orbital rotations, as a Numpy array of shape (L, norb, norb).

  • The OptimizeResult returned by scipy.optimize.minimize().

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

  • ValueError – max_vecs is less than 1.

  • ValueError – diag_coulomb_indices contains lower triangular indices.

  • ValueError – The initial guess has no terms. This includes the case where initial_guess is not specified and the exact factorization has no terms.

  • ValueError – The shapes of the initial guess tensors are inconsistent.

  • ValueError – The initial guess tensors are complex-valued.