FPGA開発日記

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

Googleの量子コンピュータフレームワークCirqを使ってみる(3. Cirqのチュートリアルを試す)

量子コンピュータの勉強を続けており、Cirqの資料をひたすら読み進めている。

以下の資料を読みながら勉強中である。

  • Cir: Tutorial

Tutorial — Cirq 0.1 documentation

Cirqのチュートリアルは以下に日本語訳と解説がなされており、非常にありがたい。

qiita.com

波動方程式を作ってシミュレーションを行うチュートリアルが紹介されているのだが、量子力学における状態ベクトルの数学的な要素について分かっていないのでいろいろ資料を読みながら進めている。 これは一度しっかり量子力学の本を買った方が良いのだろうか。。。?

f:id:msyksphinz:20180926011313p:plain
図. Cirqで作成される量子回路の概念図 (https://cirq.readthedocs.io/en/latest/tutorial.html#background-variational-quantum-algorithms より抜粋)

固有値 - Wikipedia

上記のCirqの例では、イジングモデルを作成し、まずは量子ビット間の関係を示す$jr$, $jc$をランダムに決める。 その値に従って量子ビットに対してXゲートを適用している。

つまり、ランダムなので最初の量子回路の形は毎回異なるらしい。なんだ。

  • 1回目
transverse fields: [[-1, 1, -1], [-1, -1, -1], [-1, -1, -1]]
row j fields: [[-1, -1, -1], [1, 1, -1]]
column j fields: [[-1, 1], [-1, -1], [1, 1]]
(0, 0): ───X^0.1───X───────@───────X───────────────────────────────────────────────────────────────────────M('x')───
                           │                                                                               │
(0, 1): ───X^0.1───Z^0.2───┼───────X───@───────X───────────────────────────────────────────@───────────────M────────
                           │           │                                                   │               │
(0, 2): ───X^0.1───────────┼───────────┼───────X───@───────X───────────────────────────────@^0.3───────────M────────
                           │           │           │                                                       │
(1, 0): ───X^0.1───X───────@^0.3───X───┼───────────┼───────────@───────────────────────────────────────────M────────
                                       │           │           │                                           │
(1, 1): ───X^0.1───────────────────X───@^0.3───X───┼───────────┼───────@───────────────────────────────────M────────
                                                   │           │       │                                   │
(1, 2): ───X^0.1───────────────────────────────X───@^0.3───X───┼───────┼───────X───@───────X───────────────M────────
                                                               │       │           │                       │
(2, 0): ───X^0.1───────────────────────────────────────────────@^0.3───┼───────────┼───────@───────────────M────────
                                                                       │           │       │               │
(2, 1): ───X^0.1───────────────────────────────────────────────────────@^0.3───────┼───────@^0.3───@───────M────────
                                                                                   │               │       │
(2, 2): ───X^0.1───────────────────────────────────────────────────────────────X───@^0.3───X───────@^0.3───M────────
  • 2回目
transverse fields: [[1, 1, -1], [1, 1, -1], [1, -1, -1]]
row j fields: [[1, -1, 1], [1, 1, -1]]
column j fields: [[1, -1], [-1, 1], [-1, 1]]
(0, 0): ───X^0.1───Z^0.2───@───────────────────────────────────────────────────────────@───────────────M('x')───
                           │                                                           │               │
(0, 1): ───X^0.1───Z^0.2───┼───────X───@───────X───────────────────────────────────────@^0.3───────────M────────
                           │           │                                                               │
(0, 2): ───X^0.1───────────┼───────────┼───────────@───────────────────────────────────────────────────M────────
                           │           │           │                                                   │
(1, 0): ───X^0.1───Z^0.2───@^0.3───────┼───────────┼───────@───────────────────────────────────────────M────────
                                       │           │       │                                           │
(1, 1): ───X^0.1───Z^0.2───X───────────@^0.3───X───┼───────┼───────@───────────────────────────@───────M────────
                                                   │       │       │                           │       │
(1, 2): ───X^0.1───────────────────────────────────@^0.3───┼───────┼───────X───@───────X───────@^0.3───M────────
                                                           │       │           │                       │
(2, 0): ───X^0.1───Z^0.2───────────────────────────────────@^0.3───┼───────────┼───────────────────────M────────
                                                                   │           │                       │
(2, 1): ───X^0.1───────────────────────────────────────────────────@^0.3───────┼───────────────@───────M────────
                                                                               │               │       │
(2, 2): ───X^0.1───────────────────────────────────────────────────X───────────@^0.3───X───────@^0.3───M────────

最終的にシミュレーションを行っているのだが、これはまだ何をやっているのか良く分かっていない。。。

CirqでのQubitsの表現

CirqでのQubitsの表現はどのようになっているのだろう? Cirqの実装を探ってみた。on()という関数で量子ビットに演算が適用されるのだが、そのあと具体的にどのように演算が適用されるのかが分からない。。。

  • Cirq/cirq/devices/grid_qubit.py
class GridQubit(QubitId):
    """A qubit on a 2d square lattice.

    GridQubits use row-major ordering:

        GridQubit(0, 0) < GridQubit(0, 1) < GridQubit(1, 0) < GridQubit(1, 1)
    """

    def __init__(self, row, col):
        self.row = row
        self.col = col
...
  • Cirq/cirq/ops/common_gates.py
class CNotGate(eigen_gate.EigenGate,
               gate_features.TextDiagrammable,
               gate_features.CompositeGate,
               gate_features.TwoQubitGate,
               gate_features.QasmConvertibleGate):
    """When applying CNOT (controlled-not) to QuBits, you can either use
    positional arguments CNOT(q1, q2), where q2 is toggled when q1 is on,
    or named arguments CNOT(control=q1, target=q2).
    (Mixing the two is not permitted.)"""
...
    def on(self, *args: raw_types.QubitId,
           **kwargs: raw_types.QubitId) -> gate_operation.GateOperation:
        if not kwargs:
            return super().on(*args)
        if not args and set(kwargs.keys()) == {'control', 'target'}:
            return super().on(kwargs['control'], kwargs['target'])
        raise ValueError(
            "Expected two positional argument or else 'target' AND 'control' "
            "keyword arguments. But got args={!r}, kwargs={!r}.".format(
                args, kwargs))