netket.experimental.vqs.DeterminantVariationalState#

class netket.experimental.vqs.DeterminantVariationalState[source]#

Bases: VariationalState

Variational State for fermionic mean-field states (Hartree-Fock ansatz).

This state represents a Slater determinant wavefunction using a Slater2nd model and computes expectation values analytically using Wick’s theorem rather than Monte Carlo sampling, which is efficient.

The state internally constructs and uses a Slater2nd model, which supports three types of Hartree-Fock ansΓ€tze:

  • Generalized Hartree-Fock (GHF): generalized=True Uses \(n_{\mathrm{M}} \times n_{\mathrm{f}}\) parameters where \(n_{\mathrm{M}}\) is the number of fermionic modes and \(n_{\mathrm{f}}\) is the number of fermions. This is the most flexible ansatz but has the most parameters.

  • Unrestricted Hartree-Fock (UHF): generalized=False, restricted=False Uses \(n_{\mathrm{S}} \times n_{\mathrm{L}} \times n_{\textrm{f, s}}\) parameters where \(n_{\mathrm{S}}\) is the number of spin states, \(n_{\mathrm{L}}\) is the number of spatial orbitals, and \(n_{\textrm{f, s}}\) is the number of fermions per spin. Allows different spatial orbitals for different spins (can describe magnetic states).

  • Restricted Hartree-Fock (RHF): generalized=False, restricted=True Uses \(n_{\mathrm{L}} \times n_{\textrm{f, s}}\) parameters. All spins share the same spatial orbitals (appropriate for non-magnetic ground states).

See Slater2nd for more details on the different Hartree-Fock types and their mathematical formulation.

Inheritance
Inheritance diagram of netket.experimental.vqs.DeterminantVariationalState
__init__(hilbert, *, generalized=False, restricted=True, param_dtype=<class 'float'>, variables=None, seed=None)[source]#

Constructs the DeterminantVariationalState.

This constructor automatically creates an internal Slater2nd model with the specified Hartree-Fock type.

Warning

If unspecified the parameters will be completely random, which is a very bad initialization for a Slater Determinant. Consider initializing using something more reasonable, like the k-space tight-binding orbitals or something similar.

Parameters:
  • hilbert (SpinOrbitalFermions) – The Hilbert space. Must be a SpinOrbitalFermions with fixed particle number (n_fermions must not be None).

  • generalized (bool) – If True, uses Generalized Hartree-Fock (GHF) with \(n_{\mathrm{M}} \times n_{\mathrm{f}}\) parameters. If False, the type depends on the restricted parameter. See Slater2nd for details. Default: False.

  • restricted (bool) – Only used when generalized=False. If True, uses Restricted Hartree-Fock (RHF) with \(n_{\mathrm{L}} \times n_{\textrm{f, s}}\) parameters where all spins share spatial orbitals. If False, uses Unrestricted Hartree-Fock (UHF) with separate orbitals per spin. See Slater2nd for details. Default: True.

  • param_dtype (Union[None, str, type[Any], dtype, _SupportsDType]) – The dtype of the variational parameters (float or complex). Default: float.

  • variables (Any | None) – Optional dictionary for the initial values for the variables (parameters and model state) of the model. If not provided, parameters are randomly initialized using the seed.

  • seed (Union[int, Any, None]) – Random seed used to generate initial parameters (only used if variables is not provided). Defaults to a random seed.

Example

>>> import netket as nk
>>> # Create a spin-1/2 fermionic Hilbert space
>>> hi = nk.hilbert.SpinOrbitalFermions(4, s=1/2, n_fermions_per_spin=(2, 2))
>>> # Create a Restricted Hartree-Fock state (non-magnetic)
>>> vstate = nk.experimental.vqs.DeterminantVariationalState(
...     hi, generalized=False, restricted=True, seed=42
... )
>>> print(vstate.n_parameters)  # Number of variational parameters
8
Attributes
hilbert#

The descriptor of the Hilbert space on which this variational state is defined.

model#

Returns the model definition of this variational state.

This field is optional, and is set to None if the variational state has been initialized using a custom function.

model_state#

The optional PyTree with the mutable state of the model, which is not optimized.

n_parameters#

The total number of parameters in the model.

parameters#

The pytree of the parameters of the model.

rdm#

The one-body reduced density matrix of the mean-field state.

This is computed from the Slater determinant parameters and cached until parameters are updated.

Returns:

The density matrix of shape (n_modes, n_modes) where n_modes is hilbert.size.

variables#

The PyTree containing the parameters and state of the model, used when evaluating it.

mutable: bool | str | Collection[str] | DenyList#

Specifies which collections in the model_state should be treated as mutable. Largely unused.

Methods
expect(O)[source]#

Estimates the quantum expectation value for a given operator \(O\) or generic observable. In the case of a pure state \(\psi\) and an operator, this is \(\langle O\rangle= \langle \Psi|O|\Psi\rangle/\langle\Psi|\Psi\rangle\) otherwise for a mixed state \(\rho\), this is \(\langle O\rangle= \textrm{Tr}[\rho \hat{O}]/\textrm{Tr}[\rho]\).

Parameters:

O (AbstractOperator) – the operator or observable for which to compute the expectation value.

Return type:

Stats

Returns:

An estimation of the quantum expectation value \(\langle O\rangle\).

expect_and_forces(O, *, mutable=None)[source]#

Estimates the quantum expectation value and the corresponding force vector for a given operator O.

The force vector \(F_j\) is defined as the covariance of log-derivative of the trial wave function and the local estimators of the operator. For complex holomorphic states, this is equivalent to the expectation gradient \(\frac{\partial\langle O\rangle}{\partial(\theta_j)^\star} = F_j\). For real-parameter states, the gradient is given by \(\frac{\partial\partial_j\langle O\rangle}{\partial\partial_j\theta_j} = 2 \textrm{Re}[F_j]\).

Parameters:
  • O (AbstractOperator) – The operator O for which expectation value and force are computed.

  • mutable (Union[bool, str, Collection[str], DenyList, None]) – Can be bool, str, or list. Specifies which collections in the model_state should be treated as mutable: bool: all/no collections are mutable. str: The name of a single mutable collection. list: A list of names of mutable collections. This is used to mutate the state of the model while you train it (for example to implement BatchNorm. Consult Flax’s Module.apply documentation for a more in-depth explanation).

Return type:

tuple[Stats, Any]

Returns:

An estimate of the quantum expectation value <O>. An estimate of the force vector \(F_j = \textrm{Cov}[\partial_j\log\psi, O_{\textrm{loc}}]\).

expect_and_grad(O, *, mutable=None, **kwargs)[source]#

Estimates the quantum expectation value and its gradient for a given operator \(O\).

Parameters:
  • O (AbstractOperator) – The operator \(O\) for which expectation value and gradient are computed.

  • mutable (Union[bool, str, Collection[str], DenyList, None]) –

    Can be bool, str, or list. Specifies which collections in the model_state should be treated as mutable: bool: all/no collections are mutable. str: The name of a single mutable collection. list: A list of names of mutable collections. This is used to mutate the state of the model while you train it (for example to implement BatchNorm. Consult Flax’s Module.apply documentation for a more in-depth explanation).

  • use_covariance – whether to use the covariance formula, usually reserved for hermitian operators, \(\textrm{Cov}[\partial\log\psi, O_{\textrm{loc}}\rangle]\)

Return type:

tuple[Stats, Any]

Returns:

An estimate of the quantum expectation value <O>. An estimate of the gradient of the quantum expectation value <O>.

grad(Γ”, *, use_covariance=None, mutable=None)[source]#

Estimates the gradient of the quantum expectation value of a given operator O.

Parameters:
Returns:

An estimation of the average gradient of the quantum expectation value <O>.

Return type:

array

init(seed=None, dtype=None)[source]#

Initialises the variational parameters of the variational state.

init_parameters(init_fun=None, *, seed=None)[source]#

Re-initializes all the parameters with the provided initialization function, defaulting to the normal distribution of standard deviation 0.01.

Warning

The init function will not change the dtype of the parameters, which is determined by the model. DO NOT SPECIFY IT INSIDE THE INIT FUNCTION

Parameters:
  • init_fun (Callable[[Any, Sequence[int], Union[None, str, type[Any], dtype, _SupportsDType]], Array] | None) – a jax initializer such as jax.nn.initializers.normal(). Must be a Callable taking 3 inputs, the jax PRNG key, the shape and the dtype, and outputting an array with the valid dtype and shape. If left unspecified, defaults to jax.nn.initializers.normal(stddev=0.01)

  • seed (Any | None) – Optional seed to be used. The seed is synced across all JAX processes. If unspecified, uses a random seed.

log_value(Οƒ)[source]#
Return type:

Array

Parameters:

Οƒ (Array)

quantum_geometric_tensor(qgt_T=None)[source]#

Compute the centered quantum geometric tensor (QGT) for the Slater determinant.

For a Slater determinant, the QGT can be computed analytically using the formula:

\[Q_{(\mu i),(\nu j)} = \delta_{ij} \left[\delta_{\mu\nu} - \gamma_{\mu\nu}\right]\]

where \(\gamma = C C^\dagger\) is the one-body reduced density matrix.

This method returns a DenseOperator wrapping the dense QGT matrix, compatible with the standard NetKet QGT interface.

Parameters:

qgt_T – Optional QGT type/constructor. If None, defaults to QGTByWick.

Returns:

A DenseOperator wrapping the centered QGT matrix of shape (n_parameters, n_parameters).

Note

  • Generalized HF: Matrix of shape (n_modes Γ— n_fermions, n_modes Γ— n_fermions)

  • Restricted HF: Matrix of shape (n_orbitals Γ— n_fermions_per_spin, n_orbitals Γ— n_fermions_per_spin)

  • Unrestricted HF: Block-diagonal matrix with blocks for each spin sector

Example

>>> import netket as nk
>>> hi = nk.hilbert.SpinOrbitalFermions(4, s=1/2, n_fermions_per_spin=(2, 2))
>>> vstate = nk.experimental.vqs.DeterminantVariationalState(
...     hi, generalized=False, restricted=True, seed=42
... )
>>> qgt = vstate.quantum_geometric_tensor()
>>> print(qgt.matrix.shape)  # (8, 8)
(8, 8)
>>> print(vstate.n_parameters)  # 8
8
reset()[source]#

Resets the cached density matrix. Called automatically when parameters/state is updated.

to_array(normalize=True)[source]#

Returns the dense-vector representation of this state.

Parameters:

normalize (bool) – If True, the vector is normalized to have L2-norm 1.

Return type:

Array

Returns:

An exponentially large vector representing the state in the computational basis.

to_fullsumstate(**kwargs)[source]#

Convert this DeterminantVariationalState to a FullSumState.

Warning

Only feasible for small systems due to exponential Hilbert space size.

Parameters:

**kwargs – Additional arguments passed to FullSumState constructor (e.g., chunk_size)

Returns:

A FullSumState with the same model and parameters

to_mcstate(sampler, n_samples=None, n_samples_per_rank=None, **kwargs)[source]#

Convert this DeterminantVariationalState to an MCState for sampling-based calculations.

Parameters:
  • sampler (Sampler) – The sampler to use for the MCState (e.g., MetropolisFermionHop)

  • n_samples (int | None) – Number of samples for Monte Carlo estimation

  • n_samples_per_rank (int | None) – Alternative specification of samples per MPI rank

  • **kwargs – Additional arguments passed to MCState constructor (e.g., n_discard_per_chain, chunk_size)

Returns:

An MCState with the same model and parameters

Example

>>> import netket as nk
>>> # Create a fermionic Hilbert space and graph
>>> g = nk.graph.Chain(4)
>>> hi = nk.hilbert.SpinOrbitalFermions(4, s=1/2, n_fermions_per_spin=(2, 2))
>>> # Create a determinant variational state
>>> mf_state = nk.experimental.vqs.DeterminantVariationalState(
...     hi, generalized=False, restricted=True, seed=42
... )
>>> # Convert to MCState for Monte Carlo sampling
>>> sampler = nk.sampler.MetropolisFermionHop(hi, graph=g)
>>> mc_state = mf_state.to_mcstate(sampler, n_samples=1024)
>>> qgt = mc_state.quantum_geometric_tensor()
to_qobj()[source]#

Convert the variational state to a qutip’s ket Qobj.

Returns:

A qutip.Qobj object.