Skip to content
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

Feature Request: Any amount of control Qbits #30

Open
tjf801 opened this issue Oct 9, 2019 · 7 comments
Open

Feature Request: Any amount of control Qbits #30

tjf801 opened this issue Oct 9, 2019 · 7 comments

Comments

@tjf801
Copy link

tjf801 commented Oct 9, 2019

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.

@perak
Copy link
Collaborator

perak commented Oct 9, 2019

@tjf801 thank you! Added to our list.

@perak
Copy link
Collaborator

perak commented Oct 10, 2019

@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)

Screen Shot 2019-10-10 at 10 53 38 PM

  • open circle (inverted control) can be done by surrounding control with X gates:

Screen Shot 2019-10-10 at 11 02 52 PM

@perak
Copy link
Collaborator

perak commented Oct 10, 2019

Workaround until we implement it natively.

@tysonwolker
Copy link

Would love to see this natively, has there been any updates?

@perak
Copy link
Collaborator

perak commented Sep 9, 2021

You deserved it after 2 years of waiting! :) Added to dev pipeline.

@perak
Copy link
Collaborator

perak commented Sep 10, 2021

@tjf801 @tysonwolker

basic support for multi-controlled gates and inverted controls is now added to v0.9.186. Only u1 and x for now.

Usage:

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!

@perak
Copy link
Collaborator

perak commented Sep 13, 2021

Now this works in GUI as well: https://youtu.be/0ujizq7iat0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants