Closed anhdpham closed 2 years ago
Hello @anhdpham, thank you for your interest in Mitiq! If this is a bug report, please provide screenshots and/or minimum viable code to reproduce your issue, so we can do our best to help get it fixed. If you have any questions in the meantime, you can also ask us on the Unitary Fund Discord.
Thanks @anhdpham for reporting this! It seems a Mitiq bug but we need to investigate more to understand the problem.
@anhdpham thanks for opening this and the other issue. If it could help clarify them, you're welcome to join the Mitiq community call on Unitary Fund's Discord, which is on Fridays at 18:00 CET (https://discord.com/invite/JqVGmpkP96).
Hi @anhdpham, could you provide more details on your Hamiltonian
, noise_model
, and installed packages? Can use the mitiq.about()
function to retrieve the installed dependencies.
I attempted to reproduce this error but was unable to with my interpretation of the provided code (plus a few fast/unchecked assumptions from tutorials), to yield ~-1.063038113954
:
from qiskit.utils import QuantumInstance
from qiskit.opflow import I, X, Y, Z, CircuitStateFn, StateFn, CircuitSampler, PauliExpectation
from qiskit.providers.aer.noise.errors.standard_errors import coherent_unitary_error
from qiskit.providers.aer.noise import NoiseModel
import qiskit.quantum_info as qi
import numpy as np
from mitiq import zne
def ansatz(parameter):
circuit = QuantumCircuit(2)
circuit.rx(parameter[0],0)
circuit.cnot(0,1)
circuit.rx(parameter[0],1)
circuit.cnot(0,1)
circuit.rx(parameter[0],0)
return circuit
epsilon = 0.1
err_h = QuantumCircuit(1, 1)
err_h.h(0)
err_h.p(epsilon, 0)
err_h.h(0)
err_h.p(-epsilon, 0)
u_err_h = qi.Operator(err_h)
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(coherent_unitary_error(u_err_h), 'h')
angles = []
for angle in np.linspace(0, 2 * np.pi, 50):
angles.append(angle)
circuits = []
for angle in angles:
circuits.append(ansatz([angle]))
Hamiltonian = (-1.0523732 * I^I) + \
(0.39793742 * I^Z) + \
(-0.3979374 * Z^I) + \
(-0.0112801 * Z^Z) + \
(0.18093119 * X^X)
def qiskit_executor(circuit: QuantumCircuit, shots: int = 8192) -> float:
quantum_instance = QuantumInstance(
backend=Aer.get_backend('qasm_simulator'),
noise_model = noise_model,
basis_gates = noise_model.basis_gates, shots=10000
)
psi = CircuitStateFn(circuit)
measurable_expression = StateFn(Hamiltonian, is_measurement=True).compose(psi)
expectation = PauliExpectation().convert(measurable_expression)
sampler = CircuitSampler(quantum_instance).convert(expectation)
value = sampler.eval().real
return value
scale_factors = [1., 1.5, 2., 2.5, 3.]
folded_circuits = [
zne.scaling.fold_gates_at_random(circuits[0], scale)
for scale in scale_factors
]
qiskit_executor(folded_circuits[0])
Hi @Aaron-Robertson. My dependancies from !pip list:
Package Version
anyio 2.2.0 appnope 0.1.2 argon2-cffi 20.1.0 async-generator 1.10 attrs 21.4.0 Babel 2.9.1 backcall 0.2.0 bleach 4.1.0 brotlipy 0.7.0 cachetools 4.2.4 certifi 2021.10.8 cffi 1.15.0 charset-normalizer 2.0.10 cirq 0.10.0 cryptography 36.0.1 cycler 0.11.0 debugpy 1.5.1 decorator 4.4.2 defusedxml 0.7.1 dill 0.3.4 docplex 2.22.213 entrypoints 0.3 fonttools 4.28.5 google-api-core 1.31.5 google-auth 1.35.0 googleapis-common-protos 1.54.0 graphviz 0.19.1 grpcio 1.43.0 gurobipy 9.5.0 h5py 3.6.0 ibm-quantum-widgets 1.0.3 idna 3.3 importlib-metadata 4.8.2 ipykernel 6.4.1 ipython 7.29.0 ipython-genutils 0.2.0 ipywidgets 7.6.5 jedi 0.18.0 Jinja2 2.11.3 joblib 1.1.0 json5 0.9.6 jsonschema 3.2.0 jupyter-client 7.1.0 jupyter-core 4.9.1 jupyter-server 1.4.1 jupyterlab 3.2.1 jupyterlab-pygments 0.1.2 jupyterlab-server 2.10.2 jupyterlab-widgets 1.0.2 kiwisolver 1.3.2 lark-parser 0.12.0 MarkupSafe 2.0.1 matplotlib 3.5.1 matplotlib-inline 0.1.2 mistune 0.8.4 mitiq 0.12.0 mpmath 1.2.1 nbclassic 0.2.6 nbclient 0.5.3 nbconvert 6.3.0 nbformat 5.1.3 nest-asyncio 1.5.1 networkx 2.5.1 notebook 6.4.6 ntlm-auth 1.5.0 numpy 1.22.2 packaging 21.3 pandas 1.3.5 pandocfilters 1.4.3 parso 0.8.3 pbr 5.8.0 pexpect 4.8.0 pickleshare 0.7.5 Pillow 9.0.0 pip 21.2.4 ply 3.11 prometheus-client 0.12.0 prompt-toolkit 3.0.20 protobuf 3.13.0 psutil 5.9.0 ptyprocess 0.7.0 pyasn1 0.4.8 pyasn1-modules 0.2.8 pycparser 2.21 Pygments 2.10.0 pylatexenc 2.10 pyOpenSSL 21.0.0 pyparsing 3.0.4 pyrsistent 0.18.0 pyscf 2.0.1 PySocks 1.7.1 python-constraint 1.4.0 python-dateutil 2.8.2 pytket 0.19.0 pytket-qiskit 0.22.0 pytz 2021.3 pyzmq 22.3.0 qiskit 0.34.1 qiskit-aer 0.10.2 qiskit-ibmq-provider 0.18.3 qiskit-ignis 0.7.0 qiskit-ionq 0.1.4 qiskit-nature 0.3.0 qiskit-optimization 0.3.0 qiskit-terra 0.19.1 requests 2.27.1 requests-ntlm 1.1.0 retworkx 0.11.0 rsa 4.8 scikit-learn 1.0.2 scipy 1.7.3 seaborn 0.11.2 Send2Trash 1.8.0 setuptools 58.0.4 six 1.16.0 sniffio 1.2.0 sortedcontainers 2.4.0 stevedore 3.5.0 symengine 0.8.1 sympy 1.9 terminado 0.9.4 testpath 0.5.0 threadpoolctl 3.0.0 tornado 6.1 tqdm 4.62.3 traitlets 5.1.1 tweedledum 1.1.1 types-Jinja2 2.11.9 types-MarkupSafe 1.1.10 types-pkg-resources 0.1.3 typing-extensions 3.10.0.2 urllib3 1.26.8 wcwidth 0.2.5 webencodings 0.5.1 websocket-client 1.2.3 wheel 0.37.1 widgetsnbextension 3.5.2 zipp 3.7.0
Here is my code that created the error in the last line when trying to evaluate the expectation value of the folded circuit using qiskit.
import pylab import qiskit import numpy as np from qiskit import Aer, BasicAer from qiskit.compiler import transpile from qiskit.opflow import X, Z, I, Y, StateFn, CircuitStateFn, SummedOp, PauliExpectation, CircuitSampler from qiskit.quantum_info.operators import Operator, Pauli from qiskit.utils import QuantumInstance, algorithm_globals from qiskit.algorithms import VQE, NumPyMinimumEigensolver from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.algorithms.optimizers import COBYLA, L_BFGS_B, SLSQP from qiskit.circuit.library import TwoLocal from mitiq.interface.mitiq_qiskit.qiskit_utils import initialized_depolarizing_noise from qiskit.circuit import Parameter from mitiq.zne import mitigate_executor from mitiq.zne.inference import RichardsonFactory from mitiq import zne from mitiq.zne.scaling.folding import fold_gates_from_left, fold_gates_from_right from scipy.optimize import minimize, minimize_scalar
H2_op = (-1.052373245772859 I ^ I) + (0.39793742484318045 I ^ Z) + (-0.39793742484318045 Z ^ I) + \ (-0.01128010425623538 Z ^ Z) + (0.18093119978423156 * X ^ X)
def trial_circuit(parameter): circuit=QuantumCircuit(2) circuit.ry(parameter[0],0) circuit.ry(parameter[1],1) circuit.cz(0,1) circuit.ry(parameter[2],0) circuit.ry(parameter[3],1) return circuit
scale_factors = [1., 1.5, 2., 2.5, 3.] folded_circuits = [ zne.scaling.fold_gates_at_random(trial_circuit([0,0,0,0]), scale) for scale in scale_factors ]
def qiskit_executor_no_noise(circuit: qiskit.QuantumCircuit, shots: int = 8192) -> float: quantum_instance = QuantumInstance(backend=Aer.get_backend('qasm_simulator'), shots=20000) psi = CircuitStateFn(circuit) value_list = [] for i in range(0,len(H2_op),1): measurable_expression = StateFn(H2_op[i], is_measurement=True).compose(psi) expectation = PauliExpectation().convert(measurable_expression) sampler = CircuitSampler(quantum_instance).convert(expectation) value = sampler.eval().real value_list.append(value) return value_list
qiskit_executor_no_noise(trial_circuit([0,0,0,0]))
qiskit_executor_no_noise(folded_circuits[0])
@anhdpham I see! I reproduced the error with qiskit>=0.34
. Official mitiq
support (currently) is qiskit~=0.32.1
, and your code block passes when using that version (and latest mitiq==0.13
). We strive to support the latest frontend versions, and I'll make sure that version support is better documented, but in the meantime you may want to try an older release.
@Aaron-Robertson Thanks. Will retest the program using a qiskit=0.32.1
Closing with documentation issue noted in #1201
I think there is a problem with passing a folded circuit generated by mitiq to the expectation value routine used to calculate in mitiq
def ansatz(parameter): circuit = QuantumCircuit(2) circuit.rx(parameter[0],0) circuit.cnot(0,1) circuit.rx(parameter[0],1) circuit.cnot(0,1) circuit.rx(parameter[0],0) return circuit
angles = [] for angle in np.linspace(0, 2 * np.pi, 50): angles.append(angle)
circuits = [] for angle in angles: circuits.append(ansatz([angle]))
def qiskit_executor(circuit: qiskit.QuantumCircuit, shots: int = 8192) -> float: quantum_instance = QuantumInstance(backend=Aer.get_backend('qasm_simulator'),noise_model = noise_model, basis_gates = noise_model.basis_gates, shots=10000) psi = CircuitStateFn(circuit) measurable_expression = StateFn(Hamiltonian, is_measurement=True).compose(psi) expectation = PauliExpectation().convert(measurable_expression) sampler = CircuitSampler(quantum_instance).convert(expectation) value = sampler.eval().real return value
scale_factors = [1., 1.5, 2., 2.5, 3.] folded_circuits = [ zne.scaling.fold_gates_at_random(circuits[0], scale) for scale in scale_factors ]
qiskit_executor(folded_circuits[0])
Error:
ValueError Traceback (most recent call last) /tmp/ipykernel_300/1422248828.py in
----> 1 qiskit_executor(folded_circuits[0])
/tmp/ipykernel_300/1414635650.py in qiskit_executor(circuit, shots) 4 # ansatz_value = ansatz.bind_parameters({theta: val for val in theta_val}) 5 psi = CircuitStateFn(circuit) ----> 6 measurable_expression = StateFn(Hamiltonian, is_measurement=True).compose(psi) 7 expectation = PauliExpectation().convert(measurable_expression) 8 sampler = CircuitSampler(quantum_instance).convert(expectation)
~/anaconda3/envs/IBM_qiskit/lib/python3.9/site-packages/qiskit/opflow/state_fns/state_fn.py in compose(self, other, permutation, front) 308 ) 309 --> 310 new_self, other = self._expand_shorter_operator_and_permute(other, permutation) 311 312 if front:
~/anaconda3/envs/IBM_qiskit/lib/python3.9/site-packages/qiskit/opflow/state_fns/state_fn.py in _expand_shorter_operator_and_permute(self, other, permutation) 263 return self, StateFn("0" * self.num_qubits) 264 --> 265 return super()._expand_shorter_operator_and_permute(other, permutation) 266 267 def to_matrix(self, massive: bool = False) -> np.ndarray:
~/anaconda3/envs/IBM_qiskit/lib/python3.9/site-packages/qiskit/opflow/operator_base.py in _expand_shorter_operator_and_permute(self, other, permutation) 436 other = Zero.class("0" * self.num_qubits) 437 elif other.num_qubits < self.num_qubits: --> 438 other = other._expand_dim(self.num_qubits - other.num_qubits) 439 elif other.num_qubits > self.num_qubits: 440 new_self = self._expand_dim(other.num_qubits - self.num_qubits)
~/anaconda3/envs/IBM_qiskit/lib/python3.9/site-packages/qiskit/opflow/state_fns/circuit_state_fn.py in _expand_dim(self, num_qubits) 383 # this is equivalent to self.tensor(identity_operator), but optimized for better performance 384 # just like in tensor method, qiskit endianness is reversed here --> 385 return self.permute(list(range(num_qubits, num_qubits + self.num_qubits))) 386 387 def permute(self, permutation: List[int]) -> "CircuitStateFn":
~/anaconda3/envs/IBM_qiskit/lib/python3.9/site-packages/qiskit/opflow/state_fns/circuit_state_fn.py in permute(self, permutation) 396 A new CircuitStateFn containing the permuted circuit. 397 """ --> 398 new_qc = QuantumCircuit(max(permutation) + 1).compose(self.primitive, qubits=permutation) 399 return CircuitStateFn(new_qc, coeff=self.coeff, is_measurement=self.is_measurement)
ValueError: max() arg is an empty sequence
It works fine if i pass a circuit created by QuantumCircuit in qiskit.