Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.2k stars 2.36k forks source link

`TaperedPauliSumOp` is incompatible with `VQE` #6100

Closed mrossinek closed 3 years ago

mrossinek commented 3 years ago

Information

What is the current behavior?

Using a tapered PauliSumOp as the input to a VQE results in the following runtime error:

Traceback (most recent call last):
  File "terra-bug-minimal.py", line 31, in <module>
    result = vqe.compute_minimum_eigenvalue(tapered_qubit_op)
  File "/home/oss/Files/Qiskit/src/qiskit-terra/qiskit/algorithms/minimum_eigen_solvers/vqe.py", line 412, in compute_minimum_eigenvalue
    self._expect_op = self.construct_expectation(self._var_form_params, operator)
  File "/home/oss/Files/Qiskit/src/qiskit-terra/qiskit/algorithms/minimum_eigen_solvers/vqe.py", line 300, in construct_expectation
    observable_meas = self.expectation.convert(StateFn(operator, is_measurement=True))
  File "/home/oss/Files/Qiskit/src/qiskit-terra/qiskit/opflow/expectations/matrix_expectation.py", line 38, in convert
    return operator.to_matrix_op()
  File "/home/oss/Files/Qiskit/src/qiskit-terra/qiskit/opflow/state_fns/operator_state_fn.py", line 119, in to_matrix_op
    return OperatorStateFn(self.primitive.to_matrix_op(massive=massive) * self.coeff,
  File "/home/oss/Files/Qiskit/src/qiskit-terra/qiskit/opflow/primitive_ops/primitive_op.py", line 244, in to_matrix_op
    prim_mat = self.__class__(self.primitive).to_matrix(massive=massive)
TypeError: __init__() missing 1 required positional argument: 'z2_symmetries'

Steps to reproduce the problem

Below is a minimal code snippet to reproduce the issue:

from qiskit import BasicAer
from qiskit.algorithms import VQE
from qiskit.circuit.library import TwoLocal
from qiskit.opflow import PauliSumOp, TwoQubitReduction

qubit_op = PauliSumOp.from_list([
    ("IIII", -0.8105479805373266),
    ("IIIZ", 0.17218393261915552),
    ("IIZZ", -0.22575349222402472),
    ("IZZI", 0.1721839326191556),
    ("ZZII", -0.22575349222402466),
    ("IIZI", 0.1209126326177663),
    ("IZZZ", 0.16892753870087912),
    ("IXZX", -0.045232799946057854),
    ("ZXIX", 0.045232799946057854),
    ("IXIX", 0.045232799946057854),
    ("ZXZX", -0.045232799946057854),
    ("ZZIZ", 0.16614543256382414),
    ("IZIZ", 0.16614543256382414),
    ("ZZZZ", 0.17464343068300453),
    ("ZIZI", 0.1209126326177663),
])

tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op)

backend = BasicAer.get_backend('statevector_simulator')
ryrz = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz')

vqe = VQE(ryrz, quantum_instance=backend)

result = vqe.compute_minimum_eigenvalue(tapered_qubit_op)

What is the expected behavior?

I would expect that the VQE is able to compute the minimum eigenvalue just like for any other opflow operator type.

Suggested solutions

A simple solution would be to make the z2_symmetries argument of TaperedPauliSumOp.__init__ optional. However, this may lead to other unwanted side-effects. Another possible solution would be to make the TaperedPauliSumOp look more like a PauliSumOp (at least in this context). But I am unsure how to achieve this given the __init__ call which is raising the problem is obtained via self.__class__. And I don't think we should hack the behavior of this internal object.

mrossinek commented 3 years ago

@ikkoham I am tagging you because (if I recall correctly) you mainly worked on the two-qubit-reduction and tapering code.

ikkoham commented 3 years ago

Thank you for finding the bug. I have checked only qasm_simulator.