-
Notifications
You must be signed in to change notification settings - Fork 61
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
Enhanced gates.Unitary
draw with matplotlib
#1618
base: master
Are you sure you want to change the base?
Enhanced gates.Unitary
draw with matplotlib
#1618
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #1618 +/- ##
=======================================
Coverage 99.07% 99.07%
=======================================
Files 77 77
Lines 11437 11437
=======================================
Hits 11331 11331
Misses 106 106
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
gates.Unitary
draw with matplotlib
Is there any way of distinguishing these unitaries from each other? For instance, the second and third unitaries in your example are different matrices but have the same symbol, so it might lead someone to think they are the same. |
These are the properties from the U-gates you mention:
I think that qibo does not provide enough information to distisguish the behaviour from each U-gate. Your comment is related to this very old issue: #478 (comment) IMHO, It is not possible yet...or am I wrong? |
Not that is simple, but in principle you could hash the matrix values in the gate parameters ( Every time you need to grab a symbol, you could just query the register. If it's in there, you take the index, if it's not, you add a new entry, with the |
Thanks @alecandido , but I do not understand how to pick up the data buffer and check on every U-gate, do you mean to hash the full U-gate? I do not catch how to pick up each single U-gate, can you point me a little example please? |
@sergiomtzlosa the |
thanks a lot @alecandido , the property
Should we think about add another property on the Unitary class to set a name to each single Unitary gate? What do you think? |
My first inclination is to say that the change needs to be in the This is just one idea, but we could think of others. |
[ins] In [3]: u = gates.Unitary(np.ones((2,2)), 0)
[ins] In [4]: hash(u.parameters[0].data.tobytes())
Out[4]: 6949360754640926774 No need to add any further info (if you accept to name them |
A |
I was not proposing to use a hash as the matrix index, but to use the hash to build a register: def unitary_id(u: Unitary, register: dict) -> int:
h = hash(u.parameters[0].data.tobytes())
id_ = register.get(h)
if id_ is not None:
return id_
id_ = register[h] = len(register)
return id_
register: dict[int, int] = {}
id_ = unitary_id(u, register) |
thanks @renatomello and @alecandido !! both solutions are good!!👍. I think that we can simplify the @alecandido solution by getting a global hash for the Unitary gate to identify it and then label each single U-gate with an index according to the number of target qubits, from 0 to len(_target_qubits) just for drawing....I keep on thinking a solution. |
Sorry @sergiomtzlosa, but anything "global" is only simple for a relative short time span. As soon as you will have to maintain (change, debug it, or debug something related) it would get much more complicate. Also because it will be more complicate to reproduce. I do not want to argue that the solution I proposed is the unique and best one. Just be careful about global objects (including having classes so huge which will act almost as a global context for most executions, as it could be a |
thanks @alecandido , sorry for that, I will focus on a more flexible solution like yours😉 |
Nothing to be sorry about. And despite being rather direct, I just wanted to be clear about something I consider relevant. But it was absolutely not meant to criticize your approach. I know the pros and cons of working with global objects myself (and, by now, I know there are mostly cons...), just because I went through the same issues myself. So, it was just me sharing a bit of hard-learnt experience :P |
great @alecandido ! I did not feel criticised at any time. I truly understand your point of view and as you know how qibo works internally more than me, I feel very happy to be part of the discussion, and as you have more expertise than me on qibo and I will follow your ideas to do a better framework. Thanks a lot! |
@sergiomtzlosa what does the left subscript mean? |
hi @renatomello ! I set the left subscript just to enumerate the gates, that'a all! they do nothing |
I thought the right subscripts were enumerating the unitaries... |
as they do nothing on both sides, then I should remove them... |
@renatomello I actually suggested it above:
This is to distinguish |
I do not know how to do that because this Unitary gates representation do not distinguish between target and control qubits...can you point me how to achive this please?🙏 |
For that, I would suggest a superscript like |
I expected it to be exactly what you did. In the plot in #1618 (comment), I expected that, if you reused twice So, if a circuit contains c.add(Unitary(array, 0, 1, 3))
c.add(Unitary(array, 2, 1, 3)) both gates would be represented with 3 boxes using |
sorry for bothering you.... |
Yes, that's correct. But apparently the right subscript it is not: if the |
Finally, by having a look at the example below: import numpy as np
from qibo import Circuit, gates, models, construct_backend
from qibo.ui import plot_circuit
from qibo.quantum_info import random_unitary
backend = construct_backend("numpy")
c = models.Circuit(4)
array1 = random_unitary(8, backend=backend, seed=42)
array2 = random_unitary(8, backend=backend, seed=44)
array3 = random_unitary(8, backend=backend, seed=48)
c.add(gates.Unitary(array1, 0, 1, 3))
c.add(gates.X(0))
c.add(gates.Unitary(array1, 1, 0, 3))
c.add(gates.Unitary(random_unitary(2, backend=backend, seed=50), 2))
c.add(gates.Unitary(array2, 1, 0, 3))
c.add(gates.Z(1))
c.add(gates.Unitary(array2, 2, 1, 0))
c.add(gates.Y(2))
c.add(gates.Unitary(array3, 1, 0, 3))
plot_circuit(c); The drawer will show as: |
I reviewed the merge conflicts with the master branch, you can have a look for merging. Thanks a lot! |
Checklist:
Now for the circuit below:
The output image is: