Read several observables from one final state¶
Prepare a Bell state and evaluate Z on qubit 0, X on qubit 0, and ZZ on the pair. These observables answer different questions about the same state. Complete the Bell lesson and Hamiltonians and observables first.
For (|00⟩ + |11⟩)/√2, each single-qubit Z measurement is balanced, so ⟨Z₀⟩ = 0. Each qubit alone also has ⟨X₀⟩ = 0. Both occupied bitstrings have even parity, giving ⟨Z₀Z₁⟩ = 1. A vanishing single-site expectation therefore does not mean the pair is uncorrelated.
Request one batch¶
"""Evaluate several typed observables from one Digital final state.
An ``ObservableSet`` requests a batch without rerunning the program for each
operator. Exact state evaluation preserves expectation, variance, estimator
kind, sample count, and source identity in one typed result.
"""
from __future__ import annotations
import json
from cascaqit import Circuit, LocalBackend, ObservableSet, PauliX, PauliZ, PauliZZ
def main() -> None:
"""Prepare a Bell state and evaluate X, Z, and ZZ together."""
circuit = Circuit(2, program_id="lesson.digital.observables").h(0).cx(0, 1)
observables = ObservableSet((PauliZ("q0"), PauliX("q0"), PauliZZ("q0", "q1")))
result = (
LocalBackend(seed=204).run(circuit, shots=32, observables=observables).result()
)
batch = result.observable_batch
if batch is None:
raise RuntimeError("Requested observable batch was not returned.")
payload = {
"track": "digital_developer",
"level": "advanced",
"lesson": "observable_batch",
"facts": {
"source_kind": batch.source_kind.value,
"observable_names": [item.name for item in batch.items],
"expectations": [round(item.expectation, 10) for item in batch.items],
"estimator_kinds": [item.estimator_kind.value for item in batch.items],
"source_hash_matches": batch.source_hash == result.metadata["state_hash"],
},
"boundaries": {
"hardware_execution": False,
"cloud_execution": False,
"network_accessed": False,
"credentials_loaded": False,
},
}
print(json.dumps(payload, sort_keys=True))
if __name__ == "__main__":
main()
python3 examples/user/tracks/digital_developer/04_advanced_observable_batch_en.py
ObservableSet preserves declaration order. Each name must be unique, and targets such as q0 must exist in the program. The backend evolves the program once and evaluates all three terms from its final source.
{
"boundaries": {
"cloud_execution": false,
"credentials_loaded": false,
"hardware_execution": false,
"network_accessed": false
},
"facts": {
"estimator_kinds": [
"exact_state",
"exact_state",
"exact_state"
],
"expectations": [
0.0,
0.0,
1.0
],
"observable_names": [
"Z(q0)",
"X(q0)",
"Z(q0)*Z(q1)"
],
"source_hash_matches": true,
"source_kind": "state_vector"
},
"lesson": "observable_batch",
"level": "advanced",
"track": "digital_developer"
}
The expected values are [0, 0, 1]. All three estimator kinds are exact_state: they are computed from the simulated state vector, even though the run also requests 32 shots. They are not sample averages inferred from those 32 Z-basis measurements. Raising shots does not change these ideal expectations.
source_hash_matches checks that the batch refers to the recorded final state. It helps detect mismatched result objects; it is not independent proof that the intended state was prepared.
Separate variance from uncertainty¶
In your copy, inspect item.variance, item.standard_error and item.sample_count for each batch item. A Pauli operator squares to identity, so its quantum variance is 1 − ⟨P⟩². Here the variances are 1, 1 and approximately 0. Exact evaluation has standard error zero and no sample count. Nonzero quantum variance and zero estimator standard error are compatible: one describes possible measurement outcomes, the other how the mean was obtained.
The observable guide explains other estimators. Trajectory means carry sampling uncertainty. Z-basis counts alone cannot recover X or Y expectation without a suitable measurement procedure.
What these three numbers cannot establish¶
A classical mixture of 00 and 11 gives the same three expectations. This batch alone does not distinguish that mixture from a coherent Bell state. To investigate the difference, include XX; the coherence lesson gives a runnable comparison using PauliProduct.
Practice: remove CX but retain H on qubit 0. Predict Z₀, X₀ and ZZ before running. Then restore CX and compare the quantum variances with the estimator standard errors.
Check your reasoning
Without CX, the state is |+0⟩: the expectations become [0, 1, 0]. Their quantum variances are [1, 0, 1], while all exact-state standard errors remain zero. In the Bell run, adding XX would give one; the incoherent 00/11 mixture gives zero. Do not call finite Z counts a measurement of X just because the simulator can calculate X from its state vector.
Finish this route by recording what actually ran.