Skip to content

Computing observables

All emulators (backends) share a convenient way to define observables to be tracked during the simulation, as defined in pulser. The default available observables are listed below, together with examples for how to create them.

Example

How to use created observables to obtain results from an emulation is shown in the example notebooks for emu-sv and for emu-mps.

Warning

Please, take into account that, for performance reasons, individual emulators may overwrite the default implementation in pulser.

StateResult

Bases: Observable

Stores the quantum state at the evaluation times.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to store the state. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

apply(*, state, **kwargs)

Calculates the observable to store in the Results.

BitStrings

Bases: Observable

Stores bitstrings sampled from the state at the evaluation times.

Error rates are taken from the NoiseModel passed to the backend via the EmulationConfig. The bitstrings are stored as a Counter[str].

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to sample bitstrings. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

num_shots

How many bitstrings to sample each time this observable is computed.

TYPE: int DEFAULT: 1000

one_state

The eigenstate that measures to 1. Can be left undefined if the state's eigenstates form a known eigenbasis with a defined "one state".

TYPE: Eigenstate | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

Initializes the observable.

apply(*, config, state, **kwargs)

Calculates the observable to store in the Results.

Fidelity

Bases: Observable

Stores the fidelity with a pure state at the evaluation times.

The fidelity uses the overlap between the given state and the state of the system at each evaluation time. For pure states, this corresponds to |<ψ|φ(t)>|^2 for the given state |ψ> and the state |φ(t)> obtained by time evolution.

PARAMETER DESCRIPTION
state

The state |ψ>. Note that this must be of an appropriate type for the backend.

TYPE: State

evaluation_times

The relative times at which to compute the fidelity. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

Initializes the observable.

apply(*, state, **kwargs)

Calculates the observable to store in the Results.

Expectation

Bases: Observable

Stores the expectation of the given operator on the current state.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the expectation value. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

operator

The operator to measure. Must be of the appropriate type for the backend.

TYPE: Operator

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

Initializes the observable.

apply(*, state, **kwargs)

Calculates the observable to store in the Results.

CorrelationMatrix

Bases: Observable

Stores the correlation matrix for the current state.

The correlation matrix is calculated as [[<φ(t)|n_i n_j|φ(t)> for j in qubits] for i in qubits] where n_k = |one_state><one_state|.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the correlation matrix. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

one_state

The eigenstate to measure the population of in the correlation matrix. Can be left undefined if the state's eigenstates form a known eigenbasis with a defined "one state".

TYPE: Eigenstate | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

Initializes the observable.

apply(*, state, hamiltonian, **kwargs)

Calculates the observable to store in the Results.

QubitDensity

Bases: Observable

Stores the occupation number of an eigenstate on each qudit.

For every qudit i, calculates <φ(t)|n_i|φ(t)>, where n_i = |one_state><one_state|.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the correlation matrix. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

one_state

The eigenstate to measure the population of. Can be left undefined if the state's eigenstates form a known eigenbasis with a defined "one state".

TYPE: Eigenstate | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

Initializes the observable.

apply(*, state, hamiltonian, **kwargs)

Calculates the observable to store in the Results.

Energy

Bases: Observable

Stores the energy of the system at the evaluation times.

The energy is calculated as the expectation value of the Hamiltonian, i.e. <φ(t)|H(t)|φ(t)>.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the energy. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

apply(*, state, hamiltonian, **kwargs)

Calculates the observable to store in the Results.

EnergyVariance

Bases: Observable

Stores the variance of the Hamiltonian at the evaluation times.

The variance of the Hamiltonian at time t is calculated by <φ(t)|H(t)^2|φ(t)> - <φ(t)|H(t)|φ(t)>^2

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the variance. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

apply(*, state, hamiltonian, **kwargs)

Calculates the observable to store in the Results.

SecondMomentOfEnergy

Bases: Observable

Stores the expectation value of H(t)^2 at the evaluation times.

Useful for computing the variance when averaging over many executions of the program.

PARAMETER DESCRIPTION
evaluation_times

The relative times at which to compute the variance. If left as None, uses the default_evaluation_times of the backend's EmulationConfig.

TYPE: Sequence[float] | None DEFAULT: None

tag_suffix

An optional suffix to append to the tag. Needed if multiple instances of the same observable are given to the same EmulationConfig.

TYPE: str | None DEFAULT: None

apply(*, state, hamiltonian, **kwargs)

Calculates the observable to store in the Results.

Defining your own observable

Most commonly desired information can be obtained using the classes documented above

  • Arbitrary observables can be measured using Expectation(operator, ...) which requires providing a valid operator for the backend in use.
  • Fidelities on arbitrary states can be computed using Fidelity(state, ...) which requires providing a valid state for the backend in use.
  • Information about the time dependent states and Hamiltonians is available via StateResult, Energy etc.

If additional behavior is desired (e.g. the kurtosis of the energy, or entanglement entropy), the user can subclass the Observable class to implement any behavior only depending on the parameters of its apply method (see here). Computation of the entanglement entropy, for example, cannot be done in a backend-independent manner, so it is unlikely to ever make it into the above default list. However, we do intend to define backend-specific callbacks in the future, which would belong to the API of a specific backend. Callbacks that can be implemented in a backend-independent manner can be added to the above list upon popular request.

Observables on remote backend

In heavy simulations, the entire quantum state can easily occupy few GBs while operators, might not even fit into the available memory. For this reason, only for remote backend execution on pasaqal-cloud, and when defining a state/operator :

Info

  • state in Fidelity(state, ...), besides being a proper state for the backend, must also be defined with its from_state_amplitudes() class method.
  • operator in Expectation(operator, ...), besides being a proper operator for the backend, must also be defined with its from_operator_repr() class method.

The methods above requires the user to locally install a backend to instantiate a state or an operator class. It might not be desirable in all cases since, for example, pulser-simulation will install qutip, while emu-mps/sv will install torch. To avoid such dependency, the classes StateRepr, OperatorRepr just implements the abstract representation of such objects.

Tip

If the full backend is not needed, state/operator in the observable can just be defined with their abstract representation

  • StateRepr.from_state_amplitudes()
  • OperatorRepr.from_operator_repr()

Moreover, the observable

Failure

StateResult is not supported in pasaqal-cloud remote backend emulators.