Measurement utilities

Various convenience functions for measurements on a quantum computer or wavefunction simulator.

Some preliminary explanation

Measuring the expectation value of a hamiltonian like

\[H = a Z_0 Z_1 + b Z_1 Z_2 + c X_0 X_1 + d X_1 + e X_2\]

requires decomposing the hamiltonian into parts that commute with each other and then measuring them succesively. On a real QPU we need to do this, because physics don’t allow us to measure non-commuting parts of a hamiltonian in one run. On the Wavefunction Simulator we need to do this, because translating \(\left< \psi | H | \psi \right>\) naively to wf.conj()@ham@wf.conj() results in huge and sparse matrices ham that take longer to generate, than it takes to calculate the wavefunction wf.

Even though \(Z_0 Z_1\) and \(X_0 X_1\) commute (go ahead and check it), we will measure them in separate runs, because measuring them simultaenously can’t be done by simply measuring the qubits 0 and 1. We only attempt to measure Pauli products simultaneously that commute trivially. Two Pauli products commute trivially, if on each qubit both act with the same Pauli Operator, or if either one acts only with the identity. This implies in particular, that they can be measured without the need for ancilla qubits.

vqe.measurelib.H_mat = array([[ 0.70710678, 0.70710678], [ 0.70710678, -0.70710678]])
vqe.measurelib.RX_mat = array([[ 0.70710678+0.j , -0. -0.70710678j], [-0. -0.70710678j, 0.70710678+0.j ]])
vqe.measurelib.append_measure_register(program, qubits=None, trials=10, ham=None)

Creates readout register, MEASURE instructions for register and wraps in trials numshots.

  • qubits (param) – List of Qubits to measure. If None, program.get_qubits() is used

  • trials (param) – The number of trials to run.

  • ham (param) – Hamiltonian to whose basis we need to switch. All terms in it must trivially commute. No base change gates are applied, if None is passed.


program with the gate change and measure instructions appended

Return type


vqe.measurelib.apply_H(qubit, n_qubits, wf)

Apply a hadamard gate to wavefunction wf on the qubit qubit

Return type

<built-in function array>

vqe.measurelib.apply_RX(qubit, n_qubits, wf)

Apply a RX(pi/2) gate to wavefunction wf on the qubit qubit

Return type

<built-in function array>

vqe.measurelib.base_change_fun(ham, qubits)

Create a function that applies the correct base change for ham on a wavefunction on n_qubits qubits.

Return type



Decompose ham into a list of PauliSums with mutually commuting terms.

Return type


vqe.measurelib.kron_eigs(ham, qubits)

Calculate the eigenvalues of ham ordered as a tensorproduct on qubits. Each qubit should be acted on with the same operator by each term or not at all.

Return type

<built-in function array>

vqe.measurelib.sampling_expectation(hamiltonians, bitstrings)

Mapped wrapper around sampling_expectation_z_base.

A function that computes expectation values of a list of hamiltonians w.r.t a list of bitstrings. Assumes, that each pair in zip(hamiltonians, bitstrings) is as needed by sampling_expectation_z_base

  • hamiltonians (List[PauliSum]) – List of PauliSums. Each PauliSum must only consist of mutually commuting terms

  • bitstrings (List[np.array]) – List of the measured bitstrings. Each bitstring must have dimensions corresponding to the coresponding PauliSum


Return type

tuple (expectation_value, standard_deviation)

vqe.measurelib.sampling_expectation_z_base(hamiltonian, bitstrings)

Calculates the energy expectation value of bitstrings w.r.t ham.


This function assumes, that all terms in hamiltonian commute trivially _and_ that the bitstrings were measured in their basis.

  • hamiltonian (param) – The hamiltonian

  • bitstrings (param) – The measurement outcomes. One column per qubit.


Return type

tuple (expectation_value, variance/(n-1))

vqe.measurelib.wavefunction_expectation(hams_eigs, base_changes, hams_squared_eigs, base_changes_squared, wf)

Compute the exp. value and standard dev. of hams w.r.t wf.

  • hams_eigs (List[np.array]) – A list of arrays of eigenvalues of the PauliSums in the commuting decomposition of the original hamiltonian.

  • base_changes (List[Callable]) – A list of functions that apply the neccesary base change gates to the wavefunction

  • hams_squared_eigs (List[np.array]) – The same as hams, but for the square of ham.

  • base_changes_squared (List[Callable]) – The same as base_changes, but for the square of ham.

  • wf (<built-in function array>) – The wavefunction whose expectation value we want to know.


A tuple containing the expectation value of ham and the expectation value of ham**2.

Return type

Tuple[float, float]