はじめての QASM 2.0:量子コンピューターのためのプログラミング言語
はじめに
QASM(kazm と発音)は、量子コンピューターのプログラムを書くための言語です1。この名前は「Quantum Assembly Language(量子アセンブリ言語)」を略したものです。
量子コンピューターの仕組みを理解するために、まず従来のコンピューター(古典コンピューター)との違いを見てみましょう。
従来のコンピューターでは、全ての情報は 0
か 1
のどちらかの値を持つビットで表現されます。例えば、数字の「2」は「10
」(2進数)として表現され、文字の「A」は「01000001
」(ASCII コード)として表現されます。
一方、量子コンピューターでは、量子ビット(qubit)という特殊な状態を使います。量子ビットの不思議な特徴は、0
と 1
を重ね合わせた状態をとることができることです。これは、1つの量子ビットが同時に 0
でも 1
でもある状態になれるということです。
この性質により、量子コンピューターは一度に複数の計算を同時に行うことができ、特定の問題では従来のコンピューターよりもはるかに高速に計算を実行できます。
QASM を使うと、このような量子ビットを操作するプログラムを簡単に書くことができます。量子ビットに対して様々な操作(量子ゲート)を適用し、量子アルゴリズムを実装することができます。例えば、量子ビットの状態を変更したり、複数の量子ビット間で演算を行ったり、量子ビットの状態を測定したりすることができます。
QASM には、2.0 と 3.0 という2つの主要バージョンがあります。
QASM 3.0 は最新バージョンで、ループや関数、古典的な制御構造など、複雑な量子アルゴリズムを開発するための高度な機能が備わっています2。
一方で、QASM 2.0 は基本的な量子操作に焦点を当てた、シンプルで理解しやすいものになっています。そのため、量子プログラミングを学び始める人にとって、QASM 2.0 は最適な入門言語となっています。
このノートでは、量子コンピュータって面白そうだけど、なんだか難しそうかもという人に向けて、量子コンピュータのプログラミング言語 QASM 2.0 の基礎について説明しますね。
QASM 2.0の基本構造
QASM 2.0 プログラムの基本的な構造は次のようになります:
OPENQASM 2.0;
include "qelib1.inc";
// 量子レジスタと古典レジスタの宣言
qreg q[n];
creg c[m];
// 量子操作
// 測定
プリアンブル
QASM 2.0プログラムを書くときは、必ず最初に2つの重要な文(命令)を書く必要があります。これを「標準プリアンブル」と呼びます。プリアンブルとは「前置き」や「序文」という意味で、プログラムの本体に入る前の準備段階として必要な部分です。
この2つの文は、以下のような役割を持っています:
- プログラミング環境を整える:使用するQASMのバージョンを明確にし、プログラムを実行するための基本的な設定を行います。
- 基本的な量子操作を使えるようにする:量子ビットを操作するための基本的な命令(量子ゲート)を読み込みます。
それでは、この標準プリアンブルを構成する2つの文を見ていきましょう:
OPENQASM 2.0;
この行は、私たちのプログラムが「QASM 2.0」というバージョンの言語を使うことを宣言する、とても大切な一行です。
これは、プログラムを書き始める時の「お約束」のようなものです。例えば、日本語の手紙を書くときに「拝啓」から始めるように、QASM 2.0のプログラムは必ずこの宣言から始めます。
include "qelib1.inc";
この文は、量子計算に必要な基本的な道具箱(標準量子ゲートライブラリ「qelib1」)を読み込むための命令です。
これは、料理で言えば「包丁やまな板、フライパンなど、基本的な調理器具一式を用意する」ようなものです。これらの道具がないと、量子プログラムを書くことができません。
これらの量子ゲートの具体的な使い方については、このあとのセクションで1つずつ詳しく説明していきます。
レジスタ宣言
QASM 2.0では、コンピュータのメモリのように情報を保存する場所として「レジスタ」というものを使います。レジスタには2つの種類があります:
量子レジスタ(
qreg
):これは量子コンピュータの「作業場」のようなものです。量子の不思議な性質を使って計算するための特別な場所です。例えば、量子ビットを重ね合わせ状態にしたり、量子ビット同士を絡み合わせたりする操作を行うときに使います。古典レジスタ(
creg
):これは普通のコンピュータのメモリのようなものです。0か1という普通の数字しか保存できませんが、量子計算の結果を記録するのに使います。量子の世界で計算した結果を、私たちが理解できる形で取り出すために必要です。
レジスタを準備することを「宣言」と呼びます。宣言するときは、それぞれのレジスタが何個のビット(情報を入れる箱)を持つのかを指定します。
たとえば、2つの量子ビットを使って計算したい場合は、2つの箱を持つ量子レジスタを用意し、その計算結果を保存するために同じく2つの箱を持つ古典レジスタを用意します。
qreg q[2]; // 2つの量子ビットを格納できるレジスタ
creg c[2]; // 2つの古典ビットを格納できるレジスタ
この例を詳しく見ていきましょう。
qreg q[2]
という宣言は、「2つの量子ビットを入れられる箱を用意して、その箱にq
という名前を付ける」という意味です。これは、例えば本棚に2冊の本を置けるスペースを作るようなものです。
creg c[2]
という宣言は、「2つの普通のビット(0か1のどちらかの値)を入れられる箱を用意して、その箱にc
という名前を付ける」という意味です。これは、紙に2桁の二進数(00、01、10、11のいずれか)を書き込めるスペースを用意するようなものです。この古典レジスタは、主に量子計算の「答え」を記録するために使います。
量子レジスタと古典レジスタは常にペアで使います。なぜなら、量子の世界で計算した結果を、私たちが理解できる普通の数字(0と1)として取り出すには、必ず「測定」という操作が必要で、その測定結果を記録する場所として古典レジスタが必要だからです。
基本的な量子ゲート
量子ゲートとは、量子ビットに対して何らかの変化を与える基本的な操作のことです。古典的なコンピュータでANDやORなどの論理ゲートを組み合わせて計算を行うように、量子コンピュータでは量子ゲートを組み合わせて量子計算を実現します。
これは、例えば料理で言えば「切る」「炒める」「煮る」といった基本的な調理操作のようなものです。これらの基本操作を組み合わせることで、様々な料理を作ることができるように、量子ゲートを組み合わせることで様々な量子計算を実現できます。
QASM 2.0では、いくつかの基本的な量子ゲートが用意されています。これらは、量子コンピュータのプログラムを書くための「基本の道具箱」のようなものです。以下では、特に重要な量子ゲートについて、順番に詳しく説明していきます:
Xゲート(NOTゲート)
Xゲートは、量子ビットの状態を「裏返す」働きをする最も基本的な量子ゲートの1つです。
古典的なコンピュータの世界では、ビットの値を反転させる操作を「NOT」と呼びます。例えば:
- 0を1に変える
- 1を0に変える
Xゲートは、この「NOT」操作の量子版です。量子の世界では:
- 状態
|0⟩
(「0の状態」と読みます)を|1⟩
(「1の状態」)に変える - 状態
|1⟩
を|0⟩
に変える
つまり、量子ビットの状態を完全に「反対」の状態に変換する操作です。これは電気のスイッチをONからOFFに、またはOFFからONに切り替えるようなものだと考えることができます。
このXゲートは1つの量子ビットに対してのみ働く「単一量子ビットゲート」の一種です。QASM 構文では次のように表現されます:
x q[0]
Hゲート(アダマールゲート)
アダマールゲート(Hゲート)は、量子コンピュータで最も重要な基本的な量子ゲートの1つです。このゲートは、量子ビットを「重ね合わせ状態」と呼ばれる特別な状態に変換する働きをします。
簡単に例えると、コインを机の上に置いているとき、表か裏のどちらかの状態になっています。これは量子ビットの|0⟩
(表)や|1⟩
(裏)の状態に似ています。アダマールゲートを適用することは、このコインを机の上で回転させ続けているような状態を作り出すようなものです。この状態では、コインは表でも裏でもない、両方の可能性を同時に持った状態になります。
具体的には:
|0⟩
(表)の状態にアダマールゲートを適用すると、表と裏が同じ確率で出現する状態(|0⟩ + |1⟩)/√2
になります|1⟩
(裏)の状態にアダマールゲートを適用すると、同様に表と裏が同じ確率で出現する状態(|0⟩ - |1⟩)/√2
になります
この「重ね合わせ状態」を作り出す能力は、量子コンピュータの並列計算を可能にする鍵となります。例えば、1つの量子ビットで2つの状態を同時に扱えるため、古典的なコンピュータでは2回必要な計算を1回で行うことができます。
このような特徴により、アダマールゲートは多くの重要な量子アルゴリズムで基礎的な部品として使用されています。QASM構文では次のように表現されます:
h q[0]
CNOTゲート(制御NOTゲート)
CNOTゲート(制御NOTゲート、または制御Xゲート)は、2つの量子ビットを使う特別な量子ゲートです。このゲートは、「もし〜なら〜する」という条件付きの操作を量子の世界で実現します。
簡単な例で説明しましょう。2人の友達がいて、1人目が「手を挙げる」か「手を下げる」かの合図をし、2人目がその合図に応じて行動を変えるような状況を想像してください:
1人目(制御量子ビット)が手を挙げている(
|1⟩
の状態)とき:- → 2人目(ターゲット量子ビット)は自分の状態を反転させます
- 立っていれば座る(
|0⟩
から|1⟩
へ) - 座っていれば立つ(
|1⟩
から|0⟩
へ)
- 立っていれば座る(
- → 2人目(ターゲット量子ビット)は自分の状態を反転させます
1人目が手を下げている(
|0⟩
の状態)とき:- → 2人目は何もせず、そのままの状態を保ちます
このように、CNOTゲートは2つの量子ビットの間に「協力関係」を作り出します。この性質は、量子コンピュータで情報を安全に保護したり(量子エラー訂正)、複雑な計算を行ったりする際の基礎となる重要な操作です。
QASM構文では、このCNOTゲートを次のように書きます:
cx q[0],q[1]
測定
測定は、量子コンピュータの計算結果を私たちが理解できる形で取り出すために必要な操作です。これは、量子の世界から古典的な世界(私たちの日常世界)への「橋渡し」のようなものです。
測定を分かりやすく例えると、次のようなものです:
- サイコロを振って投げる前は、1から6までの目が出る可能性が「重なり合って」います
- サイコロを投げて止まると、1つの目(例えば3)に「決定」します
- 一度サイコロが止まると、それ以前の「可能性の重なり合い」は失われます
量子ビットの測定も同じような性質を持ちます:
- 測定前の量子ビットは、0と1の状態が重なり合っている可能性があります
- 測定すると、必ず0か1のどちらかの値になります
- 例えば、50%の確率で0、50%の確率で1になるような状態を作ることができます
- 測定結果は普通のコンピュータのメモリ(古典レジスタ)に保存されます
- 一度測定すると、元の量子状態には戻れません(不可逆な操作です)
QASMでは、測定は次のように書きます:
measure q[0] -> c[0];
この命令は、量子ビットの状態を私たちが理解できる形で取り出すための重要な操作です。具体的には:
- 量子ビット
q[0]
の状態を観測(測定)します - 測定の結果を古典的なビット
c[0]
に保存します
例えば、量子ビットq[0]
が重ね合わせ状態(0と1が同時に存在する状態)にあるとき:
- 測定すると、確率的にどちらかの状態に「決定」します
- もし0の状態に決定したら →
c[0]
に0が保存されます - もし1の状態に決定したら →
c[0]
に1が保存されます
- もし0の状態に決定したら →
重要なポイントは、一度測定すると元の量子状態には戻れないということです。これは量子力学の基本的な性質の1つです。
カスタムゲート
QASM 2.0では、自分だけの特別な量子ゲートを作ることができます。これを「カスタムゲート」と呼びます。
カスタムゲートは、次のような場合に便利です:
よく使う操作をまとめたい場合
- 例えば、「アダマールゲートの後にCNOTゲートを使う」という組み合わせをよく使うとき
- これを1つの新しいゲートとして定義できます
プログラムを分かりやすくしたい場合
- 複雑な操作に分かりやすい名前をつけることができます
- 例:「ベル状態を作るゲート」という名前をつける
同じ操作を何度も書きたくない場合
- 一度定義したカスタムゲートは、何度でも使い回せます
- コードが短くなり、ミスも減ります
つまり、カスタムゲートは「オリジナルの道具箱」のようなものです。自分が必要な道具(ゲート)を作って、それを何度も使うことができます。
gate mygate a,b {
h a;
cx a,b;
}
mygate q[0],q[1];
この例を詳しく見ていきましょう:
gate mygate a,b { ... }
という形で、新しいゲート「mygate」を定義しています- このゲートは2つの量子ビット(aとb)を受け取ります
- 波括弧{ }の中に、実際の操作を書きます
このゲートは2つの基本的な量子ゲートを組み合わせています:
- アダマールゲート(
h
):量子ビットを重ね合わせ状態にする操作 - CNOTゲート(
cx
):2つの量子ビット間の関係を作る操作
- アダマールゲート(
つまり、このカスタムゲートは「2つの量子ビットを使って特別な状態を作る」ための便利な道具として定義されているのです。これを一度定義しておけば、mygate q[0],q[1];
のように簡単に呼び出すことができます。
QASM 2.0の簡単な例
量子コンピューティングの基本を理解するために、「ベル状態」という特別な量子状態を作って観察するプログラムを見てみましょう。
そもそも、ベル状態とは?
- 2つの量子ビットを使って作る特別な状態です
- この状態では、2つの量子ビットが「もつれ合い」という不思議な関係を持ちます
- 物理学者のJohn Stewart Bellにちなんで名付けられました
ベル状態の面白いところは:
- 2つの量子ビットが完全に協調して動くようになります
- 1つの量子ビットを測定すると、もう1つの状態が瞬時に決まってしまいます
- この現象は、Einsteinも「不思議すぎる!」と驚いたほどです
これから見ていくプログラムでは、最も基本的なベル状態を作ります。数式で書くと(|00⟩ + |11⟩)/√2
という状態です。
それでは、実際のプログラムを見てみましょう:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q -> c;
このプログラムを1行ずつ、初心者にもわかりやすく解説していきましょう:
まずは準備段階です:
OPENQASM 2.0;
これは「このプログラムはQASM 2.0という言語で書きます」という宣言です。前に説明したように、プログラムの最初に必ず書く決まり文句です。
include "qelib1.inc";
これは「量子コンピュータの基本的な命令セットを使います」という宣言です。パソコンで新しいプログラムを書くときに必要な道具箱を開けるようなものです。
次に、作業場所を用意します:
qreg q[2];
2つの量子ビットを用意します。これらはq[0]
とq[1]
という名前で呼び出せます。最初は両方とも0
の状態(|00⟩
と書きます)です。
creg c[2];
2つの古典的なビット(普通のコンピュータのビット)も用意します。これらは後で量子ビットの測定結果を記録するために使います。
いよいよ本番の操作です:
h q[0];
1番目の量子ビット(q[0]
)に「アダマールゲート」という操作を行います。これにより、q[0]
は「0と1が同時に存在する」という不思議な状態になります。具体的には、0である確率50%、1である確率50%の状態です。
cx q[0],q[1];
これは「CNOT(制御NOT)ゲート」という操作です。もしq[0]
が1ならq[1]
を反転させ、0なら何もしないという操作です。この操作により、2つの量子ビットが「もつれ合い」状態になります。
measure q -> c;
最後に、両方の量子ビットを測定して、その結果を古典ビットc
に記録します。
このプログラムを実行すると、面白いことが起こります:
- 測定結果は必ず
00
か11
のどちらかになります - どちらになるかは完全にランダムですが、確率は50-50です
- 決して
01
や10
という結果は出ません
これは「量子もつれ」という現象を示しています。2つの量子ビットが不思議な形で結びつき、片方の状態を測定すると、もう片方の状態が瞬時に決まってしまうのです。Einstein でさえ「この現象は物理法則に反している!」と考えたほど不思議な現象です。
さいごに
以上で QASM 2.0 についての基本的な説明を終わります。ここまでで学んだ内容を簡単におさらいしましょう:
- QASM 2.0 は量子コンピュータのプログラミング言語です
- プログラムの最初には必ず
OPENQASM 2.0
とinclude "qelib1.inc"
を書きます qreg
で量子ビット、creg
で古典ビットを用意します- アダマールゲート(
h
)で量子の重ね合わせ状態を作ります - CNOT ゲート(
cx
)で量子ビット同士を「もつれ合わせる」ことができます measure
で量子ビットの状態を測定し、古典ビットに記録します
これらの基本的な量子ゲートは、レゴブロックのようなものです。一つ一つは単純な操作ですが、これらを組み合わせることで、より複雑で面白い量子アルゴリズムを作ることができます。例えば、量子暗号や量子テレポーテーション、さらには大きな数の素因数分解など、古典的なコンピュータでは難しい計算も実現できるようになります。
付録:QASM 2.0の基本量子ゲート
単一量子ビット操作
Xゲート(ビット反転ゲート)
Xゲートは、量子ビットの状態を「裏返す」最も基本的な量子ゲートの1つです。
古典的なコンピュータでは、ビットの値を反転させる操作を「NOT」と呼びます:
- 0を1に変える
- 1を0に変える
Xゲートは、この「NOT」操作の量子版です。量子の世界では:
- 状態
|0⟩
(「0の状態」と読みます)を|1⟩
(「1の状態」)に変える - 状態
|1⟩
を|0⟩
に変える
これは、例えば電気のスイッチをONからOFFに、またはOFFからONに切り替えるようなものだと考えることができます。
より専門的には、Xゲートは量子力学の「ブロッホ球」というモデルのX軸周りに180度回転させる操作として理解することができます。この操作は数学的には「パウリX行列」という特別な行列で表現されますが、初学者の方は「状態を裏返す」という直感的な理解で十分です。
Xゲートは、量子エラーの訂正や、量子ビット同士を「もつれ合わせる」操作など、様々な量子アルゴリズムの重要な構成要素として使われます。
x q[0]
Yゲート(パウリYゲート)
Yゲートは、量子ビットに対する基本的な操作の1つです。このゲートの動作を理解するために、まず簡単な例から見ていきましょう。
想像してください:量子ビットを小さな矢印だと考えてみましょう。この矢印は3次元空間(ブロッホ球と呼ばれます)の中で回転することができます。Yゲートは、この矢印をY軸(上下の軸)の周りに180度(πラジアン)回転させる操作なのです。
具体的には、Yゲートは以下のような変化を引き起こします:
- 状態
|0⟩
(上向きの矢印)をi|1⟩
(下向きの矢印に、少し特別な性質を加えたもの)に変える - 状態
|1⟩
(下向きの矢印)を-i|0⟩
(上向きの矢印に、別の特別な性質を加えたもの)に変える
ここで出てくるi
と-i
は「虚数」と呼ばれる数学的な概念で、量子ビットの「位相」(波としての性質)を表しています。初めのうちは、これらは「特別な印」程度に考えておいて構いません。
Yゲートの特徴は、以下の2つの効果を同時に持っていることです:
- ビットの値を反転させる(0を1に、1を0に)
- 量子ビットの位相を変える
このような特徴により、Yゲートは他の基本ゲート(XゲートやZゲート)と組み合わせることで、量子ビットをより細かく制御することができます。これは、例えば量子コンピュータでエラーを修正したり、複雑な量子シミュレーションを行ったりする際に重要な役割を果たします。
y q[0]
Zゲート(位相反転ゲート)
Zゲートは、量子ビットの「位相」という特別な性質を変える働きをする基本的な量子ゲートです。
位相とは、量子ビットが持つ波としての性質で、私たちの日常生活では直接目にすることができないものです。例えば、海の波を思い浮かべてみてください。波には「山」と「谷」があり、これを上向き(プラス)と下向き(マイナス)と考えることができます。量子ビットの位相も、このように「プラス」と「マイナス」の性質を持っています。
Zゲートは、量子ビットの状態によって以下のような変化を引き起こします:
- 状態
|0⟩
のときは何も変化しません(そのままの状態を保ちます) - 状態
|1⟩
のときは、位相が反転します(プラスからマイナスに変わります)
これは、例えば次のような状況に似ています:
- 晴れの日(状態
|0⟩
)には何も変化を与えない - 雨の日(状態
|1⟩
)には傘を差す(位相を反転させる)
Zゲートは、直接目に見える変化は起こしませんが、量子コンピュータの計算において非常に重要な役割を果たします。特に:
- 量子ビット同士の干渉(波としての重なり合い)を制御する
- 量子計算の途中で発生するエラーを修正する
- より複雑な量子アルゴリズムの基礎となる
このように、Zゲートは目に見えない量子の世界で、波としての性質を巧みに操る「魔法の杖」のような働きをする重要なゲートなのです。
z q[0]
Hゲート(アダマールゲート)
アダマールゲート(Hゲート)は、量子コンピュータで最も重要な基本的な量子ゲートの1つです。このゲートは、量子ビットを「重ね合わせ状態」と呼ばれる特別な状態に変換する働きをします。
簡単に例えると、コインを机の上に置いているとき、表か裏のどちらかの状態になっています。これは量子ビットの|0⟩
(表)や|1⟩
(裏)の状態に似ています。アダマールゲートを適用することは、このコインを机の上で回転させ続けているような状態を作り出すようなものです。この状態では、コインは表でも裏でもない、両方の可能性を同時に持った状態になります。
具体的には:
|0⟩
(表)の状態にアダマールゲートを適用すると、表と裏が同じ確率で出現する状態(|0⟩ + |1⟩)/√2
になります|1⟩
(裏)の状態にアダマールゲートを適用すると、同様に表と裏が同じ確率で出現する状態(|0⟩ - |1⟩)/√2
になります
この「重ね合わせ状態」を作り出す能力は、量子コンピュータの並列計算を可能にする鍵となります。例えば、1つの量子ビットで2つの状態を同時に扱えるため、古典的なコンピュータでは2回必要な計算を1回で行うことができます。
このような特徴により、アダマールゲートは多くの重要な量子アルゴリズムで基礎的な部品として使用されています。
h q[0]
Tゲート(π/4位相ゲート)
Tゲートは、量子ビットの位相(波としての性質)を微細に調整する特殊な量子ゲートです。このゲートの働きを理解するために、まずは簡単な例で考えてみましょう。
時計の文字盤を想像してください。通常の時計は12時間(360度)で1周します。ここで、その1周を8等分すると、1つの区切りは45度(π/4ラジアン)になります。Tゲートは、量子ビットの位相をちょうどこの45度分だけ回転させる操作なのです。
具体的には:
- 状態
|0⟩
のときは何も変化しません(時計の針が動かないようなもの) - 状態
|1⟩
のときは、位相が45度回転します(時計の針が45度進むようなもの)
このような微細な位相の制御が必要な理由は、量子コンピュータで複雑な計算を行う際に、単純な0と1の切り替え(Xゲート)や180度の位相反転(Zゲート)だけでは不十分だからです。例えば:
- より精密な量子計算を実現する
- 量子コンピュータで発生するエラーを効果的に修正する
- より複雑な量子アルゴリズムを構築する
これは、例えば料理で味付けをする際に、塩を一度に大量に入れるのではなく、少しずつ加えて微調整するようなものです。Tゲートは、量子計算における「繊細な味付け」を可能にする重要なツールなのです。
t q[0]
Sゲート(位相ゲート)
Sゲートは、量子ビットの位相(波としての性質)を90度(π/2ラジアン)回転させる量子ゲートです。このゲートの働きを理解するために、時計の例で考えてみましょう。
先ほどのTゲートが時計の針を45度回転させたのに対し、Sゲートは時計の針を90度(つまり3時間分)回転させます。具体的には:
- 状態
|0⟩
のときは何も変化しません(時計の針が動かないようなもの) - 状態
|1⟩
のときは、位相が90度回転します(時計の針が3時間分進むようなもの)
数学的に表現すると、Sゲートは:
|0⟩
を|0⟩
のまま保ちます|1⟩
をi|1⟩
に変換します(i
は虚数単位で、90度の回転を表します)
Sゲートは、Zゲート(180度回転)の「半分」の回転を行うゲートとも言えます。そのため、Sゲートを2回適用すると、Zゲートと同じ効果が得られます。
このゲートは、例えば音楽の調律のように、量子ビットの位相を「半音」単位で調整するような働きをします。このような精密な位相制御は、より複雑な量子アルゴリズムを構築する際の重要な基礎となります。
s q[0]
RX、RY、RZゲート(回転ゲート)
RX、RY、RZゲートは、量子ビットの状態を3次元空間(ブロッホ球)の中で回転させる基本的な量子ゲートです。これらのゲートを理解するために、まずは身近な例で考えてみましょう。
地球儀を想像してください:
- RXゲート:赤道を軸にして地球儀を回転させるようなもの
- RYゲート:経度0度の線を軸にして回転させるようなもの
- RZゲート:北極から南極を貫く軸で回転させるようなもの
これらのゲートの特徴は、回転の角度θを自由に指定できることです。例えば:
- RXゲート
- θ=0度のとき:何も変化しない
- θ=180度のとき:完全なビット反転(Xゲートと同じ)
- その間の角度:部分的なビット反転
- RYゲート
- 状態|0⟩と|1⟩の間の任意の重ね合わせを作れる
- 例えば、θ=90度で|0⟩と|1⟩が等しい割合の重ね合わせになる
- RZゲート
- 量子ビットの位相を自由に調整できる
- θ=180度でZゲート、θ=90度でSゲート、θ=45度でTゲートと同じ効果
これらのゲートは、例えば料理で火加減を自由に調整するように、量子状態を細かく制御できる道具です。特に:
- 量子シミュレーション:自然界の連続的な変化を模倣する
- 量子最適化:最適な解を徐々に見つけていく といった場面で重要な役割を果たします。
rx(θ) q[0]
U1、U2、U3ゲート(ユニバーサルゲート)
U1、U2、U3ゲートは、量子ビットを自由自在に操作できる「万能の道具」のような量子ゲートです。これらは、まるでロボットアームのように、量子ビットの状態を思い通りの方向に動かすことができます。
- U1ゲート:最もシンプルな操作
- 量子ビットの「位相」だけを変える単純な操作です
- 例えると、時計の針を好きな角度だけ回すようなものです
- パラメータλ(ラムダ)で回転角度を指定します
- U2ゲート:少し複雑な操作
- 2つのパラメータ(φ:ファイ、λ:ラムダ)を使います
- 量子ビットを|0⟩と|1⟩の等しい重ね合わせにした後、位相を調整できます
- 例えると、コインを立てた状態で、特定の方向に傾けるようなものです
- U3ゲート:最も自由度の高い操作
- 3つのパラメータ(θ:シータ、φ:ファイ、λ:ラムダ)を使います
- 量子ビットを完全に自由に操作できます
- 例えると、3D空間で物体を好きな方向に向けられるようなものです
- 実は、他のすべての単一量子ビットゲート(X、H、Sなど)は、U3ゲートの特別な場合として表現できます
これらのゲートは、量子コンピュータのプログラミングにおける「基本文字」のようなものです。アルファベットの文字を組み合わせて様々な単語が作れるように、これらのゲートを組み合わせることで、どんな複雑な量子操作でも実現できます。
特に、U3ゲートは「究極の単一量子ビット操作」と呼べるもので、適切なパラメータを選ぶことで、他のすべての単一量子ビットゲートの動作を真似することができます。U1とU2は、U3の特別なバージョンで、よく使う特定の操作に特化した「便利な省略形」のようなものです。
u3(θ,φ,λ) q[0]
2量子ビット操作
CNOT(CX)ゲート
CNOTゲート(Controlled-NOTゲート、またはCXゲートとも呼ばれます)は、2つの量子ビットを使う最も基本的な量子操作の1つです。
このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)の状態を裏返します - もし制御ビットが
|0⟩
の状態なら、何もしません
これは、例えば以下のような状況に似ています:
- お母さん(制御ビット)が「掃除をして」と言った場合(
|1⟩
の状態)、子供(ターゲットビット)は今やっていることの反対のことをする - お母さんが何も言わない場合(
|0⟩
の状態)、子供は今やっていることを続ける
CNOTゲートの特に重要な性質は、2つの量子ビットを「もつれ合わせる」ことができるという点です。例えば、アダマールゲートの後にCNOTゲートを使うと、2つの量子ビットが不思議な形で結びつき、一方の状態を測定すると必ず他方の状態も決まってしまうような状態(ベル状態)を作ることができます。
このゲートは量子コンピュータの世界での「基本工具」のようなもので、以下のような場面で重要な役割を果たします:
- 量子エラーの検出と訂正
- 複雑な量子計算の実行
- 量子暗号や量子テレポーテーションなどの高度な量子プロトコル
また、CNOTゲートと単一量子ビットのゲート(例:X、H、Tゲートなど)を組み合わせることで、どんな複雑な量子計算でも実現できることが知られています。これは、ちょうど積み木のように、シンプルなパーツを組み合わせて複雑な構造を作れるということです。
cx q[0],q[1];
CZゲート(制御Zゲート)
CZゲート(制御Zゲート)は、2つの量子ビットを使う特別な量子操作です。このゲートは以下のように動作します:
- 制御量子ビットとターゲット量子ビットの2つの量子ビットを使います
- 制御量子ビットが
|1⟩
の状態で、かつターゲット量子ビットも|1⟩
の状態のときだけ、符号(プラスとマイナス)を反転させます - それ以外の場合は何も変化を与えません
簡単な例えで説明すると:
- お母さん(制御ビット)と子供(ターゲットビット)がいて、両方が「はい」(
|1⟩
の状態)と言ったときだけ、子供の気持ちが反転する(プラスからマイナスに変わる)ようなものです - それ以外の場合(お母さんが「いいえ」だったり、子供が「いいえ」だったり)は、何も変化しません
CZゲートの面白い特徴は、どちらの量子ビットを制御用、どちらをターゲット用にしても同じように働くということです。これは、お母さんと子供の役割を入れ替えても同じ結果になるということです。
このゲートは以下のような場面で特に重要です:
- 量子ビット間のもつれ合いを作る
- 量子エラーを見つけて直す
- より複雑な量子操作の部品として使う
また、CZゲートは他のゲートを使って作ることもできます。具体的には、ターゲットの量子ビットの前後にアダマールゲートを置いたCNOTゲートと同じ働きをします。これは、量子回路を設計するときに便利な性質です。
cz q[0],q[1];
CYゲート(制御Yゲート)
CYゲート(制御Yゲート)は、2つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)にYゲート操作を行います - もし制御ビットが
|0⟩
の状態なら、何もしません
簡単な例えで説明すると:
- お母さん(制御ビット)が「はい」(
|1⟩
の状態)と言った場合、子供(ターゲットビット)は特別な方法で状態が変わります - お母さんが「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
Yゲート操作には2つの効果があります:
- ビットの反転:
|0⟩
を|1⟩
に、|1⟩
を|0⟩
に変える(Xゲートと同じ) - 位相の変化:状態に特別な数学的な性質(虚数
i
)を加える
このゲートは以下のような場面で特に重要です:
- 量子ビット間のもつれ合いを作る
- 量子の状態を精密に制御する必要がある計算
- 量子シミュレーションでの特殊な状態の表現
CYゲートは、CNOTゲートやCZゲートの仲間で、量子コンピュータの重要な基本部品の1つとして使われています。
cy q[0],q[1];
CHゲート(制御アダマールゲート)
CHゲートは、2つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)にアダマールゲート操作を行います - もし制御ビットが
|0⟩
の状態なら、何もしません
簡単な例えで説明すると:
- お母さん(制御ビット)が「はい」(
|1⟩
の状態)と言った場合、子供(ターゲットビット)は重ね合わせ状態になります - お母さんが「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
アダマールゲート操作は、量子ビットを重ね合わせ状態にする特別な操作です:
- 状態
|0⟩
を「|0⟩
と|1⟩
が同時に存在する状態」に変える - 状態
|1⟩
を「|0⟩
と|1⟩
が同時に存在するが、|1⟩
の部分が負の符号を持つ状態」に変える
このゲートは以下のような場面で特に重要です:
- 条件付きで量子の重ね合わせ状態を作る
- 量子コンピュータで複雑な計算を行う(量子フーリエ変換など)
- 量子エラーを見つけて直す
CHゲートは、量子コンピュータの重要な基本部品の1つとして、より複雑な量子アルゴリズムを作るために使われています。
ch q[0],q[1];
CU1ゲート(制御U1ゲート)
CU1ゲートは、2つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)に特別な「位相回転」という操作を行います - もし制御ビットが
|0⟩
の状態なら、何もしません
簡単な例えで説明すると:
- お母さん(制御ビット)が「はい」(
|1⟩
の状態)と言った場合、子供(ターゲットビット)は特別な方法で状態が変わります - お母さんが「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
位相回転操作は、量子ビットの状態に特別な「位相」という性質を加える操作です:
- 量子ビットが
|1⟩
の状態のとき、その状態に特別な数学的な性質(位相因子e^(iλ)
)を加えます - 量子ビットが
|0⟩
の状態のときは、何も変化しません
このゲートは以下のような場面で特に重要です:
- 量子コンピュータで複雑な計算を行う(量子フーリエ変換など)
- 量子の状態を精密に制御する必要がある計算
- 量子エラーを見つけて直す
また、CU1ゲートは他の重要な量子ゲート(例:CZゲート)を作るための基本部品としても使われています。
cu1(λ) q[0],q[1];
CU3ゲート(制御U3ゲート)
CU3ゲートは、2つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)に特別な回転操作を行います - もし制御ビットが
|0⟩
の状態なら、何もしません
簡単な例えで説明すると:
- お母さん(制御ビット)が「はい」(
|1⟩
の状態)と言った場合、子供(ターゲットビット)は特別な方法で回転します - お母さんが「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
CU3ゲートの特徴は、3つの数字(θ,φ,λ)を使って回転の仕方を自由に決められることです。これは、例えば地球儀を好きな方向に回すように、量子ビットの状態を好きな方向に回転させることができるということです。
このゲートは、量子コンピュータの「万能工具」のようなものです。適切な数字(θ,φ,λ)を選ぶことで、他のすべての基本的な制御操作(CX、CY、CZ、CH、CU1など)を作ることができます。
CU3ゲートは以下のような場面で特に重要です:
- 量子コンピュータで複雑な計算を行う(量子フーリエ変換など)
- 量子の状態を精密に制御する必要がある計算
- より複雑な量子アルゴリズムの基本部品として
cu3(θ,φ,λ) q[0],q[1];
CRZゲート(制御RZゲート)
CRZゲートは、2つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜なら〜する」という条件付きの操作を行います:
- 1つ目の量子ビット(制御ビット)の状態を確認します
- もし制御ビットが
|1⟩
の状態なら、2つ目の量子ビット(ターゲットビット)に特別な回転操作を行います - もし制御ビットが
|0⟩
の状態なら、何もしません
簡単な例えで説明すると:
- お母さん(制御ビット)が「はい」(
|1⟩
の状態)と言った場合、子供(ターゲットビット)は特別な方法で回転します - お母さんが「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
CRZゲートの「RZ回転」とは、量子ビットの状態を特別な方法で回転させる操作です。これは、例えば地球儀を上から見て、真上を軸にして回すような動きをイメージしてください。回転の角度θ(シータ)を自由に決めることができ、この角度によって回転の量が決まります。
このゲートは以下のような場面で特に重要です:
- 量子コンピュータで精密な計算を行う(量子位相推定など)
- 量子フーリエ変換という特別な計算を実行する
- より複雑な量子アルゴリズムの基本部品として
また、CRZゲートは別の重要な量子ゲート(CU1ゲート)と同じ働きをすることができ、量子回路を設計する際の重要な選択肢となっています。
crz(θ) q[0],q[1];
3量子ビット操作
CCXゲート(トフォリゲート)
CCXゲート(トフォリゲートとも呼ばれます)は、3つの量子ビットを使う特別な量子操作です。このゲートは、「もし〜かつ〜なら〜する」という2重の条件付き操作を行います:
- 最初の2つの量子ビット(制御ビット)の状態を確認します
- もし2つの制御ビットが両方とも
|1⟩
の状態なら、3つ目の量子ビット(ターゲットビット)の状態を裏返します - それ以外の場合は、何もしません
簡単な例えで説明すると:
- お父さんとお母さん(2つの制御ビット)が両方「はい」(
|1⟩
の状態)と言った場合のみ、子供(ターゲットビット)は裏返し(0→1、または1→0)の動作をします - お父さんかお母さんのどちらかでも「いいえ」(
|0⟩
の状態)と言った場合、子供は今の状態のままです
このゲートは、量子コンピュータで複雑な計算を行うための重要な部品です。例えば:
- 数の足し算や掛け算を行う量子回路を作るとき
- エラーを見つけて直す量子エラー訂正という技術
- より複雑な量子アルゴリズムの基本的な構成要素として
実際の量子コンピュータでCCXゲートを実行するときは、より単純な操作(1つや2つの量子ビットを使う操作)に分解して実行します。これは、実際の量子コンピュータの制限に対応するために必要な工夫です。
ccx q[0],q[1],q[2];
その他の操作
バリア
バリアは、量子コンピュータのプログラムで「ここで一旦区切りを付ける」という合図を出すための命令です。
これを理解するために、料理の例で考えてみましょう:
お母さんが子供に料理の手順を教えるとき、「この3つの手順は必ずこの順番でやってね」と言うことがありますよね。例えば:
- 玉ねぎを切る
- フライパンで炒める
- 塩を振る
この場合、「玉ねぎを切る」と「炒める」の順番を変えたり、「塩を振る」のを先にしたりすると、おいしい料理ができません。
バリアは、このように「この順番は絶対に変えちゃダメ!」という印をつけるための道具なのです。
バリアは主に以下のような場面で使われます:
- 量子操作の順番を守る:特定の順序で実行しないと正しい結果が得られない操作があるとき
- プログラムの確認を簡単にする:「ここまでの操作がうまくいっているか」を確認するための区切りとして
- 大切な操作を守る:特に重要な操作の前後に置いて、その操作が正しく行われるようにする
- 実験をきちんと行う:量子コンピュータの調整や性能確認をするときの区切りとして
バリアは、量子ビットの状態そのものは変えません。これは、料理で言えば「レシピの手順に線を引く」ようなもので、料理の味には影響しませんが、正しい手順で料理を作るために重要な役割を果たすのです。
特に、現在の量子コンピュータはまだ完璧ではなく、ノイズ(余計な影響)が入りやすいため、操作の順序を正確に制御することが非常に重要です。バリアは、そのための重要な道具として使われています。
barrier q[0],q[1];
測定
測定は、量子ビットの状態を「見る」操作です。これは量子コンピュータの世界で最も重要な操作の1つですが、少し不思議な性質を持っています。
測定について理解するために、例を使って説明しましょう:
想像してください。あなたの目の前に、特別なコインがあります。このコインは、量子の世界では「表と裏が同時に存在する」という不思議な状態になることができます。これが量子ビットの「重ね合わせ状態」です。
でも、このコインの状態を知りたいとき(つまり測定するとき)、面白いことが起こります:
- コインは必ず「表」か「裏」のどちらかの状態になります
- 一度測定すると、その状態に「固定」されてしまいます
- 元の「重ね合わせ状態」には戻れません
これは、量子の世界の重要な法則です。測定することで、不思議な重ね合わせ状態は消えてしまい、普通の世界(古典的な世界)の「はっきりした状態」になるのです。
測定の結果は、次のように記録されます:
- 量子ビットが
|0⟩
の状態だった場合→古典ビットに0
を記録 - 量子ビットが
|1⟩
の状態だった場合→古典ビットに1
を記録
重ね合わせ状態の場合は、確率的にどちらかの結果が出ます。例えば、「表と裏が同じ確率で重なっている状態」を測定すると、50%の確率で0
、50%の確率で1
が得られます。
この測定という操作は、通常、量子プログラムの最後に行います。なぜなら、測定をすると量子の不思議な状態が失われてしまうからです。ただし、量子エラーを直したり、量子テレポーテーションを行ったりする特別な場合には、計算の途中でも測定を行うことがあります。
measure q[0] -> c[0];
Cross, A. W., et al., (2017). Open Quantum Assembly Language. arXiv:1707.03429 . ↩︎
Cross, A. W., et al., (2022). OpenQASM 3: A broader and deeper quantum assembly language. arXiv:2104.14722 . ↩︎