pyquil icon indicating copy to clipboard operation
pyquil copied to clipboard

Defining Permutation Gates Array is not unitary in pyquil/docs/source/basics.rst

Open fieldofnodes opened this issue 2 years ago • 5 comments

Pre-Report Checklist

  • [x] I am running the latest versions of pyQuil and the Forest SDK
  • [x] I checked to make sure that this bug has not already been reported

Issue Description

Code block

import numpy as np
from pyquil.quilbase import DefGate

ccnot_matrix = 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, 0, 1],
    [1, 0, 0, 0, 0, 0, 1, 0]
])

ccnot_matrix is not a unitary matrix.

>>> ccnot_gate = DefGate("CCNOT", ccnot_matrix)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/fieldofnodes/anaconda3/envs/Rigetti/lib/python3.9/site-packages/pyquil/quilbase.py", line 437, in __init__
    raise ValueError("Matrix must be unitary.")
ValueError: Matrix must be unitary.

If you take the conjugate transpose (transpose then complex conjugate of the given matrix), then multiply we should get the identity.

Suppose for a matrix $U$, then the conjugate transpose $U^\dagger$, we should have

$UU^\dagger = U^\dagger U = UU^{-1} = I,$

$I$ being the identity matrix.

ccnot_conjugate_transpose = ccnot_matrix.transpose()
ccnot_inverse = np.linalg.inv(ccnot_matrix) 

unitary_check1 = np.matmul(ccnot_matrix,ccnot_conjugate_transpose)
unitary_check2 = np.matmul(ccnot_conjugate_transpose,ccnot_matrix)
unitary_check3 = np.matmul(ccnot_matrix,ccnot_inverse)

np.array_equal(unitary_check1, unitary_check2)
np.array_equal(unitary_check1, unitary_check3)
np.array_equal(unitary_check2, unitary_check3)

>>> np.array_equal(unitary_check1, unitary_check2)
False
>>> np.array_equal(unitary_check1, unitary_check3)
False
>>> np.array_equal(unitary_check2, unitary_check3)
False

Also, check the identity matrix.

ccnot_size = ccnot_conjugate_transpose.shape[1]
identity = np.eye(8)

>>> np.array_equal(unitary_check1, identity)
False
>>> np.array_equal(unitary_check2, identity)
False
>>> np.array_equal(unitary_check2, identity)
False
----------------

If useful, provide a numbered list of the steps that result in the error.

Otherwise, just fill out the "Code Snippet" and "Error Output" sections below.

### Code Snippet

```python
Include a snippet of the pyQuil code that produces the error here.

Error Output

Additionally, please copy and paste the output of the above code here.

Environment Context

Operating System:

Python Version (python -V):

Quilc Version (quilc --version):

QVM Version (qvm --version):

Python Environment Details (pip freeze or conda list):

Copy and paste the output of `pip freeze` or `conda list` here.

fieldofnodes avatar Aug 09 '22 17:08 fieldofnodes

@fieldofnodes It looks like there is simply a typo in your definition of CCNOT. The bottom row should start with a 0 instead of a 1.

caldwellshane avatar Aug 09 '22 20:08 caldwellshane

The typo is in the latest stable version, I copied and pasted that.

fieldofnodes avatar Aug 09 '22 20:08 fieldofnodes

I'm not seeing it. The definition in simulation.matrices on the latest stable version (v3.2.1) looks correct: https://github.com/rigetti/pyquil/blob/v3.2.1/pyquil/simulation/matrices.py#L140.

There's also a docstring in gates which is also correct: https://github.com/rigetti/pyquil/blob/v3.2.1/pyquil/gates.py#L323.

Neither has been changed in the last three years or so.

Are you referring to something else?

caldwellshane avatar Aug 10 '22 15:08 caldwellshane

Here: https://pyquil-docs.rigetti.com/en/stable/basics.html This is the stable version

Go to Defining Permutation Gates

Note the matrx.

fieldofnodes avatar Aug 11 '22 14:08 fieldofnodes

See #1465

genos avatar Aug 11 '22 15:08 genos