-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement iterating/collecting PauliSumOp coefficients #5547
Comments
Hello, I'm pretty new to quantum, but I wanted to start contributing. If this is the patch you were looking for, I can create a pull request.
Here's how it is working now:
Paolo |
Thanks for jumping in. I don't think that patch gives the correct result in all cases. There are two "layers" of coefficients: A list of the full coefficient might be generated like this: |
Thank you for the additional info. Sorry I did not get it in the first place. So how about this?
that would return something like
|
Thanks, this looks good. Before making a PR, it would be a good idea to wait a bit to see if someone comments. There might be a reason to return a list rather than an array. |
All right. Thanks a lot. I'll just leave this here for others to jump in and provide review/direction. diff --git a/qiskit/opflow/primitive_ops/pauli_sum_op.py b/qiskit/opflow/primitive_ops/pauli_sum_op.py
index 0b5c0526..89ec23ec 100644
--- a/qiskit/opflow/primitive_ops/pauli_sum_op.py
+++ b/qiskit/opflow/primitive_ops/pauli_sum_op.py
@@ -59,6 +59,16 @@ class PauliSumOp(PrimitiveOp):
def num_qubits(self) -> int:
return self.primitive.num_qubits # type: ignore
+ # issue 5547 start
+ @property
+ def coeffs(self):
+ return self.coeff * self.primitive.coeffs
+
+ @property
+ def coeffslist(self):
+ return (self.coeff * self.primitive.coeffs).tolist()
+ # issue 5547 end
+
def add(self, other: OperatorBase) -> OperatorBase:
if not self.num_qubits == other.num_qubits:
raise ValueError( from qiskit.quantum_info import SparsePauliOp
from qiskit.opflow.primitive_ops import PauliSumOp
from qiskit.quantum_info.operators import PauliTable
a_table = PauliTable.from_labels(['X','I','Y'])
pauli_sum = PauliSumOp(SparsePauliOp(a_table),3)
print(pauli_sum.coeffs)
print(type(pauli_sum.coeffs))
print(pauli_sum.coeffslist)
print(type(pauli_sum.coeffslist))
|
Thanks. Nice. I provide some discussion points.
|
|
Hi thanks for the comments.
return list(self.coeff * self.primitive.coeffs) instead of calling the
I don't have any experience with this matter, so forgive me, but I'd keep it simple and go with the basic implementation of returning the coeffs with a numpy array, since that is the type that is returned by the primitive object, and leave any typecasting/conversion to the caller. |
So, here's what I have so far: diff --git a/qiskit/opflow/primitive_ops/pauli_sum_op.py b/qiskit/opflow/primitive_ops/pauli_sum_op.py
index 0b5c0526..6bf43fd5 100644
--- a/qiskit/opflow/primitive_ops/pauli_sum_op.py
+++ b/qiskit/opflow/primitive_ops/pauli_sum_op.py
@@ -20,6 +20,10 @@ from scipy.sparse import spmatrix
from qiskit.circuit import Instruction, ParameterExpression
from qiskit.quantum_info import Pauli, SparsePauliOp
+# issue 5547 start
+from qiskit.quantum_info.operators.symplectic.pauli_table import PauliTable
+from qiskit.quantum_info.operators.custom_iterator import CustomIterator
+# issue 5547 end
from ..exceptions import OpflowError
from ..list_ops.summed_op import SummedOp
from ..list_ops.tensored_op import TensoredOp
@@ -59,6 +63,47 @@ class PauliSumOp(PrimitiveOp):
def num_qubits(self) -> int:
return self.primitive.num_qubits # type: ignore
+ # issue 5547 start
+ @property
+ def coeffs(self):
+ return self.coeff * self.primitive.coeffs
+
+ @property
+ def coeffslist(self):
+ # return (self.coeff * self.primitive.coeffs).tolist()
+ return list(self.coeff * self.primitive.coeffs)
+
+ def matrix_iter(self, sparse=False):
+ """Return a matrix representation iterator.
+
+ This is a lazy iterator that converts each term in the PauliSumOp
+ into a matrix as it is used. To convert to a single matrix use the
+ :meth:`to_matrix` method.
+
+ Args:
+ sparse (bool): optionally return sparse CSR matrices if True,
+ otherwise return Numpy array matrices
+ (Default: False)
+
+ Returns:
+ MatrixIterator: matrix iterator object for the PauliTable.
+ """
+ class MatrixIterator(CustomIterator):
+ """Matrix representation iteration and item access."""
+ def __repr__(self):
+ return "<PauliSumOp_matrix_iterator at {}>".format(hex(id(self)))
+
+
+ def __getitem__(self, key):
+ sumopcoeff = self.obj.coeff * self.obj.primitive.coeffs[key]
+ mat = PauliTable._to_matrix(self.obj.primitive.table.array[key],
+ sparse=sparse)
+ return sumopcoeff * mat
+
+
+ return MatrixIterator(self)
+ # issue 5547 end
+
def add(self, other: OperatorBase) -> OperatorBase:
if not self.num_qubits == other.num_qubits:
raise ValueError( from qiskit.quantum_info import SparsePauliOp
from qiskit.opflow.primitive_ops import PauliSumOp
from qiskit.quantum_info.operators import PauliTable
a_table = PauliTable.from_labels(['X','I','Y'])
pauli_sum = PauliSumOp(SparsePauliOp(a_table),3)
print(pauli_sum.coeffs)
print(type(pauli_sum.coeffs))
print(pauli_sum.coeffslist)
print(type(pauli_sum.coeffslist[0]))
the_iterator = pauli_sum.matrix_iter()
print(the_iterator)
while True:
try:
print(next(the_iterator))
except StopIteration:
break
|
* Implement iterating/collecting PauliSumOp coefficients #5547 * Fixing Style and lint pipeline error on pull request * Using Pauli(keys).to_matrix() for testing iterator * removing unused import Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com> Co-authored-by: Julien Gacon <gaconju@gmail.com>
It would be useful to be able to iterate over, or return a list of coefficients in PauliSumOp. At present, one has to dig into the details to construct the coefficients for each term. In particular, it requires multiplying two numbers for each coeffcient. There are use cases, for instance when bounding the eigenvalues of the operators.
For example, this gives a bound on the eigenvalues:
Abstracting access would be cleaner and resistant to implementation changes. Like this, if we want to return an numpy array
or this, if we return a list
This should be quite easy to implement.
https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/opflow/primitive_ops/pauli_sum_op.py
The text was updated successfully, but these errors were encountered: