Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Incorrectly generated matrix out of a list of Pauli strings after converting to opflow #1381

Closed
Brogis1 opened this issue Oct 23, 2020 · 1 comment
Assignees
Labels
type: bug Something isn't working

Comments

@Brogis1
Copy link
Contributor

Brogis1 commented Oct 23, 2020

Information

  • Qiskit Aqua version:
    'qiskit-terra': '0.17.0',
    'qiskit-aer': '0.8.0',
    'qiskit-ignis': '0.6.0',
    'qiskit-ibmq-provider': '0.12.0',
    'qiskit-aqua': '0.9.0'

  • Python version:
    Python 3.6.11 | packaged by conda-forge | (default, Aug 5 2020, 20:19:23)

  • Operating system:
    macOS Cataline Version 10.15.5 (19F101)

What is the current behavior?

Problem spotted when executed the NumpyEigensolver for an operator.
The matrix and the spectrum of an operator (specific case) is changed when using to_opflow() (automatically called for legacy operators in the NumpyEigensolver).

Steps to reproduce the problem

Given a list of Paulis strings with coefficients in a dictionary (particular case), giving it to WeightedPauliOperator to construct the matrix with qubit_op= WeightedPauliOperator.from_dict(pauli_list) then matrix = to_matrix_operator(qubit_op).dense_matrix upon diagonalization produces correct expected eigenvalues.
Then, when switching to_opflow(), with qubit_op_opflow = qubit_op.to_opflow() then
qubit_op_opflow_matrix = qubit_op_opflow.to_matrix() the matrix and eigenvalues are modified.

from qiskit.aqua.operators import WeightedPauliOperator
import numpy as np
from qiskit.aqua.operators.legacy.op_converter import to_matrix_operator

# Paulis of the operator
h_real_paulis = {'IIII': (4+0j),
 'IIIZ': (3.0025020840279018+0j),
 'IIZI': (0.9974979159720981+0j),
 'IZII': (3.0025020840279018+0j),
 'IZIZ': (1+0j),
 'IZZI': (1+0j),
 'IZZZ': (-0.002502084027901752+0j),
 'XXXX': (1+0j),
 'XXXY': 0.050083375009922104j,
 'XXYX': -0.050083375009922104j,
 'XXYY': (1+0j),
 'XYXX': 0.050083375009922076j,
 'XYYY': 0.050083375009922076j,
 'YXXX': -0.050083375009922076j,
 'YXYY': -0.050083375009922076j,
 'YYXX': (1+0j),
 'YYXY': 0.050083375009922104j,
 'YYYX': -0.050083375009922104j,
 'YYYY': (1+0j),
 'ZIII': (0.9974979159720981+0j),
 'ZIIZ': (1+0j),
 'ZIZI': (0.9999999999999999+0j),
 'ZIZZ': (0.002502084027901752+0j),
 'ZZIZ': (-0.002502084027901752+0j),
 'ZZZI': (0.002502084027901752+0j)}

h_real_paulis_new = {}
h_real_paulis_new['paulis'] = []
for entry, coef in h_real_paulis.items():
    h_real_paulis_new['paulis'].append({"coeff": {"imag": np.imag(coef), "real": np.real(coef)}, "label": entry})

# matrix using Legacy matrix
qubit_op = WeightedPauliOperator.from_dict(h_real_paulis_new)
matrix = to_matrix_operator(qubit_op).dense_matrix
eigs2, eigv2 = np.linalg.eig(matrix)
print(np.sort(eigs2))

# This is also the correct expected spectrum
"""
[-2.00000000e+00 -2.00000000e+00 -1.65685425e+00 -1.11022302e-16
  0.00000000e+00  1.11022302e-16  1.11022302e-16  2.00000000e+00
  2.00000000e+00  6.00000000e+00  6.00000000e+00  8.00000000e+00
  9.65685425e+00  1.00000000e+01  1.00000000e+01  1.60000000e+01]
"""

# matrix after switching to_opflow()
qubit_op_opflow = qubit_op.to_opflow()
qubit_op_opflow_matrix = qubit_op_opflow.to_matrix()
eigs2_opflow, eigv2_opflow = np.linalg.eig(qubit_op_opflow_matrix)
print(np.sort(eigs2_opflow))

# Note the 3rd eigenvalue has changed
"""
[-2.00000000e+00 -2.00000000e+00 -1.68516210e+00 -1.11022302e-16
  0.00000000e+00  1.11022302e-16  1.11022302e-16  2.00000000e+00
  2.00000000e+00  6.00000000e+00  6.00000000e+00  8.00000000e+00
  9.68516210e+00  1.00000000e+01  1.00000000e+01  1.60000000e+01]
"""

What is the expected behavior?

The spectrum of an operator (given as Pauli strings and their coefficients) should not change upon switching to_opflow().

Suggested solutions

Inspect the to_opflow() method and Pauli label to Pauli object converter.

@woodsp-ibm woodsp-ibm added the type: bug Something isn't working label Oct 23, 2020
@ikkoham
Copy link
Contributor

ikkoham commented Oct 26, 2020

Thanks for the issue.
I found that to_opflow() mistakenly converts a imaginary number to a real number.

minimal code

qubit_op = WeightedPauliOperator.from_dict({"paulis":[{"coeff": {"imag": 1, "real": 0}, "label": "X"}]})
print(qubit_op.to_opflow().to_matrix())

This returns a Pauli X.

I will fix this issue.

@ikkoham ikkoham self-assigned this Oct 26, 2020
ikkoham added a commit to ikkoham/qiskit-aqua that referenced this issue Oct 26, 2020
ikkoham added a commit to ikkoham/qiskit-aqua that referenced this issue Oct 26, 2020
@ikkoham ikkoham mentioned this issue Oct 26, 2020
1 task
manoelmarques pushed a commit to manoelmarques/qiskit-aqua that referenced this issue Nov 9, 2020
* fix qiskit-community#1311

* fix qiskit-community#1317

* add a test of reps for trotterization

* fix tests for qiskit-community#1311

* fix typing

* fix qiskit-community#1321

* add release note

* fix qiskit-community#1381

* add a test for to_opflow

* Update qiskit/aqua/operators/converters/circuit_sampler.py

Co-authored-by: John Lapeyre <[email protected]>

* remove None from constructor

* simplify logic

* Revert "remove None from constructor"

This reverts commit c884ebb.

* add releasenote

* simplify logic (not iscomplex to isreal)

* remove Optional

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

Co-authored-by: John Lapeyre <[email protected]>
Co-authored-by: Panagiotis Barkoutsos <[email protected]>
Co-authored-by: Steve Wood <[email protected]>
mtreinish pushed a commit to mtreinish/qiskit-core that referenced this issue Nov 20, 2020
* fix qiskit-community/qiskit-aqua#1311

* fix qiskit-community/qiskit-aqua#1317

* add a test of reps for trotterization

* fix tests for qiskit-community/qiskit-aqua#1311

* fix typing

* fix qiskit-community/qiskit-aqua#1321

* add release note

* fix qiskit-community/qiskit-aqua#1381

* add a test for to_opflow

* Update qiskit/aqua/operators/converters/circuit_sampler.py

Co-authored-by: John Lapeyre <[email protected]>

* remove None from constructor

* simplify logic

* Revert "remove None from constructor"

This reverts commit c884ebba123adee22f252e11f90964a6defaec38.

* add releasenote

* simplify logic (not iscomplex to isreal)

* remove Optional

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

Co-authored-by: John Lapeyre <[email protected]>
Co-authored-by: Panagiotis Barkoutsos <[email protected]>
Co-authored-by: Steve Wood <[email protected]>
manoelmarques pushed a commit to manoelmarques/qiskit-terra that referenced this issue Dec 2, 2020
* fix qiskit-community/qiskit-aqua#1311

* fix qiskit-community/qiskit-aqua#1317

* add a test of reps for trotterization

* fix tests for qiskit-community/qiskit-aqua#1311

* fix typing

* fix qiskit-community/qiskit-aqua#1321

* add release note

* fix qiskit-community/qiskit-aqua#1381

* add a test for to_opflow

* Update qiskit/aqua/operators/converters/circuit_sampler.py

Co-authored-by: John Lapeyre <[email protected]>

* remove None from constructor

* simplify logic

* Revert "remove None from constructor"

This reverts commit c884ebba123adee22f252e11f90964a6defaec38.

* add releasenote

* simplify logic (not iscomplex to isreal)

* remove Optional

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

Co-authored-by: John Lapeyre <[email protected]>
Co-authored-by: Panagiotis Barkoutsos <[email protected]>
Co-authored-by: Steve Wood <[email protected]>
manoelmarques pushed a commit to manoelmarques/qiskit-terra that referenced this issue Dec 7, 2020
* fix qiskit-community/qiskit-aqua#1311

* fix qiskit-community/qiskit-aqua#1317

* add a test of reps for trotterization

* fix tests for qiskit-community/qiskit-aqua#1311

* fix typing

* fix qiskit-community/qiskit-aqua#1321

* add release note

* fix qiskit-community/qiskit-aqua#1381

* add a test for to_opflow

* Update qiskit/aqua/operators/converters/circuit_sampler.py

Co-authored-by: John Lapeyre <[email protected]>

* remove None from constructor

* simplify logic

* Revert "remove None from constructor"

This reverts commit c884ebba123adee22f252e11f90964a6defaec38.

* add releasenote

* simplify logic (not iscomplex to isreal)

* remove Optional

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

* Update qiskit/aqua/operators/legacy/weighted_pauli_operator.py

Co-authored-by: John Lapeyre <[email protected]>
Co-authored-by: Panagiotis Barkoutsos <[email protected]>
Co-authored-by: Steve Wood <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants