from qiskit_aer.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit.library import RealAmplitudes

ansatz = RealAmplitudes(num_qubits=2, reps=2)
observable = SparsePauliOp.from_list([("XX", 1), ("YY", 2), ("ZZ", 3)])

estimator = Estimator()
result = estimator.run(ansatz, observable, parameter_values=[0, 1, 1, 2, 3, 5]).result()
print("Expectation value:", result.values)

estimator = Estimator(approximation=True)
result = estimator.run(ansatz, observable, parameter_values=[0, 1, 1, 2, 3, 5]).result()
print("Expectation value:", result.values)

from itertools import product
import numpy as np

num_qubits = 8
abelian_grouping = True

ansatz = RealAmplitudes(num_qubits=num_qubits, reps=1)
observables = [
    SparsePauliOp("".join(pauli_str)) for pauli_str in product("IZ", repeat=num_qubits)
]
parameter_values = list(np.random.rand(1, ansatz.num_parameters))
estimator = Estimator(abelian_grouping=abelian_grouping)

%%time
result = estimator.run(
    circuits=[ansatz] * len(observables),
    observables=observables,
    parameter_values=parameter_values * len(observables),
).result()

# opflow and estimator can group
SparsePauliOp(["XX", "XI"])

# Estimator can group
[SparsePauliOp("XX"), SparsePauliOp("XI")]