Skip to content

Running estimator with non-Pauli observables - runtime #2431

@YutoMorohoshi

Description

@YutoMorohoshi

Describe the bug
Running a SparseObservable with the Estimator runtime fails:

uv run main.py

management.get:WARNING:2025-10-03 23:10:14,900: Loading saved account: YutoMorohoshiOsakaU
Traceback (most recent call last):
  File "/Users/yutomorohoshi/Desktop/test-sparse-observable/main.py", line 32, in <module>
    main()
  File "/Users/yutomorohoshi/Desktop/test-sparse-observable/main.py", line 26, in main
    job = estimator.run(pub)
          ^^^^^^^^^^^^^^^^^^
  File "/Users/yutomorohoshi/Desktop/test-sparse-observable/.venv/lib/python3.12/site-packages/qiskit_ibm_runtime/estimator.py", line 149, in run
    validate_estimator_pubs(coerced_pubs)
  File "/Users/yutomorohoshi/Desktop/test-sparse-observable/.venv/lib/python3.12/site-packages/qiskit_ibm_runtime/utils/validations.py", line 83, in validate_estimator_pubs                                                                                                                                      
    raise IBMInputValueError("Observables alphabet is limited to I, X, Y, Z")
qiskit_ibm_runtime.exceptions.IBMInputValueError: 'Observables alphabet is limited to I, X, Y, Z'

This issue is similar to #15113, where it was reported that executing SparseObservable with StatevectorEstimator fails.
By using SparseObservable, the probability of obtaining a specific bitstring can be expressed as the expectation value of a projector, allowing circuits to be executed with Estimator instead of Sampler. Since Estimator provides richer error-mitigation features, resolving this issue is crucial for running large-scale quantum circuits.

Steps to reproduce

from qiskit import QuantumCircuit
from qiskit.quantum_info import SparseObservable
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator


def main():
    service = QiskitRuntimeService()
    backend = service.least_busy()

    n_qubits = 2
    qc = QuantumCircuit(n_qubits)
    qc.h(0)
    for i in range(1, n_qubits):
        qc.cx(0, i)

    # If chaning "Z" to "0", ie., projecting (|0><0|), it fails.
    observable = SparseObservable.from_label("0" * n_qubits)

    pass_manager = generate_preset_pass_manager(optimization_level=1, backend=backend)
    isa_circuit = pass_manager.run(qc)
    isa_observable = observable.apply_layout(isa_circuit.layout)

    pub = [(isa_circuit, isa_observable)]
    estimator = Estimator(mode=backend)
    job = estimator.run(pub)
    result = job.result()
    print(f"Expected value: {result[0].data.evs}")


if __name__ == "__main__":
    main()

Expected behavior
The expectation value of the projector |00...0><00...0|, i.e., the probability that all qubits are measured in the 0 state, should be returned. For the above 2-qubit GHZ example, the expected probability is 0.5.

Suggested solutions
According to the error message, Observables array in Estimator PUB only validates characters I, X, Y, Z. However, looking at the code, Observables array is forcibly converted into SparseObservable through coerce_observable():
https://github.com/Qiskit/qiskit/blob/041c0425701bc61a61a212bbf2e2716f04993552/qiskit/primitives/containers/observables_array.py#L252

This means the Estimator PUB’s Observables array should validate not only I, X, Y, Z, but also digits such as 0 and 1 (i.e., projectors). Therefore, the validation process in validate_estimator_pubs() (located in qiskit_ibm_runtime/utils/validations.py) should be modified accordingly.

Additional Information

  • qiskit-ibm-runtime version: 0.42.0
  • Python version: 3.12
  • Operating system: macOS 26.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions