ffsim.linalg.double_factorized_t2_compressed

ffsim.linalg.double_factorized_t2_compressed(t2_amplitudes, *, initial_guess=None, max_terms=None, diag_coulomb_indices=None, regularization=0, multi_stage_start=None, multi_stage_step=None, **optimize_kwargs)[source]

Compress a double-factorized decomposition of \(t_2\) amplitudes.

Optimizes the diagonal Coulomb matrices and orbital rotations of a double-factorized decomposition of \(t_2\) amplitudes (see double_factorized_t2()) 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_t2() with the default tolerance is used. To use a different tolerance, call double_factorized_t2() yourself, without max_terms so that the optimization starts from the full factorization, and pass its output as initial_guess. If max_terms is specified, then the factorization is truncated to its first max_terms terms. The optimization is always performed, even if no terms are truncated.

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\).

A “multi-stage” optimization can be requested by passing either multi_stage_start or multi_stage_step. In multi-stage optimization, the number of terms is iteratively reduced by multi_stage_step, starting from multi_stage_start, until there are only max_terms remaining. This procedure can yield a more accurate factorization at the cost of increased running time. If you only pass one of multi_stage_start or multi_stage_step, then the value of the other is chosen automatically: multi_stage_start defaults to the number of terms in the initial guess, and multi_stage_step defaults to 1. If max_terms is not specified or is at least the number of terms in the initial guess, a single stage of optimization is run with all of the terms, and these arguments have no effect.

Note: Currently, only real-valued \(t_2\) amplitudes are supported.

Parameters:
  • t2_amplitudes (ndarray) – The doubles amplitudes tensor of shape (nocc, nocc, nvrt, nvrt), where nocc is the number of occupied orbitals and nvrt is the number of virtual orbitals.

  • 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). Typically, this is the untruncated output of double_factorized_t2(). If not specified, the exact factorization computed by double_factorized_t2() with the default tolerance is used.

  • max_terms (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\).

  • regularization (float) – Parameter for regularizing the norm of the diagonal Coulomb matrices. This specifies the coefficient to a term added to the loss function equal to the difference between the sums of the squares of the Frobenius norms of the diagonal Coulomb matrices from the optimized factorization and the initial guess.

  • multi_stage_start (int | None) – The number of terms to start multi-stage optimization.

  • multi_stage_step (int | None) – The number of terms to eliminate in each stage of multi-stage optimization.

  • 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() in the last stage of the optimization.

Raises:
  • ValueError – The t2 amplitudes are complex-valued.

  • ValueError – max_terms is less than 1.

  • ValueError – multi_stage_start or multi_stage_step 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.