QuantumKatas Superposition Task 12
量子コンピューティングの問題集Microsoft/QuantumKatasでは、Q#プログラムを完成させてユニットテストを実行することにより、問題を解いていくことができます。
今回は、解くのに時間がかかった問題Superposition Task 12
について、紹介します。
ユニットテストの実行方法は以下です。(参考: Microsoft Quantum Development Kitのインストール(Linux))
$ cd QuantumKatas/Superposition $ dotnet test
Task 12
- 入力
- N個の量子ビットの状態|0...0>
- 2つのBool型配列
- ゴール
- 状態|0...0>から2つのBool型配列が表す等確率の重ね合わせ状態を作る
- 例) Bool型配列が[false, true, false]と[false, false, true]のとき、(|010> + |001>) / sqrt(2) を作る
- 前提条件
- 2つのBool型配列の要素数はどちらもN
- 2つのBool型配列は、少なくとも1要素は異なる
方針
- 最初の量子ビットにアダマールゲートを作用させ、を作る
- 上で作ったのは2つの状態の重ね合わせ。すなわち、0番目の量子ビットが|0>の状態Aと|1>の状態Bの重ね合わせ。状態Aに配列bits1、状態Bに配列bits2を設定する。
- 1番目〜N-1番目の量子ビットをbits1, bits2の要素に応じて反転させる(|0>を|1>にする)。ここで、0番目の量子ビットの状態を判別のために使う。
- 最後に残った0番目の量子ビットを設定する。bits1とbits2は、0番目が異なる場合と、1番目〜N-1番目のどれかが異なる場合があることを考慮する。
解答(テストは通った)
// Task 12. Superposition of two bit strings // Inputs: // 1) N qubits in |0...0⟩ state // 2) two bit string represented as Bool[]s // Goal: create an equal superposition of two basis states given by the bit strings. // // Bit values false and true correspond to |0⟩ and |1⟩ states. // Example: for bit strings [false, true, false] and [false, false, true] // the qubit state required is (|010⟩ + |001⟩) / sqrt(2). // You are guaranteed that the both bit strings have the same length as the qubit array, // and that the bit strings will differ in at least one bit. operation TwoBitstringSuperposition (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Unit { mutable diffIndex = 0; H(qs[0]); for (i in 1..Length(qs)-1) { if (bits1[i] != bits2[i]) { set diffIndex = i; } if (bits1[i]) { (ControlledOnInt(0, X))([qs[0]], qs[i]); } if (bits2[i]) { (ControlledOnInt(1, X))([qs[0]], qs[i]); } } if (diffIndex == 0) { if (bits1[0]) { X(qs[0]); } } else { if (bits1[0]) { if (bits1[diffIndex]) { (ControlledOnInt(1, X))([qs[diffIndex]], qs[0]); } else { (ControlledOnInt(0, X))([qs[diffIndex]], qs[0]); } } if (not bits2[0]) { if (bits2[diffIndex]) { (ControlledOnInt(1, X))([qs[diffIndex]], qs[0]); } else { (ControlledOnInt(0, X))([qs[diffIndex]], qs[0]); } } } }
ControlledOnInt関数
上記コードではControlledOnInt関数を使いました。
例えば、以下は量子ビットq1, q2, q3が全て状態|1>のとき量子ビットq4にゲートXを作用させます。
(ControlledOnInt(1, X))([q1, q2, q3], q4);
改良版 (2019/3/31追記)
もっと簡単にできました。ポイントは、状態を識別するための量子ビットを確保して、最後に確保した量子ビットを元に戻すことです。 こちらの記事を参考にさせていただきました。 Microsoft Q# Coding Contest - Winter 2019 - その2 - 純粋関数型雑記帳
operation TwoBitstringSuperposition (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Unit { using (indicator = Qubit()) { H(indicator); for (i in 0..Length(qs)-1) { if (bits1[i]) { (ControlledOnInt(0, X))([indicator], qs[i]); } if (bits2[i]) { (ControlledOnInt(1, X))([indicator], qs[i]); } } (ControlledOnBitString(bits2, X))(qs, indicator); } }