Q# を使用してテレポーテーションを作成する
前のユニットでは、量子テレポート プロトコルの手順を確認しました。 今度は、Alice と Bob の量子テレポーテーション実験を手助けする番です。
このユニットでは、量子テレポート プロトコルを使用して量子ビットの状態を Alice から Bob に送信する量子テレポート プログラムを Q# で作成します。
Q# で量子テレポーテーション プログラムを作成する
- Visual Studio Code を開きます。
- [ファイル] > [新しいテキスト ファイル] の順に選択し、ファイルを Main.qs として保存します。
- [表示] -> [コマンド パレット] を選択し、「Q#: Azure Quantum QIR target プロファイルを設定する」と入力します。 Enter キーを押します。
- [Q#: 無制限] を選択します。
必要なライブラリをインポートする
最初に、Q# の演算と関数を使用するために必要なライブラリをインポートする必要があります。 次のコードをコピーし、Main.qs ファイルに貼り付けます。
import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*;
import Microsoft.Quantum.Intrinsic.*; // Aka Std.Intrinsic.*;
import Microsoft.Quantum.Measurement.*; // Aka Std.Measurement.*;
Teleport
演算を定義する
まず、量子テレポーテーション プロトコルを実装する Teleport
演算を定義する必要があります。 この演算は、2 つの量子ビットを入力として受け取ります。テレポートされる量子状態を含む message
量子ビットと、その状態を受け取る bob
量子ビットです。
operation Teleport(message : Qubit, bob : Qubit) : Unit {
// Allocate an alice qubit.
use alice = Qubit();
// Create some entanglement that we can use to send our message.
H(alice);
CNOT(alice, bob);
// Encode the message into the entangled pair.
CNOT(message, alice);
H(message);
// Measure the qubits to extract the classical data we need to decode
// the message by applying the corrections on the bob qubit
// accordingly.
if M(message) == One {
Z(bob);
}
if M(alice) == One {
X(bob);
}
// Reset alice qubit before releasing.
Reset(alice);
}
以下で Teleport
演算を詳しく見ていきましょう。
この演算は、
alice
量子ビットを使用して、alice
とbob
の量子ビットの間にエンタングルメントを作成します。 その後、message
量子ビットはalice
量子ビットとのエンタングル状態になるため、この 2 つの量子ビットはbob
量子ビットとのエンタングル状態となり、message
がエンコードされます。次に、ベル基底で
alice
とmessage
の量子ビットを測定する必要があります。 どうすればベル基底での測定を Q# で表現できるでしょうか? できません。 少なくとも直接的にはできません。 Q# にはM
演算が存在し、これは $Z$ 基底あるいは計算基底で測定を実行します。 そのため、M
演算を正しく使用するには、ベル状態を計算基底状態に変換する必要があります。 これを行うには、message
量子ビットにH
演算を適用します。 次の表は、ベル状態と計算基底状態の対応関係を示しています。ベルの状態 計算基底状態 $\ket{\phi^+}$ $\ket{00}$ $\ket{\phi^-}$ $\ket{01}$ $\ket{\psi^+}$ $\ket{10}$ $\ket{\psi^-}$ $\ket{11}$ ヒント
最初の量子ビットにアダマール演算を適用した後のベル状態と計算基底状態の等価性を確認することは良い演習となります。 がんばってください。
最後に、
if
ステートメントは測定結果をチェックし、それに応じてbob
量子ビットに修正を適用します。message
量子ビットをOne
で測定する場合は、Z ゲートをbob
量子ビットに適用します。alice
量子ビットもOne
で測定する場合は、bob
量子ビットに X ゲートを適用します。
SetToPlus
および SetToMinus
演算を定義する
|0⟩、|1⟩、|+⟩、|−⟩ などのさまざまな状態の量子ビットをテレポートしたい場合は、初期状態を定義する必要があります。 量子ビットをテレポートする Teleport
演算は既に存在しますが、テレポートする前に、量子ビットを正しい状態に準備する必要があります。
|0⟩ 状態の量子ビットをそれぞれ |+⟩ と |−⟩ に設定する SetToPlus
と SetToMinus
という 2 つの演算をさらに定義する必要があります。
/// Sets a qubit in state |0⟩ to |+⟩.
operation SetToPlus(q : Qubit) : Unit is Adj + Ctl {
H(q);
}
/// Sets a qubit in state |0⟩ to |−⟩.
operation SetToMinus(q : Qubit) : Unit is Adj + Ctl {
X(q);
H(q);
}
Main
演算を定義する
すべての Q# プログラムには、プログラムのエントリ ポイントとして機能する Main
演算が必要です。 Main
演算は、さまざまな量子状態 ($\ket{{0}$、$\ket{1}$、$\ket{+}$、$\ket{-}$) に対してテレポート プロトコルを実行します。
以下で Main
演算を詳しく見ていきましょう。
- この演算では、
message
とbob
の 2 つの量子ビットを割り当てます。 - 量子状態、その状態で量子ビットを初期化するために必要な初期化子演算、テレポートの基準を含むタプルの一覧を定義します。 初期化子演算は、$\ket{0}$ の場合は
I
、$\ket{1}$ の場合はX
、$\ket{+}$ の場合はSetToPlus
、$\ket{-}$ の場合はSetToMinus
です。SetToPlus
およびSetToMinus
演算は、前の手順で定義されています。 - この操作では、タプルの一覧を反復処理し、対応する状態の
message
量子ビットを初期化し、DumpMachine
を使用して状態を表示します。 次に、前の手順で定義したTeleport
演算を使用して、message
量子ビットの状態をbob
量子ビットにテレポートします。 - 状態をテレポートした後、この演算は、対応する基準で
bob
量子ビットを測定し、量子ビットをリセットして、さらに別のメッセージのテレポートを続行します。 - 最後に、この演算は各テレポートの測定結果を返します。
operation Main() : Result[] {
// Allocate the message and bob qubits.
use (message, bob) = (Qubit(), Qubit());
// Use the `Teleport` operation to send different quantum states.
let stateInitializerBasisTuples = [
("|0〉", I, PauliZ),
("|1〉", X, PauliZ),
("|+〉", SetToPlus, PauliX),
("|-〉", SetToMinus, PauliX)
];
mutable results = [];
for (state, initializer, basis) in stateInitializerBasisTuples {
// Initialize the message and show its state using the `DumpMachine`
// function.
initializer(message);
Message($"Teleporting state {state}");
DumpMachine();
// Teleport the message and show the quantum state after
// teleportation.
Teleport(message, bob);
Message($"Received state {state}");
DumpMachine();
// Measure bob in the corresponding basis and reset the qubits to
// continue teleporting more messages.
let result = Measure([basis], [bob]);
set results += [result];
ResetAll([message, bob]);
}
return results;
}
プログラムの実行
これで量子テレポーテーション プログラムの準備ができました。 プログラムを実行して、さまざまな量子状態に対して量子テレポーテーションがどのように機能するかを確認できます。 このプログラムは、message
量子ビットをさまざまな状態に初期化し、その状態を bob
量子ビットへテレポートします。
次のコードには、Teleport
演算、SetToPlus
および SetToMinus
演算、そしてさまざまな量子状態に対してテレポーテーション プロトコルを実行する Main
演算が含まれています。
Main.qs ファイルは次のようになります。
/// This Q# program implements quantum teleportation. import Microsoft.Quantum.Diagnostics.*; import Microsoft.Quantum.Intrinsic.*; import Microsoft.Quantum.Measurement.*; operation Main() : Result[] { // Allocate the message and bob qubits. use (message, bob) = (Qubit(), Qubit()); // Use the `Teleport` operation to send different quantum states. let stateInitializerBasisTuples = [ ("|0〉", I, PauliZ), ("|1〉", X, PauliZ), ("|+〉", SetToPlus, PauliX), ("|-〉", SetToMinus, PauliX) ]; mutable results = []; for (state, initializer, basis) in stateInitializerBasisTuples { // Initialize the message and show its state using the `DumpMachine` // function. initializer(message); Message($"Teleporting state {state}"); DumpMachine(); // Teleport the message and show the quantum state after // teleportation. Teleport(message, bob); Message($"Received state {state}"); DumpMachine(); // Measure bob in the corresponding basis and reset the qubits to // continue teleporting more messages. let result = Measure([basis], [bob]); set results += [result]; ResetAll([message, bob]); } return results; } /// # Summary /// Sends the state of one qubit to a bob qubit by using teleportation. /// /// Notice that after calling Teleport, the state of `message` is collapsed. /// /// # Input /// ## message /// A qubit whose state we wish to send. /// ## bob /// A qubit initially in the |0〉 state that we want to send /// the state of message to. operation Teleport(message : Qubit, bob : Qubit) : Unit { // Allocate an alice qubit. use alice = Qubit(); // Create some entanglement that we can use to send our message. H(alice); CNOT(alice, bob); // Encode the message into the entangled pair. CNOT(message, alice); H(message); // Measure the qubits to extract the classical data we need to decode // the message by applying the corrections on the bob qubit // accordingly. if M(message) == One { Z(bob); } if M(alice) == One { X(bob); } // Reset alice qubit before releasing. Reset(alice); } /// # Summary /// Sets a qubit in state |0⟩ to |+⟩. operation SetToPlus(q : Qubit) : Unit is Adj + Ctl { H(q); } /// # Summary /// Sets a qubit in state |0⟩ to |−⟩. operation SetToMinus(q : Qubit) : Unit is Adj + Ctl { X(q); H(q); }
組み込みのシミュレーターでプログラムを実行するには、
Main
演算の上の [実行] をクリックするか、Ctrl+F5 キーを押します。 出力がデバッグ コンソールに表示されます。受信した状態がテレポートしている状態と一致することを確認します。 次に例を示します。
Teleporting state |0〉 DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |00⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000 Received state |0〉