Q#のQuickstartをやってみた

docs.microsoft.com

ファイル構成

  • Bell.qs デバイス側のQ#プログラム。量子ビット(Qubit)に対する操作(operation)を記述。
  • Driver.cs ホスト側のC#プログラム。デバイス側のoperationを呼ぶ。

Bell.qs

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

    // q1を状態desiredにセットする
    operation Set (desired: Result, q1: Qubit) : Unit {
        // q1の状態を測定(Measurement)
        let current = M(q1);

        if (desired != current) {
          // セットしたい状態と異なる状態ならば反転
          X(q1);
        }
    }

    // countは測定回数。initialはqubits[0]の初期状態。
    operation BellTest (count: Int, initial: Result) : (Int, Int, Int) {
      mutable numOnes = 0;
      mutable agree = 0;
      // 2個のQubitを使う
      using (qubits = Qubit[2]) {
        for (test in 1..count) {
          // qubits[0]を状態initialにセット
          Set(initial, qubits[0]);
          // qubits[1]を|0>にセット
          Set(Zero, qubits[1]);

          // Hはアダマールゲート?
          H(qubits[0]);
          // CNOTゲート?
          CNOT(qubits[0], qubits[1]);
          let res = M(qubits[0]);

          if (M(qubits[1]) == res) {
            set agree = agree + 1;
          }

          // Count the number of ones we saw:
          if (res == One) {
            set numOnes = numOnes + 1;
          }
        }
        Set(Zero, qubits[0]);
        Set(Zero, qubits[1]);
      }

      // Return number of times we saw a |0> and number of times we saw a |1>
      return (count - numOnes, numOnes, agree);
    }
}

Driver.cs

using System;

using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;

namespace Bell
{
    class Driver
    {
        static void Main(string[] args)
        {
            using (var qsim = new QuantumSimulator())
            {
              // Try initial values
              Result[] initials = new Result[] { Result.Zero, Result.One };
              foreach (Result initial in initials) {
                var res = BellTest.Run(qsim, 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...");
            Console.ReadKey();
        }
    }
}

実行

$ dotnet run
Init:Zero 0s=508  1s=492  agree=1000
Init:One  0s=470  1s=530  agree=1000
Press any key to continue...

やっていることは、たぶん以下だと思う。

  • 量子ビットを2つ(qubits[0], qubits[1])使う。
  • qubits[0]の初期状態を|0>として、1000回測定した。qubits[0]は|0>が508回、|1>が492回測定された。qubits[0]とqubits[1]は1000回全ての測定で同じ状態だった。
  • qubits[0]の初期状態を|1>として、1000回測定した。qubits[0]は|0>が470回、|1>が530回測定された。qubits[0]とqubits[1]は1000回全ての測定で同じ状態だった。

|0>と|1>の測定回数は実行ごとに変わった。 ゲートHやゲートCNOTが何なのか、不勉強なため、まだわかっていない。

量子コンピューティングのチュートリアル QuantumKatas をやってみようかなぁ。

github.com