Callbacks#
Callbacks provide a way to calculate quantities on the state vector as it
propagates through the circuit. Example of such quantity is the entanglement
entropy, which is currently the only callback implemented in
qibo.callbacks.EntanglementEntropy.
The user can create custom callbacks by inheriting the
qibo.callbacks.Callback class. The point each callback is
calculated inside the circuit is defined by adding a qibo.gates.CallbackGate.
This can be added similarly to a standard gate and does not affect the state vector.
- class qibo.callbacks.Callback[source]#
Base callback class.
Results of a callback can be accessed by indexing the corresponding object.
- property nqubits#
Total number of qubits in the circuit that the callback was added in.
Entanglement entropy#
- class qibo.callbacks.EntanglementEntropy(partition=None, compute_spectrum=False, base=2)[source]#
Von Neumann entanglement entropy callback.
\[S = \mathrm{Tr} \left ( \rho \log _2 \rho \right )\]- Parameters:
Example
from qibo import Circuit, gates from qibo.callbacks import EntanglementEntropy # create entropy callback where qubit 0 is the first subsystem entropy = EntanglementEntropy([0], compute_spectrum=True) # initialize circuit with 2 qubits and add gates circuit = Circuit(2) # add callback gates between normal gates circuit.add(gates.CallbackGate(entropy)) circuit.add(gates.H(0)) circuit.add(gates.CallbackGate(entropy)) circuit.add(gates.CNOT(0, 1)) circuit.add(gates.CallbackGate(entropy)) # execute the circuit final_state = circuit() print(entropy[:]) # Should print [0, 0, 1] which is the entanglement entropy # after every gate in the calculation. print(entropy.spectrum) # Print the entanglement spectrum.
- property nqubits#
Total number of qubits in the circuit that the callback was added in.
Norm#
Overlap#
- class qibo.callbacks.Overlap(state)[source]#
State overlap callback.
Calculates the overlap between the circuit state and a given target state:
\[\mathrm{Overlap} = |\left \langle \Phi | \Psi \right \rangle |\]- Parameters:
state (np.ndarray) – Target state to calculate overlap with.
normalize (bool) – If
Truethe states are normalized for the overlap calculation.
Energy#
- class qibo.callbacks.Energy(hamiltonian)[source]#
Energy expectation value callback.
Calculates the expectation value of a given Hamiltonian as:
\[\left \langle H \right \rangle = \left \langle \Psi | H | \Psi \right \rangle = \mathrm{Tr} (\rho H)\]assuming that the state is normalized.
- Parameters:
hamiltonian (
qibo.hamiltonians.Hamiltonian) – Hamiltonian object to calculate its expectation value.
Gap#
- class qibo.callbacks.Gap(mode='gap', check_degenerate=True)[source]#
Callback for calculating the gap of adiabatic evolution Hamiltonians.
Can also be used to calculate the Hamiltonian eigenvalues at each time step during the evolution. Note that this callback can only be added in
qibo.evolution.AdiabaticEvolutionmodels.- Parameters:
mode (str/int) – Defines which quantity this callback calculates. If
mode == 'gap'then the difference between ground state and first excited state energy (gap) is calculated. Ifmodeis an integer, then the energy of the corresponding eigenstate is calculated.check_degenerate (bool) – If
Truethe excited state number is increased until a non-zero gap is found. This is used to find the proper gap in the case of degenerate Hamiltonians. This flag is relevant only ifmodeis'gap'. Default isTrue.
Example
from qibo import callbacks, hamiltonians from qibo.models import AdiabaticEvolution # define easy and hard Hamiltonians for adiabatic evolution h0 = hamiltonians.X(3) h1 = hamiltonians.TFIM(3, h=1.0) # define callbacks for logging the ground state, first excited # and gap energy ground = callbacks.Gap(0) excited = callbacks.Gap(1) gap = callbacks.Gap() # define and execute the ``AdiabaticEvolution`` model evolution = AdiabaticEvolution(h0, h1, lambda t: t, dt=1e-1, callbacks=[gap, ground, excited]) final_state = evolution(final_time=1.0) # print results print(ground[:]) print(excited[:]) print(gap[:])