$$ \def\bra#1{\mathinner{\left\langle{#1}\right|}} \def\ket#1{\mathinner{\left|{#1}\right\rangle}} \def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}} $$

Q# 入門していく(4)

問題

Problem - A4 - Codeforces

\( 2^k \)bit の qubits で W 状態をつくる。

解法

難しかった。

 

\( 2^{k-1} \)bit の qubits で W 状態をまずつくる。

 


そのうえである1つの qubit を用意し、アダマール変換しておく。これでこの qubit は等確率で\(\ket{0}\)と\(\ket{1}\)が観測される。

 

この qubit を制御ビットとして、すでに作ってある W 状態の qubits をもとに\( 2^{k} \)bit の qubits に拡張していく。SWAPゲートで\(\ket{(W)0..0}\)と\(\ket{0..0(W)}\)が作成できる。

 

ここで忘れていけないのが制御ゲートを使っているということ。つまり作成したのは\(\ket{0}\ket{(W)0..0}\)と\(\ket{1}\ket{0..0(W)}\)であり、用意した qubit とエンタングル状態にある。このエンタングル状態をとく、つまり\(\ket{+}\ket{(W)}\)の直積で書ける状態にするには\(\ket{1}\ket{(W)0..0}\)と\(\ket{0}\ket{0..0(W)}\)の状態も作らなければいけない。このために最後にCNOTゲートをつかっている。

 

量子ゲートで複数入力・複数出力のものがあるが、qubits の状態が入力され qubits の状態が出力されるとイメージしないと罠にはまってしまう。個々の qubit で考えると間違える(重要)。

コード


namespace Solution {
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;

operation Solve(qs : Qubit[]) : () {
  body {
    let n = Length(qs);
    if (n == 1) {
      X(qs[0]);
    } else {
      let m = n / 2;
      Solve(qs[0..m - 1]);
      using(qb = Qubit[1]) {
        H(qb[0]);
        for (i in 0..m - 1) {
          (Controlled SWAP)([qb[0]], (qs[i], qs[i + m]));
        }
        for (i in m..n - 1) {
          CNOT(qs[i], qb[0]);
        }
      }
    }
  }
}
}  // namespace Solution