Q# ハンズオン 第1回

はじめに

問題0と問題1はどちらも量子テレポーテーションを扱った問題です。問題0はQuantum Development Kitにある手順そのままであり、問題1もMSDNブログに記載がある問題です。当日参加者の方に聞きながらどちらをやるか決めます。もしくは問題2をやらずに問題0と1をやるかもしれません。

問題の解答はそれぞれ Problem0 Problem1 Problem2 に置いてあります。 フィードバックはGitHubのissueにお願いします。

参考資料

本家ドキュメント 日本語でまとめた資料 - Q#基礎 ver1.1

問題0 Bell state

参照: Quickstart - your first quantum program

次のようにBell状態を使った測定を行うQ#プロジェクトを作成してください。

問題1 量子テレポーテーション

Microsoftのブログを参考に量子テレポーテーションをQ#プロジェクトとして実装してください。

実装するプロジェクトの詳細

ヒント

C#から呼ぶQ#のオペレーションは次のような定義になります。このオペレーションの中で送信用のQubitと受信用のQubitそれぞれ1個ずつを生成してみましょう。

operation TeleportClassicalMessage(message : Bool) : Bool 

さらにそれぞれのQubit間でテレポーテーションするOperationとして次のOperationを定義してみましょう。このOperationの中では、エンタングルするためにさらに1個のQubitが必要になります。

operation Teleport(msg : Qubit, there : Qubit) : Unit

問題2 Q# Conding Contestの問題C2の回答を検証する

問題の詳細

Q# Conding Contestの問題C2を実際に実行して確認するプロジェクトをつくってみよう。

問題C2であるSolveメソッドは次のフォーマットをしています、

operation Solve (q : Qubit) : Int

q|0>または|+>状態の量子ビットを渡すたとき、|0>であれば0を返し、|+>であれば1を返し、検知不能の場合は-1を返します。さらに10000回実行したときに次の条件も満たしています。

そこでこの問題ではこのSolveメソッドの解答が正しく動作しているか検証するプロジェクトを作成します。 C#からはSolveメソッドを実行する回数(偶数)を渡します。 Q#のコードでは、指定された回数のうち半分は|0>を生成してSolveメソッドを実行します。 残り半分は|1>を生成してSolveメソッドを実行します。Solveメソッドの結果を集計して次の4つの値をC#に返します。C#コードはこの結果を表示します。

Solveメソッドの実装はこのページの一番下にあります。自分で解いてみたい方はそのまま解いてみるか、下のヒントを参考にしてみてください。

C2を解く場合のヒント

両方確実に検出することは不可能なので、|0>だった場合に|0>を確実に検出しそれ以外の場合は-1を返すパターンと、|+>だった場合に|+>を確実に検出しそれ以外の場合に-1を返すパターンの2パターンを用意し、それぞれ50%の確率的に実行することにします。 とんち的な問題ですが、これにより目的を達成できます。 |0>であることは、M(q)による測定結果が1であることで検出できます。 |+>であることは、Hadamard変換した後にM(q)による測定結果が1であることで検出できます。

Q# 全般のヒント (適宜追加予定)

発展(時間が余ったら)

QuantumKatasをやってみましょう。 (今日の最後に簡単に紹介する予定です)

問題2で出てくるCoding Contest C2の解答

operation Solve (q : Qubit) : Int 
{
    mutable output = 0;
    let basis = RandomInt(2);
    
    if (basis == 0) 
    {
        //三項演算子を使うとこう書ける
        set output = M(q) == One ? 1 | -1;

        //三項演算子を書き下すならこんな感じ
        // let result = M(q);
        // if (result == One) 
        // {
        //     set output = 1;
        // }
        // else 
        // {
        //     set output = -1;
        // }
    }
    else 
    {
        H(q);
        set output = M(q) == One ? 0 | -1;
        // let result = M(q);
        // if (result == One)
        // {
        //     set output = 0;
        // }
        // else 
        // {
        //     set output = -1;
        // }
    }
    
    return output;
}