(VQLS algorithm)The construction method of matrix A is different in Qiskit and Pennylane tutorials about VQLS

Qiskit:

# A = 0.55I + 0.225Z_2 + 0.225Z_3
coefficient_set = [0.55, 0.225, 0.225]

a1 = coefficient_set[2]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0,1,0,0,0,0,0], [0,0,0,1,0,0,0,0], [0,0,0,0,-1,0,0,0], [0,0,0,0,0,-1,0,0], [0,0,0,0,0,0,-1,0], [0,0,0,0,0,0,0,-1]])
a0 = coefficient_set[1]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0,-1,0,0,0,0,0], [0,0,0,-1,0,0,0,0], [0,0,0,0,1,0,0,0], [0,0,0,0,0,1,0,0], [0,0,0,0,0,0,-1,0], [0,0,0,0,0,0,0,-1]])
a2 = coefficient_set[0]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0,1,0,0,0,0,0], [0,0,0,1,0,0,0,0], [0,0,0,0,1,0,0,0], [0,0,0,0,0,1,0,0], [0,0,0,0,0,0,1,0], [0,0,0,0,0,0,0,1]])

a3 = np.add(np.add(a2, a0), a1)
A = a3 = 
array([[1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.55, 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.55, 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.55, 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.55, 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.1 , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.1 ]])

PennyLane:

Id = np.identity(2)

Z = np.array([[1, 0], [0, -1]])

X = np.array([[0, 1], [1, 0]])

A_0 = np.identity(8)

A_1 = np.kron(np.kron(Id, Z), Id)

A_2 = np.kron(np.kron(Id, Id), Z)

A_num = coefficient_set[0] * A_0 + coefficient_set[1] * A_1 + coefficient_set[2] * A_2
A_num = 
array([[1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.55, 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.55, 0.  , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.1 , 0.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 1.  , 0.  , 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.55, 0.  , 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.55, 0.  ],
       [0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.1 ]])

I simulated the circuit, and the result shows that Qiskit seems to be correct

from qiskit import QuantumCircuit, QuantumRegister,ClassicalRegister,execute, Aer


#%%
backend = Aer.get_backend('unitary_simulator')

q = QuantumRegister(3, 'q')
c = ClassicalRegister(3, 'c')

circuit = QuantumCircuit(q, c)

#circuit.h(q[0])
circuit.z(q[2])

print(circuit)

job = execute(circuit, backend, shots=8192)
result = job.result()

print(np.real(result.get_unitary(circuit,3)))

A_2= 
      [[ 1.  0.  0.  0.  0.  0.  0.  0.]
       [ 0.  1.  0.  0.  0.  0.  0.  0.]
       [-0. -0. -1. -0. -0. -0. -0. -0.]
       [-0. -0. -0. -1. -0. -0. -0. -0.]
       [ 0.  0.  0.  0.  1.  0.  0.  0.]
       [ 0.  0.  0.  0.  0.  1.  0.  0.]
       [-0. -0. -0. -0. -0. -0. -1. -0.]
       [-0. -0. -0. -0. -0. -0. -0. -1.]]

but in pennylane:

A_2 = 
        array([[ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
               [ 0., -1.,  0., -0.,  0., -0.,  0., -0.],
               [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
               [ 0., -0.,  0., -1.,  0., -0.,  0., -0.],
               [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
               [ 0., -0.,  0., -0.,  0., -1.,  0., -0.],
               [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
               [ 0., -0.,  0., -0.,  0., -0.,  0., -1.]])

But Pennylane’s result is correct, which makes me confused and I don’t know the reason.

Hi @SHAN, welcome to the Forum!

I’m not sure why Qiskit is giving you the wrong answer. Have you looked into how their get_unitary function works? I don’t know how well documented it is but there may be some details there. Or it may be a bug. I’m not sure. But this is where i’d look first. If the answer isn’t there then maybe you can open an issue in the Qiskit GitHub repo.

I hope this helps!

1 Like

Hi @CatalinaAlbornoz, thanks.
I find the qiskit’s results were also right using the matrix A its construction(don’t use A by pennylane constructed). But I still can’t understand what causes it. :rofl:

Hi @SHAN ,

I don’t understand what you mean. Can you elaborate a bit more please?

Thanks!

Hi @CatalinaAlbornoz ,
In qiskit example:

coefficient_set = [0.55, 0.225, 0.225]

#Qiskit A
a2 = coefficient_set[2]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0, 1,0,0,0,0,0], [0,0,0, 1,0,0,0,0], [0,0,0,0,-1,0,0,0], [0,0,0,0,0,-1,0,0], [0,0,0,0,0,0,-1,0], [0,0,0,0,0,0,0,-1]])
a1 = coefficient_set[1]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0,-1,0,0,0,0,0], [0,0,0,-1,0,0,0,0], [0,0,0,0, 1,0,0,0], [0,0,0,0,0, 1,0,0], [0,0,0,0,0,0,-1,0], [0,0,0,0,0,0,0,-1]])
a0 = coefficient_set[0]*np.array([[1,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0], [0,0, 1,0,0,0,0,0], [0,0,0, 1,0,0,0,0], [0,0,0,0, 1,0,0,0], [0,0,0,0,0, 1,0,0], [0,0,0,0,0,0, 1,0], [0,0,0,0,0,0,0, 1]])

a3 = np.add(np.add(a0, a1), a2)

b = np.array([float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8)),float(1/np.sqrt(8))])

A_inv = np.linalg.inv(a3)
x0 = np.dot(A_inv, b)
real_x = x0/np.linalg.norm(x0)

And the pred_x=V(α)|0> is approximately equal to real_x. It’s not the way PennyLane created A matrix, but a3 is right in this example. Maybe I didn’t make myself clear enough. But what I’m wondering is why are both methods correct?
(Qiskit example)