quspin.tools.measurements.obs_vs_time

quspin.tools.measurements.obs_vs_time(psi_t, times, Obs_dict, return_state=False, Sent_args={}, enforce_pure=False, verbose=False)[source]

Calculates expectation value of observable(s) as a function of time in a time-dependent state.

This function computes the expectation of a time-dependent state \(|\psi(t)\rangle\) in a time-dependent observable \(\mathcal{O}(t)\). It automatically handles the cases where only the state or only the observable is time-dependent.

\[\langle\psi(t)|\mathcal{O}(t)|\psi(t)\rangle\]
Parameters:
psi_t{tuple,aray_like,generator}

Time-dependent state data; can be either one of:

  • tuple: psi_t = (psi, E, V) where

    – np.ndarray: initial state psi.

    – np.ndarray: unitary matrix V, contains all eigenstates of the Hamiltonian \(H\).

    – np.ndarray: real-valued array E, contains all eigenvalues of the Hamiltonian \(H\).

    The order of the eigenvalues must correspond to the order of the columns of V.

    Use this option when the initial state is evolved with a time-INdependent Hamiltonian \(H\).

  • numpy.ndarray: array with the states evaluated at times stored in the last dimension.

    Can be 2D (single time-dependent state) or 3D (many time-dependent states or time-dep mixed density matrix, see enforce_pure argument.)

    Use this option for PARALLELISATION over many states.

  • obj: generator which generates the states.

Obs_dictdict

Dictionary with observables (e.g. hamiltonian objects) stored in the values, to calculate their time-dependent expectation value. Dictionary keys are chosen by user.

timesnumpy.ndarray

Vector of times to evaluate the expectation values at. This is important for time-dependent observables.

return_statebool, optional

If set to True, adds key “psi_time” to output. The columns of the array contain the state vector at the times which specifies the column index. Default is False, unless Sent_args is nonempty.

Srdm_argsdict, optional

If nonempty, this dictionary contains the arguments necessary for the calculation of the entanglement entropy. The following key is required:

  • “basis”: the basis used to build system_state in. Must be an instance of the basis class.

The user can choose optional arguments according to those provided in the function method basis.ent_entropy() of the basis class [preferred], or the function ent_entropy().

If only the basis is passed, the default parameters of basis.ent_entropy() are assumed.

enforce_purebool, optional

Flag to enforce pure state expectation values in the case that psi_t is an array of pure states in the columns. (psi_t will otherwise be interpreted as a mixed density matrix).

verbosebool, optional

If set to True, displays a message at every times step after the calculation is complete. Default is False.

Returns:
dict

The following keys of the output are possible, depending on the choice of flags:

  • “custom_name”: for each key of Obs_dict, the time-dependent expectation of the

    corresponding observable Obs_dict[key] is calculated and returned under the user-defined name for the observable.

  • “psi_t”: (optional) returns time-dependent state, if return_state=True or Srdm_args is nonempty.

  • “Sent_time”: (optional) returns dictionary with keys corresponding to the entanglement entropy

    calculation for each time in times. Can have more keys than just “Sent_A”, e.g. if the reduced DM was also requested (toggled through Srdm_args.)

Examples

The following example shows how to calculate the expectation values \(\langle\psi_1(t)|H_1|\psi_1(t)\rangle\) and \(\langle\psi_1(t)|H_2|\psi_1(t)\rangle\).

The initial state is an eigenstate of \(H_1=\sum_j hS^x_j + g S^z_j\). The time evolution is done under \(H_2=\sum_j JS^z_{j+1}S^z_j+ hS^x_j + g S^z_j\).

 1from quspin.basis import spin_basis_1d  # Hilbert space spin basis
 2from quspin.tools.measurements import obs_vs_time
 3import numpy as np  # generic math functions
 4
 5#
 6L = 12  # syste size
 7# coupling strenghts
 8J = 1.0  # spin-spin coupling
 9h = 0.8945  # x-field strength
10g = 0.945  # z-field strength
11# create site-coupling lists
12J_zz = [[J, i, (i + 1) % L] for i in range(L)]  # PBC
13x_field = [[h, i] for i in range(L)]
14z_field = [[g, i] for i in range(L)]
15# create static and dynamic lists
16static_1 = [["x", x_field], ["z", z_field]]
17static_2 = [["zz", J_zz], ["x", x_field], ["z", z_field]]
18dynamic = []
19# create spin-1/2 basis
20basis = spin_basis_1d(L, kblock=0, pblock=1)
21# set up Hamiltonian
22H1 = hamiltonian(static_1, dynamic, basis=basis, dtype=np.float64)
23H2 = hamiltonian(static_2, dynamic, basis=basis, dtype=np.float64)
24# compute eigensystems of H1 and H2
25E1, V1 = H1.eigh()
26psi1 = V1[:, 14]  # pick any state as initial state
27E2, V2 = H2.eigh()
28#
29# time-evolve state under H2
30times = np.linspace(0.0, 5.0, 10)
31psi1_t = H2.evolve(psi1, 0.0, times, iterate=True)
32# calculate expectation values of observables
33Obs_time = obs_vs_time(psi1_t, times, dict(E1=H1, Energy2=H2), return_state=True)
34print("Output keys are same as input keys:", Obs_time.keys())
35E1_time = Obs_time["E1"]
36psi_time = Obs_time["psi_t"]