Closed tjf801 closed 2 months ago
@tjf801 thank you! Added to our list.
@tjf801 by the way, I guess you already know that, but just in case to say that workaround is:
you can make n-control-NOT with multiple toffoli gates (requires adding ancilla qubits)
open circle (inverted control) can be done by surrounding control with X gates:
Workaround until we implement it natively.
Would love to see this natively, has there been any updates?
You deserved it after 2 years of waiting! :) Added to dev pipeline.
@tjf801 @tysonwolker
basic support for multi-controlled gates and inverted controls is now added to v0.9.186. Only u1
and x
for now.
Multi-controlled u1
var circuit = new QuantumCircuit();
// register controlled u1 gate with 3 controls
circuit.registerGate("mcu1_3", circuit.MCU1Circuit(3).save(true));
// And now you can add it anywhere into your circuit (with lamda of your choice)
circuit.appendGate("mcu1_3", [0, 1, 2, 3], { params: { lambda: "pi/3" } });
circuit.appendGate("mcu1_3", [2, 3, 0, 1], { params: { lambda: "pi/2" } });
console.log(circuit.exportQASM());
Output is:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[4];
gate mcu1_3(lambda) a, b, c, d
{
cu1 (lambda / 4) c, d;
cx c, b;
cu1 (-(lambda / 4)) b, d;
cx c, b;
cu1 (lambda / 4) b, d;
cx b, a;
cu1 (-(lambda / 4)) a, d;
cx c, a;
cu1 (lambda / 4) a, d;
cx b, a;
cu1 (-(lambda / 4)) a, d;
cx c, a;
cu1 (lambda / 4) a, d;
}
mcu1_3 (pi / 3) q[0], q[1], q[2], q[3];
mcu1_3 (pi / 2) q[2], q[3], q[0], q[1];
Multi-controlled x
var circuit = new QuantumCircuit();
// Register controlled x gate with 4 controls
circuit.registerGate("mcx_4", circuit.MCXCircuit(4).save(true));
// And use it in your circuit
circuit.appendGate("mcx_4", [0, 1, 2, 3, 4]);
circuit.appendGate("mcx_4", [2, 3, 0, 1, 4]);
console.log(circuit.exportQASM());
Output is:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[5];
gate mcx_4 a, b, c, d, e
{
h e;
cu1 ((pi) / 8) d, e;
cx d, c;
cu1 (-((pi) / 8)) c, e;
cx d, c;
cu1 ((pi) / 8) c, e;
cx c, b;
cu1 (-((pi) / 8)) b, e;
cx d, b;
cu1 ((pi) / 8) b, e;
cx c, b;
cu1 (-((pi) / 8)) b, e;
cx d, b;
cu1 ((pi) / 8) b, e;
cx b, a;
cu1 (-((pi) / 8)) a, e;
cx d, a;
cu1 ((pi) / 8) a, e;
cx c, a;
cu1 (-((pi) / 8)) a, e;
cx d, a;
cu1 ((pi) / 8) a, e;
cx b, a;
cu1 (-((pi) / 8)) a, e;
cx d, a;
cu1 ((pi) / 8) a, e;
cx c, a;
cu1 (-((pi) / 8)) a, e;
cx d, a;
cu1 ((pi) / 8) a, e;
h e;
}
mcx_4 q[0], q[1], q[2], q[3], q[4];
mcx_4 q[2], q[3], q[0], q[1], q[4];
Inverted controls
When creating gate, instead of simply providing number of control wires, you can provide array of boolean values where true
is normal control and false
is inverted.
Example: 3-controlled x
gate with second control inverted:
var circuit = new QuantumCircuit();
// Register controlled x gate with 3 controls. Second control is inverted:
circuit.registerGate("mcx_3_101", circuit.MCXCircuit([true, false, true]).save(true));
// And use it in your circuit
circuit.appendGate("mcx_3_101", [0, 1, 2, 3]);
circuit.appendGate("mcx_3_101", [2, 3, 0, 1]);
console.log(circuit.exportQASM());
Output is:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[4];
gate mcx_3_101 a, b, c, d
{
x b;
h d;
cu1 ((pi) / 4) c, d;
cx c, b;
cu1 (-((pi) / 4)) b, d;
cx c, b;
cu1 ((pi) / 4) b, d;
cx b, a;
cu1 (-((pi) / 4)) a, d;
cx c, a;
cu1 ((pi) / 4) a, d;
cx b, a;
cu1 (-((pi) / 4)) a, d;
cx c, a;
cu1 ((pi) / 4) a, d;
x b;
h d;
}
mcx_3_101 q[0], q[1], q[2], q[3];
mcx_3_101 q[2], q[3], q[0], q[1];
Warning! Achtung! In moment of writing this: not tested well!
Now this works in GUI as well: https://youtu.be/0ujizq7iat0
it would be nice to be able to add any amount of "control points" to any gate, and if you have time, an inverted "control point" would be nice also.