dwavesystems / dwave-gate

dwave-gate is a software package for constructing, modifying and running quantum circuits on the provided state-vector simulator.
Apache License 2.0
12 stars 7 forks source link

Drawing circuits #46

Closed ACE07-Sev closed 4 months ago

ACE07-Sev commented 5 months ago

Greetings dear D-Wave team,

Hope all are well. How can I draw a circuit to visually confirm if a gate is applied correctly? I have been using the circuit.circuit for now, but I think there's either an issue with the ParametricOperation, or with how it is printed :

circuit = Circuit(5, 5)

for i in range(3):
    with circuit.context as (q, c):
        RX(np.pi, q[i]).conditional([q[3], q[4]])
    circuit.unlock()

I get this output, but I don't imagine it is correct :

[<ParametricOperation: RX([3.141592653589793]), qubits=(<qubit: '0', id: q03k>,)>,
 <ParametricOperation: RX([3.141592653589793]), qubits=(<qubit: '1', id: q07v>,)>,
 <ParametricOperation: RX([3.141592653589793]), qubits=(<qubit: '2', id: q0vz>,)>]

For your kind reference, I am trying to implement a multi-controlled RX gate.

thisac commented 5 months ago

Hi @ACE07-Sev,

The conditional modifier is used for applying gates dependent on prior measurements. For example, the following code snippet would apply an RX(pi/2) gate followed by a measurement (which should now have a 0.5 chance of measuring either 0 or 1). The second RX gate is only applied (at runtime) if the measurement output is 1.

from dwave.gate import Circuit
from dwave.gate.operations import RX, Measurement
from dwave.gate.simulator import simulate

circuit = Circuit(1, 1)
with circuit.context as (q, c):
    RX(np.pi / 2, q[0])
    Measurement(q[0]) | c[0]
    RX(np.pi, q[0]).conditional(c[0])

simulate(circuit)

If you'd like to create an operation controlled on other qubits you'd need to create your own controlled operation with RX(np.pi) as the target as a class inheriting from ControlledOperation.

from dwave.gate.operations import ControlledOperation

class RXControlledOp(ControlledOperation):
    _num_control = 2
    _num_target = 1
    _target_operation = RX(np.pi)

The RXControlledOp can now be applied in circuits as usual. In your case it would be:

circuit = Circuit(5, 5)
with circuit.context as (q, _):
    for i in range(3):
        RXControlledOp(control=(q[3], q[4]), target=q[i])

You should then get the following, which should run fine on the included simulator.

[<ControlledOperation: RXControlledOp, qubits=(<qubit: '3', id: qa2c>, <qubit: '4', id: q0c7>, <qubit: '0', id: q0h9>)>,
 <ControlledOperation: RXControlledOp, qubits=(<qubit: '3', id: qa2c>, <qubit: '4', id: q0c7>, <qubit: '1', id: q0kp>)>,
 <ControlledOperation: RXControlledOp, qubits=(<qubit: '3', id: qa2c>, <qubit: '4', id: q0c7>, <qubit: '2', id: qa14>)>]
ACE07-Sev commented 5 months ago

Understood. I do apologize for asking so many questions, but I have two more for the moment. One is how I can draw the circuits, and the other is how I can get the depth of the circuit.

thisac commented 5 months ago

how I can draw the circuits

Currently, there's no internal way to draw the circuits, although we're working on adding that functionality. You could try to convert the circuit into OpenQASM 2 and then draw it using Qiskit as a workaround.

how I can get the depth of the circuit

The circuits in dwave-gate aren't packed, meaning that the gates are applied sequentially. With this is mind, the circuit depth is simply the number of gates in the circuit (i.e., the length of Circuit.circuit minus any non-gate operations, with some potential caveats depending on how we choose to define circuit depth).

ACE07-Sev commented 4 months ago

Ohh I see. I'll have to update my code a bit. Would it be fine to keep this thread open for further questions so that I don't have to open new issues?

ACE07-Sev commented 4 months ago

Ok, so I am having a bit of an issue with the simulator. It doesn't represent the small values like 0.02 amplitudes, which basically when used with algorithms like FRQI, makes it output a numpy array of all 0s. Anything I can do to fix this?

Here's what I get with Cirq for instance :

[0.125      0.125      0.125      0.125      0.125      0.125
 0.125      0.125      0.125      0.125      0.125      0.125
 0.125      0.1221966  0.12381981 0.125      0.125      0.125
 0.125      0.125      0.12480307 0.11370273 0.125      0.125
 0.125      0.125      0.125      0.12498055 0.1087806  0.125
 0.125      0.125      0.125      0.125      0.125      0.11108285
 0.12499628 0.125      0.125      0.125      0.125      0.125
 0.12250098 0.12246352 0.125      0.125      0.125      0.125
 0.125      0.125      0.10999145 0.12485503 0.125      0.125
 0.125      0.125      0.125      0.125      0.125      0.125
 0.125      0.125      0.125      0.125      0.         0.
 0.         0.         0.         0.         0.         0.
 0.         0.         0.         0.         0.         0.0263247
 0.01713632 0.         0.         0.         0.         0.
 0.0070138  0.05192965 0.         0.         0.         0.
 0.         0.00220521 0.06157745 0.         0.         0.
 0.         0.         0.         0.05732016 0.00096478 0.
 0.         0.         0.         0.         0.02486988 0.02505364
 0.         0.         0.         0.         0.         0.
 0.05938755 0.00601839 0.         0.         0.         0.
 0.         0.         0.         0.         0.         0.
 0.         0.        ]

And here's what I get with D-Wave :

[0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125
 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125
 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125
 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125
 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125
 0.125 0.125 0.125 0.125 0.    0.    0.    0.    0.    0.    0.    0.
 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
 0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
 0.    0.    0.    0.    0.    0.    0.    0.   ]

You see the difference? This is causing my code to break as you can imagine. Is there a way I can fix this? Again, this is only in D-Wave, I tried the code with Qiskit, Cirq, TKET, and PennyLane, and they are running as expected, and can extract these smaller values. I'd appreciate the help on fixing this.

thisac commented 4 months ago

Hi @ACE07-Sev. It would be great if you could open a new issue for this and include code examples for both the dwave-gate and e.g., the Cirq example. If you have any further questions about drawing circuits feel free to post them in this issue.

I'll close this one for now but we could reopen it if needed.