-
Notifications
You must be signed in to change notification settings - Fork 64
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
Adds single qubit decomposition functions #52
Conversation
except ZeroDivisionError: | ||
input_array = input_array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discuss at June 14 meeting
Don't think this exception has to be added. If this function's goal is to check if the matrix is unitary or not then a matrix whose determinant is zero is not a unitary matrix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you can return False
already.
However, I'm not sure if normalizing is needed. It seems very unlikely to me that a not normalized gate will be unitary after the normalization. If someone provides something with |det| != 1
, he/she already missed the point of providing a unitary.
Or is there a special reason?
except ZeroDivisionError: | ||
input_array = input_array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discuss at June 14 meeting
Same as above. If the determinant is zero then do not need to make this exception. det(U) = 1
|
||
import numpy as np | ||
|
||
def normalize_matrix(input_array)-> np.array: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if we can have an optional parameter in the main function that allows turning off some checks if the decomposition is used e.g. for qutip predefined gates. Those gates should, by construction, be valid.
except ZeroDivisionError: | ||
input_array = input_array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you can return False
already.
However, I'm not sure if normalizing is needed. It seems very unlikely to me that a not normalized gate will be unitary after the normalization. If someone provides something with |det| != 1
, he/she already missed the point of providing a unitary.
Or is there a special reason?
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
############################################################################### | ||
|
||
# add functions to check the calculated decomposition is equivalent to input array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you mean checking whether the decomposed list of matrices is correct after the decomposition, I think it should be in the tests and not here. If we provide something for the user, we should make sure in advance that it is correct by testing it ourselves.
Unless there are some round-off error or special reasons that we cannot tell ahead if the decomposition will succeed?
if input_check_bool == True: | ||
input_shape = input_gate.shape | ||
if input_shape[0]%2==0.0: # won't be 2 for higher qudits | ||
# TO DO : if d=4 (qu4it) then it will still appear as a d=2 i.e. qubit gate | ||
# change to powers of 2 | ||
number_of_qubits = np.log(input_shape[0])/np.log(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hodgestar @BoxiLi Is there a better way to find the number of qubits based on the size/shape of the input gate matrix ? Here, with what I have chosen to do, if the qudits are of dimensions that are power of 2 then my condition is valid for both qubit and said qudit.
Could dims
work here ?
If I have a 2 qubit state unitary then dims = [[[2], [2]], [[2], [2]]]
but if it was a qu4it state unitary then dims = [[4,4]]
.
And I think, a qutrit-qudit gate will also be incorrectly identified as a qubit gate. But I can change the line to be division by powers of 2 which will help catch odd-even dimensional states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BoxiLi @hodgestar I edited my previous comment. I think I have a better idea now. It's possible my understanding of dims
is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason that we need to consider qudits/qutrits? I thought the whole decomposition module assumes that we are working with qubits? Or is there anything also useful for qudits?
This kind of information is much easier to extract from the Qobj
, before taking the full numpy matrix. A 2-qubit ket state has dims=[[2, 2], [1, 1]]
, while a qudit ket dims=[[4], [1]]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For unitaries acting on them: dims=[[2, 2], [2, 2]]
and dims=[[4], [4]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason that we need to consider qudits/qutrits?
Not really. As the user can input any n x n unitary, I added this extra check to make sure the unitary acts only on qubits and not on other dimensions.
Plus, this should be able to find the number of qubits a unitary is acting on by looking at the shape/dims.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then this is just a validity check. Since the input is Qobj
, using dims
is easier. We can check if it is a list of 2
.
input_gate.dims[0] == [2] * len(input_gate.dims[0])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's my problem. dims
cannot distinguish between a 4 x 4 input. It could be an object acting on 2 qubits or a qudit of d = 4.
q = Qobj([[0., 0, 0, 0.],[0., 0, 0, 0.],[0., 0, 0, 0.],[0., 0, 0, 0.]])
q.dims = [[4], [4]]
I think I am going to change the input to the function. In addition to the input Qobj, they will also need to input number of qubits. This could help avoid the ambiguity. Then, this function could check if the shape of input gate is compatible with number of qubits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, technically speaking, the example you provided is interpreted in QuTiP as a unitary acting on a qudit system, not two qubits.
E.g.
q = Qobj([[0., 0, 0, 0.],[0., 0, 0, 0.],[0., 0, 0, 0.],[0., 0, 0, 0.]], dims = [[4], [4]])
q * basis([2,2],[0,0])
will raise an error because the dimension does not match. This is how QuTiP distinguish them. If the user is meant to provide an operator acting on qubits, the dimension should match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, in decomposition we can also be lenient and allow the user to just produce a 2^n times 2^n Qobj
.
So I see two options:
- We make it strict and all the input must have the dimension
[[2,2,2,...],[2,2,2,...]
- We allow it to be ambiguous a bit and require that
input.shape[0]
is a power of 2, by some smart bit manipulation: https://stackoverflow.com/questions/57025836/how-to-check-if-a-given-number-is-a-power-of-two. Although it will be a bit hard to find out what isn
since technicallylog2(2^n)
is not always reliable to give asn
. Asking the user to provide the number of qubits is also fine.
Closing this PR because I want to start on a new branch. When trying to rebase this branch, there were a lot of conflicts. |
WIP for 4 single qubit decomposition functions.
To do before marking PR ready for review :