Skip to content

Commit

Permalink
Katas UI review - Multiqubit gates (#1845)
Browse files Browse the repository at this point in the history
Co-authored-by: Mariia Mykhailova <[email protected]>
Co-authored-by: César Zaragoza Cortés <[email protected]>
  • Loading branch information
3 people authored Aug 21, 2024
1 parent 1038ee4 commit 40a7783
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 69 deletions.
12 changes: 6 additions & 6 deletions katas/content/multi_qubit_gates/anti_controlled_gate/solution.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

In vector form the transformation we need is:
In vector form, the transformation you need is:

$$
\begin{bmatrix}\color{blue}\alpha\\ \color{blue}\beta\\ \gamma\\ \delta \end{bmatrix}
Expand All @@ -12,17 +12,17 @@ $$
U = \begin{bmatrix}0 & 1 & 0 & 0\\ 1 & 0 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}
$$

We remember a two-qubit gate with a similar matrix representation - the $CNOT$ gate:
Remember a two-qubit gate with a similar matrix representation - the $CNOT$ gate:

$$
CNOT =
\begin{bmatrix}1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 1\\ 0 & 0 & 1 & 0 \end{bmatrix}
$$

We need a way to transform the $CNOT$ gate into the unitary transformation represented by $U$.
We remember that the Pauli X gate flips the state in the single-qubit case. Here we need to use a 2-qubit version of this gate, which would affect only the second qubit. We conclude, that the idenity gate needs to be used on the first qubit. In the end, the required gate is a tensor product: $I \otimes X$.
You need a way to transform the $CNOT$ gate into the unitary transformation represented by $U$.
Remember that the Pauli X gate flips the state in the single-qubit case. Here you need to use a 2-qubit version of this gate, which would affect only the second qubit. You can conclude that the identity gate needs to be used on the first qubit. In the end, the required gate is a tensor product: $I \otimes X$.

We validate that composition of $I \otimes X$ and the $CNOT$ gate produces the required unitary transformation represented by $U$.
You validate that composition of $I \otimes X$ and the $CNOT$ gate produces the required unitary transformation represented by $U$.

$$
(I \otimes X)\cdot CNOT =
Expand All @@ -43,7 +43,7 @@ $$
"id": "multi_qubit_gates__anti_controlled_gate_a",
"codePath": "./SolutionA.qs"
})
Alternatively, we can notice that the task requires application of a Pauli X gate on the second qubit when the first qubit is in the $\ket{0}$ state. This can be achieved with [`ApplyControlledOnInt`](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonint) library operation.
Alternatively, you can notice that the task requires application of a Pauli X gate on the second qubit when the first qubit is in the $\ket{0}$ state. This can be achieved with [`ApplyControlledOnInt`](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonint) library operation.

Notice that the `ApplyControlledOnInt` operation uses an array of qubits as control, not by a single qubit.

Expand Down
10 changes: 5 additions & 5 deletions katas/content/multi_qubit_gates/arbitrary_controls/solution.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
We are asked to perform an $X$ gate on the `target` qubit controlled by the state of `controls` qubits; this state should correspond to the mask given by `controlBits`.
You're asked to perform an $X$ gate on the `target` qubit controlled by the state of `controls` qubits; this state should correspond to the mask given by `controlBits`.

If the `controlBits` mask consists of all `true` values, we can use a familiar `Controlled X` gate. What can we do if the mask has some `false` values in it?
If the `controlBits` mask consists of all `true` values, you can use a familiar `Controlled X` gate. What can you do if the mask has some `false` values in it?

Turns out we can transform the state of the control qubits depending on the corresponding elements of `controlBits`: if the element is `false`, we apply an $X$ gate to the corresponding qubit in the `controls` array. After this, `Controlled X` gate will apply an $X$ gate in the exact case that we want.
Finally, we'll need to remember to undo ("uncompute") the first step, otherwise our controlled gate will affect the state of the control qubits as well as the state of the target.
Turns out you can transform the state of the control qubits depending on the corresponding elements of `controlBits`: if the element is `false`, you apply an $X$ gate to the corresponding qubit in the `controls` array. After this, `Controlled X` gate will apply an $X$ gate in the exact case that you want.
Finally, you'll need to remember to undo ("uncompute") the first step, otherwise your controlled gate will affect the state of the control qubits as well as the state of the target.

As you can see in the first cell below, this can take quite some coding.

Expand All @@ -12,7 +12,7 @@ As you can see in the first cell below, this can take quite some coding.
"codePath": "./SolutionA.qs"
})

We can shorten the code a bit using the `within ... apply` construct which takes care of uncomputing the steps done in the first code block automatically:
You can shorten the code a bit using the `within ... apply` construct which takes care of uncomputing the steps done in the first code block automatically:

@[solution]({
"id": "multi_qubit_gates__arbitrary_controlled_solution_b",
Expand Down
2 changes: 1 addition & 1 deletion katas/content/multi_qubit_gates/compound_gate/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ i & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
\end{bmatrix}
$$

> We recommend to keep a list of common quantum gates on hand.
> It's recommended to keep a list of common quantum gates on hand.
<details>
<summary><b>Need a hint?</b></summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
In Q# the `Rx` intrinsic gate takes the angle $\theta$ and the target qubit as inputs. To create a controlled version of this gate, we can use the `Controlled` functor.
In Q#, the `Rx` intrinsic gate takes the angle $\theta$ and the target qubit as inputs. To create a controlled version of this gate, you can use the `Controlled` functor.

A matrix representation of this operation would be:

Expand All @@ -11,7 +11,7 @@ The parameters of the new gate are changed a bit:
* The first parameter has to be the array of control qubits; the `Rx` gate will be applied to the target only if these are all in the $\ket{1}$ state. Note that this parameter has to be an array, even if there is just one control qubit!
* The second parameter is a tuple with the parameters that you would've passed to the original `Rx` gate. You can create a tuple of values by putting round brackets around them.

> The `Controlled` functor can be used before any single-qubit gate to make it a controlled gate. The first argument will be an array of qubits even if you are using a single control qubit, like in the $CNOT$ gate. The second argument is a tuple `()` with the parameters of the gate. For example, these two gates are equivalent: `CNOT(qs[0], qs[1])` and `Controlled X([qs[0]], (qs[1]));`
> The `Controlled` functor can be used before any single-qubit gate to make it a controlled gate. The first argument will be an array of qubits even if you're using a single control qubit, like in the $CNOT$ gate. The second argument is a tuple `()` with the parameters of the gate. For example, these two gates are equivalent: `CNOT(qs[0], qs[1])` and `Controlled X([qs[0]], (qs[1]));`
@[solution]({
"id": "multi_qubit_gates__controlled_rotation_solution",
Expand Down
8 changes: 4 additions & 4 deletions katas/content/multi_qubit_gates/entangle_qubits/solution.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Let's denote the first qubit in state $\alpha \ket{0} + \beta \ket{1}$ as A and the second qubit in state $\ket{0}$ as B.

Compare our input state $\alpha \ket{0_A0_B} + \beta \ket{1_A0_B}$ with the goal state $\alpha \ket{0_A0_B} + \beta \ket{1_A1_B}$.
We want to pass our input qubit through a gate or gates (to be decided) that do the following. If qubit A is in the $\ket{0}$ state, then we want to leave qubit B alone (the first term of the superposition).
However, if A is in the $\ket{1}$ state, we want to flip qubit B from $\ket{0}$ into $\ket{1}$ state. In other words, the state of B is to be made contingent upon the state of A.
This is exactly the effect of the $CNOT$ gate. Depending upon the state of the **control** qubit (A in our case), the value of the controlled or **target** qubit (B in our case) is inverted or unchanged. Thus, we get the goal state $\alpha \ket{00} + \beta \ket{11}$.
Compare the input state $\alpha \ket{0_A0_B} + \beta \ket{1_A0_B}$ with the goal state $\alpha \ket{0_A0_B} + \beta \ket{1_A1_B}$.
You want to pass our input qubit through a gate or gates (to be decided) that do the following. If qubit A is in the $\ket{0}$ state, then you want to leave qubit B alone (the first term of the superposition).
However, if A is in the $\ket{1}$ state, you want to flip qubit B from $\ket{0}$ into $\ket{1}$ state. In other words, the state of B is to be made contingent upon the state of A.
This is exactly the effect of the $CNOT$ gate. Depending upon the state of the **control** qubit (A in this case), the value of the controlled or **target** qubit (B in this case) is inverted or unchanged. Thus, you get the goal state $\alpha \ket{00} + \beta \ket{11}$.

@[solution]({
"id": "multi_qubit_gates__entangle_qubits_solution",
Expand Down
2 changes: 1 addition & 1 deletion katas/content/multi_qubit_gates/fredkin_gate/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
**Input:** Three qubits (stored in an array of length 3) in an arbitrary three-qubit state
$\alpha \ket{000} + \beta \ket{001} + \gamma \ket{010} + \delta \ket{011} + \epsilon \ket{100} + {\color{blue}\zeta}\ket{101} + {\color{blue}\eta}\ket{110} + \theta\ket{111}$.

**Goal:** Swap the states of second and third qubit if and only if the state of the first qubit is $\ket{1}$, i.e., change the three-qubit state to $\alpha \ket{000} + \beta \ket{001} + \gamma \ket{010} + \delta \ket{011} + \epsilon \ket{100} + {\color{red}\eta}\ket{101} + {\color{red}\zeta}\ket{110} + \theta\ket{111}$.
**Goal:** Swap the states of second and third qubit if and only if the state of the first qubit is $\ket{1}$, that is, change the three-qubit state to $\alpha \ket{000} + \beta \ket{001} + \gamma \ket{010} + \delta \ket{011} + \epsilon \ket{100} + {\color{red}\eta}\ket{101} + {\color{red}\zeta}\ket{110} + \theta\ket{111}$.
6 changes: 3 additions & 3 deletions katas/content/multi_qubit_gates/fredkin_gate/solution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This is essentially bookwork, because there is only one gate that performs this state change (and the task title already gave it away!)
This is essentially bookwork, because there's only one gate that performs this state change (and the task title already gave it away!)
The Fredkin gate is also known as the controlled $SWAP$ gate:
$$
\begin{bmatrix}
Expand All @@ -12,13 +12,13 @@ $$
0 & 0 & 0 & 0 & 0 & 0 & 0 & 1
\end{bmatrix}
$$
and our initial state is:
and the initial state is:
$$
\begin{bmatrix}
\alpha \\ \beta \\ \gamma \\ \delta \\ \epsilon \\ \zeta \\ \eta \\ \theta
\end{bmatrix}
$$
So we have:
So you have:
$$
\begin{bmatrix}
1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
Expand Down
Loading

0 comments on commit 40a7783

Please sign in to comment.