このページの本文へ

前へ 1 2 次へ

量子シミュレーターで「量子もつれ」を作って観測してみよう

はじめよう「Q#」で量子コンピューティング

2018年01月12日 08時00分更新

文● 廣瀬一海 編集 ● 羽野/TECH.ASCII.jp

  • この記事をはてなブックマークに追加
  • 本文印刷

2.1 初めての量子Hello World

 環境が準備できたので、今度は自分でプロジェクトを作成して、Writing a Quantum Programを参考に、量子コンピューティングにおけるHello Worldである「量子もつれ状態」を作ってみたいと思います。今回は触れませんが、量子もつれ状態を利用して、量子テレポーテーションなど量子コンピュータ特有のタスクが実行できます。

 その前に、ここからの操作で登場する量子力学の概念を、簡単におさらいしておきましょう(太字のところは後の操作で出てきます)。

 量子コンピューティングでは、同時に0と1の状態(重ね合わせ状態)を持つ「量子ビット(Qubit)」で計算を行います。2個以上のQubitに対し、重ね合わせを利用して作成された特殊な相関状態を「量子もつれ(エンタングルメント)」と呼びます。量子もつれ状態と呼ばれるものはたくさんありますが、とくに量子コンピューティングで用いられる状態が「Bell states(ベル状態)」と呼ばれるものです。

 重ね合わせ状態を含む各Qubitの状態は、MRIなどの核磁気の説明で利用される3次元の単位球内の座標(X,Y,Z)で表現することができます。Qubitの3次元ベクトルの方向を操作するのが「量子ゲート」であり、X軸またはZ軸を180度回転させる「回転ゲート」、Z軸とX軸の間の軸を中心に180度回転させる「アダマールゲート」、2つのゲートで条件分岐する「制御NOTゲート(CNOTゲート)」などがあります。

 量子ゲート方式の量子コンピューティングは、Qubitの状態を観測し、量子ゲートを通すことによってQubitの状態をコントロールする技術です。そしてQ#は、Qubitを操作・測定し、観測結果を得るための言語です。

 量子の重ね合わせ状態や量子ゲートについてはIBMのサイトで図解されているので、詳しく理解したい方はこちらをお読みください。

2.2 プロジェクトの作成

 右のソリューションエクスプローラーから一番上のソリューションを右クリックし、Add > New Projectをクリックします。追加するプロジェクトの選択が出てきますので、Q# Applicationを選択し、プロジェクトの名前を指定します。ここでは、Bellという名称のプロジェクトを作成しました。

 プロジェクトには、C#言語で記述された「Driver.cs」と、Q#言語で記述された「Operation.qs」が追加されています。Driver.csは、QuantumSimulatorでOperation.qsを操作、表示するエントリポイントが記述されたコードであり、本体はOperation.qsです。

 わかりやすいように、Operation.qsを右クリックして、Renameを選択し、Bell.qsに名前の変更をしましょう。

2.3 まずは1個の量子をセットしてみましょう

 作成されたBell.qsを編集をしましょう。Q#では、このoperationとBodyの中にコードを記述します。operationは、今までのオブジェクト指向言語におけるstaticメソッドと同じようなものです。

 以下は、Qubitその1(q1)が期待した状態(desired)ではない場合、Qubit状態を反転させる初期化コードです。M()operationによって、Qubit1個の現在の量子ビット状態を測定し、currentに結果を格納します。次のifで、q1がdesiredではない場合は、回転ゲートによってQubitのX軸を反転しています。


namespace Quantum.Bell
{
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;
    operation Set (desired: Result, q1: Qubit) : ()
    {
      body
      {
          let current = M(q1); // 1個のQubitの量子ビット測定
          if (desired != current)
          {
                  // 回転ゲートによってQubitのX軸を反転
                  X(q1);
          }
        }
      }
}

2.4 2個の量子で重ね合わせ状態を作りましょう

 次に2つのQubitで量子もつれの状態をつくり、測定を行います。namespace Quantum.Bellにあるoperation Setの次のオペレーションとして、以下のコードを追記しましょう。

 ここでは、まず、usingで2つのQubitを使うことを宣言し、引数で渡されたcountの数だけループを行い測定を行います。ループの中では、1つのQubitを「0」に初期化(Qubit0)、もう1つのQubitは引数から投入される初期値で初期化します(Qubit1)。

 その後、Qubit0はアダマールゲートによって、0と1の状態を取る確率が等しい量子ビットを生成します。この状態が重ね合わせ状態です。この重ね合わせ状態のQubit0とQubit1を制御NOT演算します。最後に、指定された試行回数(ループ)が終わったら、結果をTupleで返却しています。


operation BellTest (count : Int, initial: Result) : (Int,Int,Int)
{
    body
    {
      mutable numOnes = 0;
      mutable agree = 0;
      using (qubits = Qubit[2])
      {
        for (test in 1..count)
        {
          // 量子ビットを1つは0に初期化、もう1つは引数から投入される初期値
          Set (initial, qubits[0]);
          Set (Zero, qubits[1]);
          // アダマールゲートで重ね合わせ状態へ
          H(qubits[0]);
          // 制御NOTゲートで2つの量子ビットをNOT演算
          CNOT(qubits[0],qubits[1]);
          // NOT演算後のqubits[0]を測定
          let res = M(qubits[0]);
          // 2つの量子ビットの測定結果がマッチしたらagreeをカウントアップ
          if (M(qubits[1]) == res) 
          {
            set agree = agree + 1;
          }
          // 何回1を観測できたかをカウントしている
          {
            set numOnes = numOnes + 1;
          }
        }
        // リセット
        Set(Zero, qubits[0]);
        Set(Zero, qubits[1]);
      }
    // NumZero|0>とNumOne|1>をそれぞれ何回測定できたかを返却する
    return (count-numOnes, numOnes, agree);
    }
}

2.5 実行してみましょう

 ここまで出来たら、ドライバから呼び出します。C#側のシミュレーター(Driver.cs)のインスタンスを作成し、初期化した後にループカウントを1000回、Result.Zeroを初期値にした場合とResult.Oneを初期値にした場合のそれぞれでループします。


using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace Quantum.Bell
{
    class Driver
    {
     static void Main(string[] args)
     {
       using (var sim = new QuantumSimulator())
       {
         // Try initial values
         Result[] initials = new Result[] { Result.Zero, Result.One };
         foreach (Result initial in initials)
         {
           var res = BellTest.Run(sim, 1000, initial).Result;
           var (numZeros, numOnes, agree) = res;
           System.Console.WriteLine(
             $"Init:{initial,-4} 0s={numZeros,-4} 1s={numOnes,-4} agree={agree,-4}");
         }
       }
       System.Console.WriteLine("Press any key to continue...");
       System.Console.ReadKey();
     }
   }
}

 さて、どのような結果が得られたでしょうか?片方の量子ビットQubit0は0と1の中間の状態にあり、それをNOT演算したわけですから、結果は、統計的にみて半分は0で半分は1を得ることになります。

量子もつれ状態観測の実行結果

まとめ

 今回は、量子コンピュータの測定器をコントロールするQ#の操作について簡単に説明してきました。他にもoperation以外のセクションや定義などがありますが、これらのQ#文法についてはQ# language referenceを参考にしてください。

 今までのノイマン型コンピュータと異なるアーキティクチャと考えを持つ量子コンピューティングは、これから発展するであろう技術です。ぜひ、この記事を参考に、新しい量子コンピュータの世界を体験してください。

前へ 1 2 次へ

カテゴリートップへ

  • 角川アスキー総合研究所
  • アスキーカード