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.3k stars 2.38k forks source link

TwoQubitWeylDecomposition: failed to diagonalize M2 #4159

Open 1ucian0 opened 4 years ago

1ucian0 commented 4 years ago

This issue accumulates TwoQubitWeylDecomposition: failed to diagonalize M2 errors found by users .

To reproduce:

from qiskit.quantum_info.synthesis import two_qubit_cnot_decompose
import numpy as np
two_qubit_cnot_decompose.num_basis_gates(np.array(<INPUT>))
1ucian0 commented 4 years ago
QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2.
Please submit this output to https://github.com/Qiskit/qiskit-terra/issues/4159
Input
[[(0.9075320821407213+0.419442642245063j), (-0.01906154950314571-0.009219823865009769j), (4.2801374171139336e-05-2.0702468651736694e-05j), (0.0020377997189412506-0.0009418290717202716j)], [(-4.2801374171139336e-05+2.0702468651736694e-05j), (-0.0020377997189412506+0.0009418290717202716j), (0.9075320821407213+0.419442642245063j), (-0.01906154950314571-0.009219823865009769j)], [(0.002037799718941249+0.0009418290717202753j), (-4.280137417122403e-05-2.070246865156162e-05j), (-0.019061549503107993+0.009219823865087738j), (-0.9075320821407221+0.4194426422450614j)], [(-0.019061549503107993+0.009219823865087738j), (-0.9075320821407221+0.4194426422450614j), (-0.002037799718941249-0.0009418290717202753j), (4.280137417122403e-05+2.070246865156162e-05j)]]'

Solved by https://github.com/Qiskit/qiskit-terra/pull/4156

1ucian0 commented 3 years ago

Reopen this issue if you new diagonalize M2 issues.

eddygta17 commented 2 years ago
from qiskit import *
from qiskit.extensions import UnitaryGate
import numpy as np
from qiskit.tools.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
from qiskit import Aer, execute
import qiskit
from qiskit import IBMQ

data_encode = np.array([[0.33125418, -0.5410485 , -0.55209031 ,-0.5410485 ],
 [ 0.5410485  , 0.780107 ,  -0.22438062 ,-0.219893  ],
 [ 0.55209031, -0.22438062,  0.77104019, -0.22438062],
 [ 0.5410485 , -0.219893 ,  -0.22438062  ,0.780107  ]])
qc = QuantumCircuit(3,1)
qc.reset(range(2))
qc.append(UnitaryGate(data_encode,label="Input"),[0,1])
#qc.barrier()
qc.cz(0,1)
qc.x(0)
qc.cz(0,1)
qc.x(0)
#qc.barrier()
qc.h(0)
qc.h(1)
#qc.barrier()
qc.x(0)
qc.x(1)
qc.ccx(0,1,2)
qc.measure(2,0)
qc.draw('mpl')

simulator = Aer.get_backend('qasm_simulator')
result = execute(qc, simulator).result()
counts = result.get_counts(qc)
plot_histogram(counts, title='State Counts')

def fire_ibmq(circuit,shots,Simulation = True,backend_name='ibm_oslo'):     
    count_set = []
    if not Simulation:
        provider = IBMQ.get_provider('ibm-q')
        backend = provider.get_backend(backend_name)
    else:
        backend = Aer.get_backend('qasm_simulator')
    job_ibm_q = execute(circuit, backend, shots=shots)
    job_monitor(job_ibm_q)
    result_ibm_q = job_ibm_q.result()
    counts = result_ibm_q.get_counts()
    return counts

def analyze(counts):
    mycount = {}
    for i in range(2):
        mycount[i] = 0
    for k,v in counts.items():
        bits = len(k) 
        for i in range(bits):            
            if k[bits-1-i] == "1":
                if i in mycount.keys():
                    mycount[i] += v
                else:
                    mycount[i] = v
    return mycount,bits

simulator = Aer.get_backend('statevector_simulator')
result = execute(qc, simulator).result()
statevector = result.get_statevector(qc)
print(statevector)

IBMQ.load_account()
qc_shots=20000
counts = fire_ibmq(qc,qc_shots,Simulation=True)

(mycount,bits) = analyze(counts)
class_prob=[]
for b in range(bits):
    class_prob.append(float(mycount[b])/qc_shots)
print(class_prob)

qc_shots=20000
counts = fire_ibmq(qc,qc_shots,Simulation=False)
israelferrazaraujo commented 2 years ago

qiskit.exceptions.QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[(-0.3812064266367201+0.38120642663672005j), (-0.08953682318096808+0.08953682318096806j), (-0.5214184531408846+0.5214184531408846j), (-0.27347323579354943+0.2734732357935494j)], [(0.11105398348218393-0.11105398348218391j), (0.145430219977459-0.14543021997745897j), (0.23096365206101888-0.23096365206101882j), (-0.6427852354467597+0.6427852354467596j)], [(-0.544932087007239+0.5449320870072389j), (-0.16786656959437854+0.16786656959437854j), (0.41778724529336947-0.4177872452933694j), (0.01799033088883041-0.017990330888830407j)], [(-0.213067345160641+0.21306734516064096j), (0.6653224962721628-0.6653224962721627j), (-0.0152448403255109+0.015244840325510897j), (0.10823991063233353-0.10823991063233351j)]]'

Version Information

Qiskit Software Version
qiskit-terra 0.21.0
qiskit-aer 0.10.4
qiskit-ignis 0.7.1
qiskit-ibmq-provider 0.19.2
qiskit 0.37.0
qiskit-finance 0.3.1
qiskit-optimization 0.3.1
qiskit-machine-learning 0.3.1

Python version | 3.7.13 Python compiler | GCC 7.5.0 Python build | default, Mar 29 2022 02:18:16 OS | Linux CPUs | 2 Memory (Gb) | 15.516639709472656 Wed Jul 20 12:11:59 2022 -03

israelferrazaraujo commented 2 years ago

QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[(0.4402772595428174+0.16674564937013872j), (-0.5138795577094725-0.48318958124789j), (-0.3740257577372414+0.35464062885690584j), (0.02721088754228169+0.1200074014368489j)], [(-0.4552626070355557-0.11993387965705486j), (-0.6002049158068373-0.3705380281421869j), (0.24689932774287246-0.4524444331042837j), (0.015427498410238815-0.12208276329304561j)], [(-0.47620648895679785-0.2271105524214607j), (0.04916848897858904+0.006171582728012511j), (-0.436598161773811+0.20908563329146243j), (0.6762198079424273+0.16608600948182134j)], [(0.5195680847330866+0.0916560334746992j), (0.01874613734110321+0.04587168055122139j), (0.09016729069923601-0.47560973139840246j), (0.6568935158431253-0.23097337518213976j)]]'

Version Information

Qiskit Software Version
qiskit-terra 0.21.0
qiskit-aer 0.10.4
qiskit-ignis 0.7.1
qiskit-ibmq-provider 0.19.2
qiskit 0.37.0
qiskit-machine-learning 0.4.0

Python version | 3.9.2 Python compiler | GCC 10.2.1 20210110 Python build | default, Feb 28 2021 17:03:44 OS | Linux CPUs | 2 Memory (Gb) | 15.516639709472656 Sat Jul 23 19:59:09 2022 -03

neelmodi14 commented 2 years ago

QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[(0.6666666666573151-1.231488602740744e-18j), (0.33333333332865756+0.33333333332865756j), (0.5659164583920617-1.0453795029345096e-18j), (-0.08084520834886597-0.08084520834886597j)], [(0.33333333332865756-0.33333333332865756j), (-0.33333333332865756+6.15744301370372e-19j), (-0.08084520834886597+0.08084520834886597j), (0.8084520834886596-1.4933992900383874e-18j)], [(0.5659164583920617-1.0453795029345096e-18j), (-0.08084520834886597-0.08084520834886597j), (-0.6666666666573151+1.231488602740744e-18j), (-0.33333333332865756-0.33333333332865756j)], [(-0.08084520834886597+0.08084520834886597j), (0.8084520834886596-1.4933992900383874e-18j), (-0.33333333332865756+0.33333333332865756j), (0.33333333332865756-6.15744301370372e-19j)]]'

Code that produces this error (qiskit-terra version 0.21.1):

from qiskit import QuantumCircuit
from qiskit.quantum_info import Operator

op = Operator([
    [2./3, 1./3 + 1.j/3, 0.5659164584, -0.08084520835 - 0.08084520835j],
    [1./3 - 1.j/3, -1./3, -0.08084520835 + 0.08084520835j, 0.8084520835],
    [0.5659164584, -0.08084520835 - 0.08084520835j, -2./3, -1./3 - 1.j/3],
    [-0.08084520835 + 0.08084520835j, 0.8084520835, -1./3 + 1.j/3, 1./3]
])

circ1 = QuantumCircuit(2)
circ1.unitary(op, [0,1])
circ2 = QuantumCircuit(3)
circ2.append(circ1.control(1), [0,1,2])

Calling op.is_unitary() returns True so op is able to be added to circ1, but subsequently circ1.control(1) throws this error.

Using a more exact form of the matrix elements resolves the issue:

op = Operator([
    [2./3, 1./3 + 1.j/3, 7*np.sqrt(17)/51, (-1 - 1.j)*np.sqrt(17)/51],
    [1./3 - 1.j/3, -1./3, (-1 + 1.j)*np.sqrt(17)/51, 10*np.sqrt(17)/51],
    [7*np.sqrt(17)/51, (-1 - 1.j)*np.sqrt(17)/51, -2./3, -1./3 - 1.j/3],
    [(-1 + 1.j)*np.sqrt(17)/51, 10*np.sqrt(17)/51, -1./3 + 1.j/3, 1./3]
])
kharazity commented 2 years ago

Is there any workout for those who have numerical representations of the system? I have real-valued element of SU(4) that fails TwoQubitWeylDecomposition and I wonder if it's for similar reasons... QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[(-0.6269523815065876+0j), (-0.1993407004790224+0j), (-0.6329122615209094+0j), (-0.4081863209808854+0j)], [(-0.6269523715065877+0j), (-0.4274160410270951+0j), (0.6121486914710139+0j), (0.2225314005347504+0j)], [(-0.32700263078579833+0j), (0.43412304104321225+0j), (-0.3146873407562042+0j), (0.7781891418700145+0j)], [(0.3270026407857983+0j), (-0.7675389218444217+0j), (-0.35449671085186746+0j), (0.4222385110146533+0j)]]' Program:

import qiskit as qk
from qiskit.quantum_info.synthesis import two_qubit_decompose
from qiskit.quantum_info import Operator
U00 = np.array([[-0.62695238, -0.1993407 , -0.63291226, -0.40818632],
                [-0.62695237, -0.42741604,  0.61214869,  0.2225314 ],
                [-0.32700263,  0.43412304, -0.31468734,  0.77818914],
                [ 0.32700264, -0.76753892, -0.35449671,  0.42223851]],dtype=np.float64)
U00 = Operator(U00)
stuff = two_qubit_decompose.TwoQubitWeylDecomposition(U00, fidelity = 1e-2)

Thanks for the help!

levbishop commented 2 years ago

Is there any workout for those who have numerical representations of the system? I have real-valued element of SU(4) that fails TwoQubitWeylDecomposition and I wonder if it's for similar reasons...

Does applying closest_unitary(U00) from https://github.com/Qiskit/qiskit-terra/issues/7120#issuecomment-940768863 solve your problem?

kharazity commented 2 years ago

Ya, thanks for letting me know! Even though the system is small, it still kind of stinks to have to do an SVD before hand. Could something like this be implemented? https://journals.aps.org/pra/abstract/10.1103/PhysRevA.69.010301

levbishop commented 2 years ago

The TwoQubitBasisDecomposer is a generalization of that Vidal/Dawson CNOT decomposer (it works any supercontrolled basis h=(pi/4, b, 0), not only the CNOT-equivalent special case (pi/4, 0, 0) basis). There are other generalizations TwoQubitControlledUDecomposer for {(a, 0, 0) for all 0<=a<=pi/4} and XXDecomposer for some finite set of {(a_i, 0, 0)}.

All of these need to do the decomposition in eqs 4-5 of the Vidal/Dawson paper, which is what's failing here for non-unitary gates.

There's a philosophical question we need to answer about where to require/impose unitarity. The discussion in #7120 has stalled out for now without a resolution, so in the meantime you can apply closest_unitary manually.

garrison commented 3 months ago

@caleb-johnson encountered the following:

import numpy as np
from qiskit.synthesis.two_qubit.two_qubit_decompose import TwoQubitWeylDecomposition

mat = [
    [0.043602684126304955 + -0.4986216208233326j, -0.22461079447224863 + -0.09679517443671315j, 0.15592626697527698 + 0.13943283228059802j, -0.803224008021238 + 0.027067469117215155j],
    [-0.09679517443669944 + 0.22461079447226426j, 0.4986216208232763 + 0.043602684126298856j, 0.02706746911718458 + 0.8032240080213412j, -0.13943283228056091 + 0.15592626697531453j],
    [0.13943283228059844 + -0.15592626697527806j, 0.027067469117214762 + 0.8032240080212403j, 0.49862162082333095 + 0.0436026841263046j, 0.09679517443671384 + -0.22461079447224833j],
    [0.8032240080213434 + -0.027067469117184207j, 0.1559262669753156 + 0.13943283228056125j, -0.2246107944722639 + -0.09679517443670013j, -0.043602684126298495 + 0.4986216208232746j]
]
mat = np.asarray(mat)
TwoQubitWeylDecomposition(mat)

raises

  File "site-packages/qiskit/synthesis/two_qubit/two_qubit_decompose.py", line 192, in __init__
    self._inner_decomposition = two_qubit_decompose.TwoQubitWeylDecomposition(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
qiskit.exceptions.QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[Complex { re: 0.043602684126304955, im: -0.4986216208233326 }, Complex { re: -0.22461079447224863, im: -0.09679517443671315 }, Complex { re: 0.15592626697527698, im: 0.13943283228059802 }, Complex { re: -0.803224008021238, im: 0.027067469117215155 }],\n [Complex { re: -0.09679517443669944, im: 0.22461079447226426 }, Complex { re: 0.4986216208232763, im: 0.043602684126298856 }, Complex { re: 0.02706746911718458, im: 0.8032240080213412 }, Complex { re: -0.13943283228056091, im: 0.15592626697531453 }],\n [Complex { re: 0.13943283228059844, im: -0.15592626697527806 }, Complex { re: 0.027067469117214762, im: 0.8032240080212403 }, Complex { re: 0.49862162082333095, im: 0.0436026841263046 }, Complex { re: 0.09679517443671384, im: -0.22461079447224833 }],\n [Complex { re: 0.8032240080213434, im: -0.027067469117184207 }, Complex { re: 0.1559262669753156, im: 0.13943283228056125 }, Complex { re: -0.2246107944722639, im: -0.09679517443670013 }, Complex { re: -0.043602684126298495, im: 0.4986216208232746 }]], shape=[4, 4], strides=[4, 1], layout=Cc (0x5), const ndim=2'
jakelishman commented 3 months ago

Thanks Jim and Caleb. Now that the Weyl decomposition code is fully in Rust, I guess it's probably time for me to dust off an ancient Python-space branch I have that does the diagonalisation and eigensystem orthogonalisation of the system more manually than the super funky "mix the real and imaginary parts together with random perturbations and call eigh in a loop" thing we've got going on right now. Previously we avoided it because the Python-space overhead was too large, and we didn't have any live reported failures (iirc), but it hopefully it should be faster from Rust space now.

hJaffaliColibritd commented 2 months ago

Another one!

self = <qiskit.transpiler.passes.synthesis.unitary_synthesis.DefaultUnitarySynthesis object at 0x00000267D801FFA0>
unitary = array([[-0.01401479+0.j, -0.36022856+0.j,  0.78035743+0.j,
         0.51096111+0.j],
       [ 0.96565434+0.j, -0.24492...81+0.j,
         0.83339133+0.j],
       [ 0.24385713+0.j,  0.79761907+0.j,  0.51011359+0.j,
        -0.21005151+0.j]])
decomposer2q = <qiskit.synthesis.two_qubit.two_qubit_decompose.TwoQubitBasisDecomposer object at 0x00000267D801F340>, preferred_direction = None, approximation_degree = 1.0

    def _synth_su4_no_dag(self, unitary, decomposer2q, preferred_direction, approximation_degree):
        approximate = not approximation_degree == 1.0
>       synth_circ = decomposer2q._inner_decomposer(unitary, approximate=approximate)
E       qiskit.exceptions.QiskitError: 'TwoQubitWeylDecomposition: failed to diagonalize M2. Please report this at https://github.com/Qiskit/qiskit-terra/issues/4159. Input: [[Complex { re: -0.014014791482630202, im: 0.0 }, Complex { r
e: -0.36022855876544824, im: 0.0 }, Complex { re: 0.7803574289848131, im: 0.0 }, Complex { re: 0.5109611080762898, im: 0.0 }],\n [Complex { re: 0.9656543362286063, im: 0.0 }, Complex { re: -0.24492681830240662, im: 0.0 }, Complex { re:
 -0.08524412725677805, im: 0.0 }, Complex { re: -0.01599985278901905, im: 0.0 }],\n [Complex { re: 0.08859451444376841, im: 0.0 }, Complex { re: 0.4171930654359363, im: 0.0 }, Complex { re: -0.351510805117566, im: 0.0 }, Complex { re:
0.8333913318251783, im: 0.0 }],\n [Complex { re: 0.24385713126038627, im: 0.0 }, Complex { re: 0.7976190727850992, im: 0.0 }, Complex { re: 0.5101135909484675, im: 0.0 }, Complex { re: -0.21005151405817812, im: 0.0 }]], shape=[4, 4], s
trides=[4, 1], layout=Cc (0x5), const ndim=2'
ACE07-Sev commented 1 month ago

Any fixes for this? To clarify, I am trying to translate the current implementation to python-only for my package and given the rust portings I am using the latest python-only implementation, which is 0.46.

If anyone here has a cleaner, more minimalistic, python-only implementation I'd deeply appreciate seeing it.

jakelishman commented 1 month ago

This is my old branch, which is pure Python. It's a single commit that applies somewhere back to around Terra 0.22 I think (you can find exactly where by looking at its parent). It'll probably apply mostly cleanly to 0.46 as well, but I haven't tried it.

https://github.com/jakelishman/qiskit-terra/tree/storage/deterministic-weyl-decomposition

I haven't had chance to look more at changing the Rust-space algorithm.

ACE07-Sev commented 1 month ago

@jakelishman Greetings dear Jake,

Hope you are well. Apologies for the bother. Quick question regarding the TwoQubitBasisDecomposer. I have noticed that for CX basis gate (which I imagine is how general unitary decomposition is usually done) the best_nbasis is always equal to 3. May I ask if it's safe to set best_nbasis explicitly to 3 if I plan to exclusively use CX gate for decomposition? As in TwoQubitBasisDecomposer(CXGate()).