Closed EnginSahinCE closed 7 years ago
There are several ways to do this. The easiest is to create a new gate with the exact Unitary matrix of the multi-controlled gate you want. For example, Toffoli is done with:
/// <summary>
/// Performs a Toffoli or Controlled-Controlled-NOT gate
/// </summary>
/// <param name="qs">The first two qubits in the list are the control qubits, and the third qubit is the target,</param>
let CCNOT (qs:Qubits) =
let gate =
Gate.Build("CCNOT",fun () ->
new Gate(
Name = "CCNOT",
Help = "Toffoli - Controlled Controlled Not",
Mat = (
let m = CSMat(8)
m.r(6,6) <- 0.0
m.r(6,7) <- 1.0
m.r(7,7) <- 0.0
m.r(7,6) <- 1.0
m),
Draw = "\\ctrl{#1}\\go[#1]\\ctrl{#2}\\go[#2]\\targ"
))
gate.Run qs
Another way is to use the Cgate (or CCgate) gate that adds a control to an existing gate (or one you've already defined):
/// <summary>
/// Performs a parent gate under two-qubit quantum control.
/// The parent must be a unitary gate.
/// </summary>
/// <param name="f">The gate to control.</param>
/// <param name="qs">The first two qubits are the control, and the remainder are passed to the parent gate.</param>
let CCgate (f:Qubits->unit) (qs:Qubits) =
let gate (f:Qubits->unit) (qs:Qubits) =
let parent = !< f qs.Tail.Tail
parent.AddControl(2)
(gate f qs).Run qs
Notice the use of AddControl
which will add any number of controls to another gate (the parent
).
Now comes the question of how to do "0" controlled gates. Just create the gate (by either method above) with "1" controls and then create a wrapper gate with an "X" before (and after) the control gate on each line you want controlled with a "0". Here's a sample wrapper gate from inside the Shor algorithm:
/// <summary>
/// Controlled rotation gate
/// </summary>
/// <param name="k">Rotation by 2^k</param>
/// <param name="qs">Qubits ([0]=Control [1]=rotated)</param>
let CR (k:int) (qs:Qubits) =
let gate (k:int) (qs:Qubits) =
Gate.Build("CR_" + k.ToString() ,fun () ->
new Gate(
Qubits = qs.Length,
Name = "CR",
Help = "Controlled R gate",
Draw = sprintf "\\ctrl{#1}\\go[#1]\\gate{R%d}" k,
Op = WrapOp (fun (qs:Qubits) -> Cgate (R k) qs)
))
(gate k qs).Run qs
In the WrapOp
function you can put as many X
gates as you like. This should give you everything you need to create your new gate.
thank you for your help. I could not think of the X gate before Cgate(and after).
I think you misunderstood what I meant. The X gates go outside of the control gate. For example, change your code to this:
let CG (f:Qubits->unit) (qs:Qubits) =
let gate (f:Qubits->unit) (qs:Qubits) =
let parent = !< f qs.Tail.Tail
parent.AddControl(2)
(gate f qs).Run qs
let C0C0X (qs:Qubits) =
let gate (qs:Qubits) =
Gate.Build("C0C0_X" ,fun () ->
new Gate(
Qubits = qs.Length,
Name = "CX",
Help = "Controlled_0 Controlled_0 X gate",
Draw = sprintf "\\ctrlo{#1}\\go[#1]\\ctrlo{#2}\\go[#2]\\gate{X}",
Op = WrapOp (fun (qs:Qubits) ->
X >< !!(qs,[0;1])
CG X qs
X >< !!(qs,[0;1])
)
))
(gate qs).Run qs
let k = Ket(4)
let qs = k.Qubits
H >< !!(qs,1,2)
let _ = k.Single()
k.Dump showInd
C0C0X !!(qs,0,2,3)
k.Dump showInd
and what you get for output is:
0:0000.0/Ket of 4 qubits:
0:0000.0/=== KetPart[ 0]:
0:0000.0/Qubits (High to Low): 0 1 2 3
0:0000.0/0x00000000: 0.5
0:0000.0/0x00000002: 0.5
0:0000.0/0x00000004: 0.5
0:0000.0/0x00000006: 0.5
0:0000.0/Ket of 4 qubits:
0:0000.0/=== KetPart[ 0]:
0:0000.0/Qubits (High to Low): 0 1 2 3
0:0000.0/0x00000001: 0.5
0:0000.0/0x00000002: 0.5
0:0000.0/0x00000005: 0.5
0:0000.0/0x00000006: 0.5
which I believe is what you wanted.
After I wrote what you wanted to say, I understood and I deleted the other question. I first noticed X then X event later. Thank you so much for your help again. My problem is solved.
I want to make a controleld gate but source qubits are not only 1 state, for example C-Swap (n qubit controlled);
let consider that we have |phi> state; qs: |0001> -> H [qs.[1]]; H [qs.[2]]; -> |0001>+|0011>+|0101>+|0111> = |phi>
and apply SWAP(0,3) gate with controlled |10> for controlled qubits 1,2; (if qubit[1]=1 and qubit[2]=0 then apply SWAP(q.[0];q.[3]) gate); U |phi> -> |0001>+|0011>+|1100>+|0111>
(or controlled |1010> for controlled qubits 1,2,3,4) Can i do this, how do i ?