FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

量子プログラミング言語Q#の勉強 (5. 2量子ビットのSWAPを書いてみる)

量子プログラミング言語 Q# を使って量子コンピュータについて勉強しようプロジェクト、量子コンピュータの論理演算の仕組みが少しずつ分かってきたので、次は自分でプログラムを書いてみたい。

幸いなことに、前回の記事にて、2つの量子ビットの状態を入れ替える、というSWAPという操作を勉強した。

2つの量子ビットa, bに対して、SWAP(a, b) を実行して量子ビットの入れ替えを行うためには、 a, b に対してCNOTを3回適用することになる。

f:id:msyksphinz:20180218224051p:plain
図. 量子コンピュータにおける量子ビットa, bを交換するのには、CNOTゲートを量子ビットa, bに対して3回適用すればよい。

これをQ#で実装するとどのようになるのだろうか?

2量子ビットのSWAPをQ#で書いてみる

Q# コードを記述する

CNOTを3回適用すればよいのだから、

とする。CNOTを3回書いて、以下のように記述した。

  • quantum_swap.qs
    operation QuantumSwap(qbit0 : Result, qbit1 : Result) : (Result, Result)
    {
        body
        {
            mutable qresult = (Zero, Zero);
            // mutable result = (0, 0);
            using (register = Qubit[2])
            {
                Set(qbit0, register[0]);
                Set(qbit1, register[1]);

                CNOT(register[0], register[1]);
                CNOT(register[1], register[0]);
                CNOT(register[0], register[1]);

                set qresult = (M(register[0]), M(register[1]));
                ResetAll(register);
            }
            return qresult;
        }
    }

ちなみに、Setは以下のように記述している。qbitという確定したデータを量子ビットに格納する関数だ。

 operation Set(desired: Result, q1: Qubit) : ()
    {
        body
        {
            let current = M(q1);
            if (desired != current)
            {
                X(q1);
            }
        }
    }

Driverを記述する

Driverは2つの量子ビットの初期状態を8回ランダムに生成する。こちらはC#のコードだ。 入力量子ビットの状態、出力量子ビットの位置が逆転していれば成功だ。

  • Driver.cs
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
using System.Linq;

namespace Quantum.quantum_swap
{
    class Driver
    {
        static void Main(string[] args)
        {
            var sim = new QuantumSimulator();
            var rand = new System.Random();

            foreach (var idxRun in Enumerable.Range(0, 8))
            {
                Result[] initials = new Result[2];
                initials[0] = (rand.Next(2) == 0) ? Result.Zero : Result.One;
                initials[1] = (rand.Next(2) == 0) ? Result.Zero : Result.One;

                Result[] received = new Result[2];
                (received[0], received[1]) = QuantumSwap.Run(sim, initials[0], initials[1]).Result;

                System.Console.WriteLine($"Round {idxRun} Sent : {initials[1]}, {initials[0]}.");
                System.Console.WriteLine($"Result : \t{received[1]}, {received[0]}");

                if (initials[0] == received[1] && initials[1] == received[0]) {
                    System.Console.WriteLine("Quantum Swap Successful!!\n");
                } else
                {
                    System.Console.WriteLine("Quantum Swap Fail...\n");
                }
            }

            System.Console.WriteLine("\n\nPress Enter to exit...\n\n");
            System.Console.ReadLine();
        }
    }
}

実行結果

試行錯誤の上で、コンパイルして実行してみた。 実行結果は以下のようになった。ちゃんとSwapされている。成功だ!

今度は、もう少し複雑なプログラムを実行してみたい。

f:id:msyksphinz:20180218224633p:plain
図. 量子ビットを交換するプログラムをQ#で記述した結果。ちゃんと2つの量子ビットの値が交換されている。

関連記事