本文へスキップ
QVILLAGERロゴQVILLAGER
OpenQASM 3.1

OpenQASM 量子回路講座

何も知らないところから、回路を説明できるまで。

『干渉する』『重ね合わせる』だけでは説明したことにしない。結果→数字→図→OpenQASMの順で、同じ変化を複数の見方から確認する。

入門 → マスター読了 約4時間全19章 + 付録A–E
OpenQASM 3.1量子回路Bell状態GroverQAOA

はじめに

最初に知ってほしいこと

この教材は、量子力学の用語集ではありません。量子回路を『入力を準備し、操作し、最後に0/1を読む手順』として学びます。抽象語を暗記せず、同じ回路を何度も実行したときの結果を予測できることを目標にします。

全体の学習順

段階章ここで初めて扱うもの
A 観測0〜2章0/1、回路、測定、shot、確率
B 状態3〜6章振幅、H、Z、干渉、測定基底
C 複数量子ビット7〜9章bit列、CX、Bell状態、もつれ
D 言語10〜13章OpenQASMの宣言、配列、制御、部品化
E 実機14章時間、barrier、ノイズ、トランスパイル
F アルゴリズム15〜17章Oracle、Grover、QUBO、QAOA
G マスター18章移行、デバッグ、総合制作

Chapter 13〜18の一本道

各章で『入力 → 変化 → 出力』を一つずつ増やす
章まず何を見るか次へ進む合図
13 回転確率・振幅・位相を分け、RX/RY/RZ/RZZの役割を見るRZは確率でなく位相を変えると説明できる
14 実機論理qubitと物理qubit、接続、SWAP、native gate、pulseを分ける同じBell回路が実機用命令へ変わる理由を説明できる
15 Oracle問題の条件、判定関数、Oracleを分けるOracleは答えを出さず、位相に印を付けると説明できる
16 Grover印 → 拡散 → 干渉 → 測定を追う重ね合わせだけでなく干渉が増幅を生むと説明できる
17 QAOA得点 → Costの位相 → Mixerの確率 → 測定を追う量子回路と外側の古典最適化を分けられる
18 デバッグ文法 → 理想論理 → 実機制約 → ノイズの順に切り分けるどの層の問題かを先に言える

この本で使う6段階テンプレート

  • •結果を見る: 何を何回測ると、0と1が何回出るか。
  • •言葉を付ける: 見た結果または計算手順にだけ新語を付ける。
  • •数字で追う: 状態の数字を一行ずつ更新する。
  • •回路図で追う: 左から右へ同じ操作を追う。
  • •OpenQASMで追う: 上から下へ同じ操作を追う。
  • •予測する: 実行前に結果を答えてから確認する。

CHAPTER 00

0と1、回路、測定

量子回路は何をする図なのか

0.1 まず普通のbitから

普通のコンピュータが扱うbitは、読んだ瞬間に0か1のどちらかです。電圧が低ければ0、高ければ1という実装が代表例です。ここでは物理方式ではなく、『答えが0か1の1桁』だけを使います。

0.2 量子回路も最後は0か1を返す

量子ビットは途中で古典bitより多くの状態を持てます。しかし最後に通常の方法で測ると、1回の実行から得られる答えは0か1のどちらか1つです。途中の状態と、最後に読める答えを混同しないことが最初のポイントです。

0.3 回路図は処理の時間表

横線1本は同じqubitの時間の流れです。左が開始、右が終了です。線上の箱は、その時点で状態を変える命令です。測定記号の位置で0/1を読みます。

図 1回路図は左から右へ読む。q[0]にXを行い、その後で測る。

0.4 OpenQASMは同じ手順を文字で書く

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit q;
bit result;
reset q;
result = measure q;
OPENQASM 3.1;使う言語の版を宣言する
include "stdgates.inc";標準ゲート名を使えるようにする
qubit q;qというqubitを1個用意する
bit result;測定結果を入れる古典bitを用意する
reset q;qを測定すると必ず0になる|0>へ準備する
result = measure q;qを測り、0または1をresultへ入れる

0.5 最初の実験

確認するもの内容
開始reset q;でqを|0>へ準備
操作ゲートをかけずに測定
測定結果理想的には必ず0
理由reset後は0として読める状態だから

理解チェック

  1. 回路図では時間はどちらへ進むか。

    答えを見る: 回路図では時間はどちらへ進むか。

    左から右へ進む。

  2. 1回の通常測定で得られる答えはいくつか。

    答えを見る: 1回の通常測定で得られる答えはいくつか。

    0か1のどちらか1つ。

  3. qubitとbitは同じか。

    答えを見る: qubitとbitは同じか。

    違う。qubitは測定前の量子状態を持ち、bitは測定後の0/1を保存する。

CHAPTER 01

Xゲートで0と1を反転する

最も単純なゲートを完全に予測する

1.1 まず結果だけを見る

Xを1回

確認するもの内容
開始|0>
操作Xを1回適用して測定
測定結果必ず1
理由Xは0として読める状態を1として読める状態へ交換する
入力Xの後測定
|0>|1>1
|1>|0>0

1.2 Xを2回かける

|0> → X → |1> → X → |0>です。最初へ戻るので、Xは自分自身が逆操作です。

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit q;
bit result;
reset q;
x q;
result = measure q;
x q;qにXゲートを1回適用する
result = measure q;Xの後のqを測るので、理想的には1

理解チェック

  1. |1>へXをかけると何になるか。

    答えを見る: |1>へXをかけると何になるか。

    |0>になる。

  2. |0>へXを2回かけて測ると何が出るか。

    答えを見る: |0>へXを2回かけて測ると何が出るか。

    0が出る。

  3. x q; の q は何を表すか。

    答えを見る: x q; の q は何を表すか。

    Xを適用する対象のqubit名。

CHAPTER 02

1回と1000回を区別する

確率はどこから分かるのか

2.1 1回の結果だけでは割合は分からない

ある準備から0が出やすいのか1が出やすいのかを知るには、同じプログラムを最初から何度も実行します。各回は新しいqubitを準備する独立した実験です。

回路1 shot1000 shotsの理想的な集計
何もしない→測定00: 1000回
X→測定11: 1000回
後で学ぶH→測定0または10と1が約500回ずつ

2.2 OpenQASMと実行サービスの役割を分ける

OpenQASMは『1回のプログラムで何をするか』を書きます。1000 shots実行する設定、実行先のシミュレータや実機の選択、集計グラフの作成は、通常SDKや実行サービス側の仕事です。

理解チェック

  1. 1000 shotsとは何を1000回行うことか。

    答えを見る: 1000 shotsとは何を1000回行うことか。

    準備から測定までの量子プログラム全体を、独立に1000回実行する。

  2. shotsは通常OpenQASMのどこに書くか。

    答えを見る: shotsは通常OpenQASMのどこに書くか。

    通常はOpenQASM内ではなく、SDKや実行サービス側で設定する。

  3. 理想的なX→測定を1000 shots行うとどうなるか。

    答えを見る: 理想的なX→測定を1000 shots行うとどうなるか。

    1が1000回出る。

CHAPTER 03

測定前の状態を2個の数字で記録する

なぜ確率だけでは足りないのか

3.1 状態カード [a, b]

1qubitの測定前の状態を、2個の数字 [a, b] で記録します。左のaは0側、右のbは1側の数字です。この教材では、まず実数だけを使います。

図 2状態カード[a, b]から、振幅を2乗して0/1の測定確率を求める流れ例 [1/√2, 1/√2] → [1/2, 1/2] → 0と1が50%ずつ。振幅と確率は別物で、確率は振幅を2乗して求める。
状態状態カード0の確率1の確率
|0>[1, 0]1² = 10² = 0
|1>[0, 1]0² = 01² = 1
50:50の例[1/√2, 1/√2](1/√2)² = 1/2(1/√2)² = 1/2

3.2 √2を怖がらない

√2は『2乗すると2になる正の数』で、約1.414です。1/√2は約0.707で、2乗すると1/2になります。したがって [1/√2, 1/√2] は0と1が50%ずつになる状態カードです。

3.3 マイナスの振幅も確率は正になる

[1/√2, -1/√2]でも、2乗すれば0側も1側も1/2です。直後に測るだけなら、プラスかマイナスかは回数分布に見えません。しかし後のゲートは振幅を足し引きするため、符号の違いが別の測定結果へ変わります。

理解チェック

  1. 状態カード[1,0]の測定結果は何か。

    答えを見る: 状態カード[1,0]の測定結果は何か。

    必ず0。

  2. 1/√2の2乗はいくつか。

    答えを見る: 1/√2の2乗はいくつか。

    1/2。

  3. 振幅−1/√2は負の確率を意味するか。

    答えを見る: 振幅−1/√2は負の確率を意味するか。

    意味しない。絶対値を2乗するので確率は1/2になる。

CHAPTER 04

Hゲートを計算で理解する

50:50を作るだけの箱ではない

4.1 Hの規則は2つ

Hゲートは入力の0側振幅aと1側振幅bから、新しい2個の振幅を作ります。新しい0側は(a+b)/√2、新しい1側は(a−b)/√2です。最初はこの式へ数字を代入するだけで十分です。

図 3Hは入力振幅a, bから、和で0側、差で1側の新しい振幅を作る

4.2 |0>へHをかける

|0>の状態カードは[1,0]です。0側は(1+0)/√2=1/√2、1側は(1−0)/√2=1/√2。したがってH|0>=[1/√2,1/√2]です。測定すると0と1が50%ずつです。

4.3 |1>へHをかける

|1>は[0,1]です。0側は(0+1)/√2=1/√2、1側は(0−1)/√2=−1/√2。したがってH|1>=[1/√2,−1/√2]です。直後の通常測定は50:50ですが、符号が異なります。

図 4|0>、|1>、H|0>の理想測定確率
入力Hの計算出力通常測定
|0>=[1,0][(1+0)/√2,(1−0)/√2]|+>0/1が50:50
|1>=[0,1][(0+1)/√2,(0−1)/√2]|->0/1が50:50

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit q;
bit result;
reset q;
h q;
result = measure q;
h q;|0>=[1,0]へHを適用し、|+>を作る
measure1 shotでは0か1、複数shotsでは約50:50

4.4 Hを2回かける

|+>=[1/√2,1/√2]へもう一度Hをかけます。新しい0側は(1/√2+1/√2)/√2=1、新しい1側は(1/√2−1/√2)/√2=0です。結果は[1,0]=|0>です。Hも自分自身が逆操作です。

理解チェック

  1. H|0>の状態カードは何か。

    答えを見る: H|0>の状態カードは何か。

    [1/√2,1/√2]。

  2. H|1>の1側振幅がマイナスになる理由は何か。

    答えを見る: H|1>の1側振幅がマイナスになる理由は何か。

    Hの1側の式が(a−b)/√2で、|1>ではa=0、b=1だから。

  3. Hを2回かけるとどうなるか。

    答えを見る: Hを2回かけるとどうなるか。

    元の状態へ戻る。

CHAPTER 05

Zゲートと『干渉』を数字から理解する

見えない符号を、見える0/1へ変換する

5.1 Zの規則

Zゲートは状態カード[a,b]を[a,−b]へ変えます。0側は変えず、1側の振幅だけ符号を反転します。

入力Zの後直後の通常測定
|0>=[1,0][1,0]必ず0
|1>=[0,1][0,-1]必ず1
|+>=[1/√2,1/√2][1/√2,-1/√2]=|->0/1が50:50

5.2 なぜ[0,−1]も測定では1なのか

0の確率は0²=0、1の確率は(−1)²=1だからです。状態全体に同じ−を付けた[0,−1]と[0,1]は、どの測定でも区別できません。一方、[1/√2,1/√2]と[1/√2,−1/√2]は2成分の間の符号関係が違い、後のHで区別できます。

5.3 H-Z-Hを一行ずつ計算する

時点状態カード計算
開始[1,0]|0>
最初のH[1/√2,1/√2]|+>
Z[1/√2,-1/√2]|->
最後のH[0,1]0側=(a+b)/√2=0、1側=(a−b)/√2=1
測定|1>必ず1
図 5H-Z-Hの各段階の状態カードと、最後のHで行う2本の足し引き

5.4 ここで初めて『干渉』と呼ぶ

最後のHでは、0側の新しい振幅を作るために1/√2と−1/√2を足しました。結果は0です。1側では1/√2から−1/√2を引いたので、結果は1です。このように、複数の振幅が同じ出力の振幅計算に入り、足し算または引き算で大きくなったり0になったりすることを干渉と呼びます。

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit q;
bit result;
reset q;
h q;
z q;
h q;
result = measure q;
h q;[1,0]→[1/√2,1/√2]
z q;1側だけ符号反転
h q;和と差を計算し[0,1]
measure理想的には必ず1

理解チェック

  1. Zは状態カード[a,b]をどう変えるか。

    答えを見る: Zは状態カード[a,b]をどう変えるか。

    [a,−b]へ変える。

  2. H-Z-Hで0側振幅が0になる足し算を書け。

    答えを見る: H-Z-Hで0側振幅が0になる足し算を書け。

    (1/√2 + (−1/√2))/√2 = 0。

  3. 本書で干渉とは何か。

    答えを見る: 本書で干渉とは何か。

    複数の振幅が同じ出力の計算に入り、足し引きで大きさが変わること。

CHAPTER 06

測定基底は『何を区別して読むか』

Z基底とX基底を回路として理解する

6.1 測定器には答えのラベルが必要

通常のmeasureは、状態を|0>と|1>のどちらとして読むかを返します。しかし|+>と|->を区別したい場合、通常測定の直前にHを置きます。H|+>=|0>、H|->=|1>だからです。

図 6Z基底測定とX基底測定の回路上の違いX基底測定は、Hで読み方を変換してから通常のZ基底測定を行う
準備状態Z基底測定X基底測定(H→measure)
|0>必ず00/1が50:50
|1>必ず10/1が50:50
|+>0/1が50:50必ず0
|->0/1が50:50必ず1

OpenQASMを一行ずつ読む

OpenQASM 3.1snippet
// |->を準備してX基底で測る
x q;
h q;
// X基底測定
h q;
result = measure q;
x; h;|0>→|1>→|->を準備
h; measure|->→|1>へ変換し、通常測定で1

理解チェック

  1. 通常のmeasureは何を区別するか。

    答えを見る: 通常のmeasureは何を区別するか。

    |0>と|1>を区別する。

  2. X基底で測る前に何を置くか。

    答えを見る: X基底で測る前に何を置くか。

    Hゲートを置く。

  3. |+>をX基底で測ると何が出るか。

    答えを見る: |+>をX基底で測ると何が出るか。

    必ず0が出る。

CHAPTER 07

2qubitを4個の候補で記録する

00、01、10、11は何を表すのか

7.1 2個の古典bitには4通りある

2個のbitを並べると、00、01、10、11の4通りです。2qubitの測定結果も、1 shotではこの4つのどれか1つです。3qubitなら000から111まで2³=8通りです。

7.2 2qubitの状態カード

2qubitでは、各候補00、01、10、11に対応する振幅を4個並べます。本書では[q[0]q[1]]の順に書き、状態カードを[a00,a01,a10,a11]とします。

状態状態カード [00,01,10,11]測定
|00>[1,0,0,0]必ず00
|01>[0,1,0,0]必ず01
00と10が50:50[1/√2,0,1/√2,0]00または10

7.3 添字順と表示順は別問題

本書の説明ではq[0]q[1]の順でbit列を書きます。ただし、SDKや実行サービスが結果文字列をq[1]q[0]の順で表示する場合があります。意味を推測せず、Xを1個だけ置く最小テストで表示規則を確認します。

図 7q[0]だけへXをかけ、結果表示が10か01かでbitの並び順を確認する

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
reset q;
x q[0];
c = measure q;
qubit[2] q;q[0]とq[1]の2qubitを用意
x q[0];本書の順では|00>→|10>
c = measure q;両方を測る。表示文字列の順は実行環境で確認

理解チェック

  1. 2qubitの測定候補はいくつか。

    答えを見る: 2qubitの測定候補はいくつか。

    00、01、10、11の4個。

  2. |01>の4成分状態カードを書け。

    答えを見る: |01>の4成分状態カードを書け。

    [0,1,0,0]。

  3. 結果文字列の順を確認する最小テストは何か。

    答えを見る: 結果文字列の順を確認する最小テストは何か。

    片方のqubitだけにXをかけて両方を測る。

CHAPTER 08

CX/CNOTを4行の表で理解する

制御と標的を取り違えない

8.1 規則は『制御が1なら標的へX』

図 8CXの4入力。第1bitの制御が1の2行だけ、第2bitの標的が反転する
入力 q[0]q[1]制御q[0]標的q[1]出力
000変えない00
010変えない01
1010→111
1111→010

8.2 状態カード全体へ同じ規則を適用する

状態が複数候補の振幅を持つ場合も、各候補へ4行表を適用します。たとえば[1/√2,0,1/√2,0]は00と10が50:50です。CX q[0],q[1]をかけると00は00、10は11へ移るので、[1/√2,0,0,1/√2]になります。

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
reset q;
x q[0];
cx q[0], q[1];
c = measure q;
x q[0];|00>→|10>
cx q[0],q[1];制御が1なので標的0→1、|10>→|11>
measure理想的には11

8.3 引数を逆にすると別の回路

同じ入力|10>でもcx q[1],q[0]なら、制御q[1]は0なので何も起こらず|10>のままです。制御線と標的線は交換できません。

理解チェック

  1. CXの第1引数は何か。

    答えを見る: CXの第1引数は何か。

    制御qubit。

  2. 入力11へcx q[0],q[1]をかけると何か。

    答えを見る: 入力11へcx q[0],q[1]をかけると何か。

    10になる。

  3. 入力10へcx q[1],q[0]をかけると何か。

    答えを見る: 入力10へcx q[1],q[0]をかけると何か。

    制御q[1]が0なので10のまま。

CHAPTER 09

Bell状態ともつれ

各qubitが50:50なのに、2個を一緒に見ると規則がある

9.1 Hの後、CXをかける

時点状態カード [00,01,10,11]意味
開始[1,0,0,0]必ず00
H q[0][1/√2,0,1/√2,0]00と10の振幅
CX q[0],q[1][1/√2,0,0,1/√2]10の振幅が11へ移る
測定00または11理想的には各50%
図 9Hで00/10の振幅を作り、CXで10の振幅を11へ移すBell回路

9.2 『各qubitだけ』を見ると50:50

00と11が半分ずつなので、q[0]だけ見ても0/1が50:50、q[1]だけ見ても0/1が50:50です。しかし2個を一緒に見ると、01と10は出ず、値が必ず一致します。個別の割合だけでは全体の関係を表せません。

図 10Bell状態では各qubit単独は50:50だが、2個を一緒に測ると00と11だけが出る

9.3 CXは未知状態のコピーではない

制御が|0>または|1>だと、CXは標的を同じZ基底値へそろえるように見えます。しかし制御が|+>なら、出力は『制御|+>、標的|+>』ではなくBell状態です。各qubit単独の同じ状態を2個作ったわけではありません。

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
reset q;
h q[0];
cx q[0], q[1];
c = measure q;
h q[0];00と10へ同じ振幅を作る
cx q[0],q[1];10の振幅を11へ移す
measure理想的には00と11だけ

理解チェック

  1. このBell回路で出ないbit列は何か。

    答えを見る: このBell回路で出ないbit列は何か。

    01と10。

  2. 各qubitだけの0/1割合はどうなるか。

    答えを見る: 各qubitだけの0/1割合はどうなるか。

    それぞれ0と1が50%ずつ。

  3. もつれだけで瞬時通信できるか。

    答えを見る: もつれだけで瞬時通信できるか。

    できない。相手側の結果は古典通信で照合するまで分からない。

CHAPTER 10

OpenQASM 3の骨格

宣言・操作・測定を自分で書く

10.1 1行は原則1つの文

種類例役割
版宣言OPENQASM 3.1;言語版を指定
読み込みinclude "stdgates.inc";標準ゲート名を定義
量子宣言qubit[2] q;2qubitを用意
古典宣言bit[2] c;2bitを用意
ゲートh q[0];対象へH
測定c = measure q;測定結果を保存

10.2 添字は0から始まる

qubit[3] q;で使える添字は0、1、2です。q[3]は4個目を意味するため範囲外です。個数3と最大添字2を区別します。

10.3 コメントは実行されない説明

OpenQASM 3.1snippet
// この行の右側は1行コメント
x q[0];  // q[0]を反転
/* 複数行の
   コメント */

10.4 完全なBellプログラム

OpenQASMを一行ずつ読む

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
reset q;
h q[0];
cx q[0], q[1];
c = measure q;
1〜2行言語版と標準ゲートを用意
3〜4行量子2個、結果保存用bit2個を宣言
5行2個のqubitを|00>へ初期化
6〜7行Bell状態を準備
8行両qubitを測定

理解チェック

  1. qubit[4] q;で有効な最大添字は何か。

    答えを見る: qubit[4] q;で有効な最大添字は何か。

    3。添字は0から始まる。

  2. セミコロンの主な役割は何か。

    答えを見る: セミコロンの主な役割は何か。

    文の終わりを示す。

  3. include "stdgates.inc";は何を可能にするか。

    答えを見る: include "stdgates.inc";は何を可能にするか。

    x、h、cxなどの標準ゲート名を使えるようにする。

CHAPTER 11

測定・reset・条件分岐

回路の途中で0/1を読み、その後の操作を変える

11.1 測定は最後だけではない

回路の途中でqubitを測り、その結果をbitへ保存できます。そのbitが0か1かによって、後のゲートを変えられる処理系があります。

11.2 resetは|0>へ準備し直す

OpenQASM 3.1snippet
reset q[0];

11.3 ifで古典bitを確認する

OpenQASM 3.1snippet
bit m;
m = measure q[0];
if (m == 1) {
  x q[1];
}
mifの条件q[1]への操作
0偽何もしない
1真Xを適用

11.4 測定したら元の重ね合わせは残らない

たとえば|+>を測ると、結果は0または1です。結果0なら測定後の状態は|0>、結果1なら|1>です。同じqubitを続けてもう一度通常測定すると、理想的には同じ値が出ます。

理解チェック

  1. qubitをifで直接q[0]==1と比較してよいか。

    答えを見る: qubitをifで直接q[0]==1と比較してよいか。

    いけない。先に測定して結果をbitへ保存し、そのbitを比較する。

  2. reset後の理想状態は何か。

    答えを見る: reset後の理想状態は何か。

    |0>。

  3. 動的回路と1000 shotsの違いは何か。

    答えを見る: 動的回路と1000 shotsの違いは何か。

    動的回路は1 shotの途中で分岐する。shotsはプログラム全体を独立に反復する。

CHAPTER 12

型・入力・ループ

外部入力の流れと、4個のqubitを順に操作するループを追う

12.1 型は値の使い方を決める

型例用途
bit / bit[n]bit[3] c;0/1。測定結果やフラグ
boolbool done = false;true/false。条件判定
int / uintuint[8] count;整数。uintは0以上
floatfloat[64] score;小数を含む数
angleangle theta;一周すると同じ向きへ戻る角度
durationduration t = 100ns;nsなど単位付きの時間

12.2 inputは回路外から値を受け取る

flip=0なら0、flip=1なら1を返す完全なプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
input bit flip;
output bit result;
qubit q;
reset q;
if (flip == 1) {
  x q;
}
result = measure q;
input bit flip;実行時に回路外から0または1を受け取る
reset q;分岐前のqを|0>へ初期化する
if (flip == 1)受け取った値が1のときだけXを実行
result = measure q;測定した0/1をoutputへ入れる

flipが入口から出口まで進む様子

同じプログラムへ0と1を入れ、実行される経路の違いを比べます。

  1. STEP 1外からflipを渡す

    実行サービスがflipへ0または1を渡します。これはshotの測定結果ではなく、実行前に決める入力です。

    型
    bit
    input bit flip;
  2. STEP 2flip=1のときだけX

    flip=0ならqは|0>のままです。flip=1ならXが実行され、qは|1>になります。

    flip=0
    result=0
    flip=1
    result=1
    if (flip == 1) {  x q;}
  3. STEP 3測定値を外へ返す

    measureで得た0/1をresultへ保存します。outputと宣言したresultだけが明示的な返り値です。

    result = measure q;

12.3 forは回数が決まった繰り返し

OpenQASM 3.1snippet
qubit[4] q;
for int i in [0:3] {
  h q[i];
}

iは0、1、2、3と変化し、4個のqubitへHを1回ずつ適用します。[0:3]は終端3を含みます。

forを4行へ展開して見る

ループは同時に4回起きる魔法ではなく、iの値を順に変えた命令列です。

  1. i = 0q[0]へHを適用

    この反復ではiが0なので、h q[i];はh q[0];として働きます。

    実際の文
    h q[0];
    for int i in [0:3] {  h q[i];}
  2. i = 1q[1]へHを適用

    この反復ではiが1なので、h q[i];はh q[1];として働きます。

    実際の文
    h q[1];
    for int i in [0:3] {  h q[i];}
  3. i = 2q[2]へHを適用

    この反復ではiが2なので、h q[i];はh q[2];として働きます。

    実際の文
    h q[2];
    for int i in [0:3] {  h q[i];}
  4. i = 3q[3]へHを適用

    この反復ではiが3なので、h q[i];はh q[3];として働きます。

    実際の文
    h q[3];
    for int i in [0:3] {  h q[i];}

12.4 whileは条件が真の間の繰り返し

OpenQASM 3.1snippet
qubit q;
bit success = 0;
while (success == 0) {
  reset q;
  h q;
  success = measure q;
}
図 11反復が起きる3つの場所

理解チェック

  1. input bit flip;のflipはどこから来るか。

    答えを見る: input bit flip;のflipはどこから来るか。

    実行時にプログラム外の実行サービスやホストから渡される。

  2. for int i in [0:3]は何回か。

    答えを見る: for int i in [0:3]は何回か。

    i=0、1、2、3の4回。

  3. whileとshotsは同じか。

    答えを見る: whileとshotsは同じか。

    違う。whileは1実行内の条件反復、shotsはプログラム全体の独立反復。

CHAPTER 13

RX・RY・RZ・RZZを図から理解する

1qubitの回転と2qubitの位相を、同じ地図で一つずつ読む

13.1 回転を読むための2枚の地図

これまでは振幅を実数で扱い、+と−だけを使いました。+の向きを0度、−の向きを180度と考えると、符号は位相の2つの特別な場合です。一般の量子回路では45度や90度など途中の向きも使います。

時計の向き度ラジアン
右0度0
上90度π/2
左180度π
一周して右360度2π
図 12複素振幅を時計の針として読む

4つの回転ゲートを、同じ質問で見比べる

3つとも球の中心を通る矢印を回します。違うのは回転の中心になる軸です。X・Y・Z軸と、矢印の先の位置を見比べましょう。

RY割合を動かす

Y軸まわり。π/2では矢印が+Xへ進み、0と1が50:50。

RX同じ割合、向きが違う

X軸まわり。π/2では矢印が−Yへ進むが、測ると同じ50:50。

RZ割合を保って向きを回す

Hで50:50を作った後、Z軸まわりに位相だけを動かす。

RY

0と1の出やすさを素直に動かす

1 qubit
変えるもの
0側と1側の振幅の割合
すぐには変えないもの
角度だけで決めた理想的な合計確率1
Example
|0>へRY(π/2)をかけると、0と1が50%ずつになる。
OpenQASM
ry(pi / 2) q;
Later use
入力データや試行確率を角度で準備するときに使います。

RX

同じ出やすさへ、別の向きから動かす

1 qubit
変えるもの
0/1の割合と、1側振幅の向き
すぐには変えないもの
|0>からの代表角ではRYと同じ測定確率
Example
|0>へRX(π/2)でも50:50。ただし1側振幅は−i方向を向く。
OpenQASM
rx(pi / 2) q;
Later use
Chapter 17のQAOAで、位相差を出やすさへ変えるMixerになります。

RZ

出やすさを保ったまま時計を回す

1 qubit
変えるもの
正のθでは、位相時計の0側をθ/2だけ時計回り、1側をθ/2だけ反時計回りに回す
すぐには変えないもの
直後のZ基底での0/1確率
Example
初期位相を右向きの1とすると、RZ(π)で0側は−i、1側は+i。確率は50:50のままで、最後のHをかけると1が100%になる。
OpenQASM
rz(pi) q;
Later use
位相を印として残す回路や、RZZの中身に使います。

RZZ

2つの0/1を見比べ、矢印の向きに目印を付ける

2 qubits
変えるもの
4候補の矢印の向き。同じ組と違う組を別方向へ向ける
すぐには変えないもの
00・01・10・11の4候補と、それぞれが出る確率
Example
θ=90°なら、00/11の矢印は右下へ、01/10は右上へ向く。4候補の確率は各25%のまま。
OpenQASM
cx a,b; rz(theta) b; cx a,b;
Later use
Chapter 17のQAOAで、2変数の得点を位相へ写すCost回路になります。

13.2 RYで0から1へ連続的に動かす

RY(θ)を|0>へかけると、状態はcos(θ/2)|0>+sin(θ/2)|1>になります。θ=0なら|0>、θ=π/2なら0/1が50:50、θ=πなら|1>です。πは180度なので、π/2は90度です。

θRY(θ)|0>1の確率
0|0>0
π/2(|0>+|1>)/√21/2
π|1>1
図 13RYの角度を0からπへ動かしたときの測定確率

外からRYの角度を受け取る完全なプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
input angle theta;
output bit result;
qubit q;
reset q;
ry(theta) q;
result = measure q;
input angle theta;0、pi/2、piなどを実行時に渡す
reset q;角度ごとに同じ|0>から始める
ry(theta) q;|0>をthetaに応じて回転
result = measure q;1の理想確率はsin²(theta/2)

13.3 RZの見えない違いをHで読む

ゲートOpenQASM主に変えるもの
RXrx(theta) q;0/1振幅と位相
RYry(theta) q;0/1振幅。実数で追いやすい
RZrz(theta) q;1qubitの相対位相
ZZ位相cx a,b; rz(theta) b; cx a,b;2qubitの関係に応じた位相

RZの位相差をHで1へ変える完全なプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
output bit result;
qubit q;
reset q;
h q;
rz(pi) q;
h q;
result = measure q;
reset q;qを|0>へ初期化
h q;|0>→|+>。0側と1側の振幅は同じ向き
rz(pi) q;2成分の相対的な向きを180度ずらし、全体位相を除けば|->
h q;|->→|1>。位相差を測定可能な違いへ変換
measure理想的には必ず1

RZだけでは見えない位相を、最後のHで読む

H-RZ(π)-Hを、状態カードと振幅の向きで交互に確認します。

  1. STEP 1|0>から始める

    resetで|0>へ準備します。0側振幅だけが1なので、通常測定なら必ず0です。

    測定
    0が100%
    qubit q;reset q;
  2. STEP 2Hで|+>を作る

    0側と1側は同じ大きさ、同じ0度の向きです。

    状態
    |+>
    h q;
  3. STEP 3RZ(π)で、2本を反対向きにする

    RZ(π)は、0側を時計回りに90°、1側を反時計回りに90°回します。2本の差が0°から180°になり、反対向きになります。矢印の長さは変わらないので、この直後に測るだけなら0/1はまだ50:50です。

    RZが変えたもの
    2本の向きの差 0° → 180°
    まだ変わらないもの
    0/1の確率 50:50
    rz(pi) q;
  4. STEP 4Hの2つの出口で、矢印を足し引きする

    Hには、2本を足す『0の出口』と、0側から1側を引く『1の出口』があります。反対向きの2本を0の出口で足すと打ち消し合います。一方、1の出口では左向きを引くので右向きへ変わり、2本が強め合います。そのため振幅は1側だけに残ります。

    測定
    1が100%
    h q;result = measure q;

13.4 CX-RZ-CXで2qubitの関係へ位相を付ける

最初のCXは、aが1のときだけbを反転します。4通りを並べると、CX後の一時的なbは、aとbが同じ組なら0、違う組なら1になります。つまりbを『同じ/違う』の一時メモとして使えます。

図 144候補を1行ずつ追うと、CX-RZ-CXがRZZと同じだと分かる
図 15上の4行の処理を量子回路記号で書く

13.5 gateは量子操作の並びに名前を付ける

OpenQASM 3.1snippet
gate zz_phase(theta) a, b {
  cx a, b;
  rz(theta) b;
  cx a, b;
}
qubit[2] q;
zz_phase(pi / 2) q[0], q[1];
発展回転を理解した後で読む: 修飾子とdefここからは回転ゲートの理解に必須ではない、OpenQASMの部品化機能です。

13.6 修飾子は既存ゲートの使い方を変える

修飾子例意味
ctrl @ctrl @ x q[0],q[1];制御付きX、つまりCX
negctrl @negctrl @ x a,b;制御が0のとき適用
inv @inv @ s q;Sの逆操作
pow(k) @pow(2) @ t q;Tを2回相当

13.7 defは一般的なサブルーチン

OpenQASM 3.1snippet
def parity(bit[4] x) -> bit {
  bit p = 0;
  for int i in [0:3] {
    p ^= x[i];
  }
  return p;
}

p ^= x[i];はpとx[i]が異なるとき1、同じとき0になるXORを計算し、その結果をpへ戻す省略記法です。4回の反復後、xの中の1が奇数個ならp=1、偶数個ならp=0になります。これは1の個数そのものではなく奇偶(parity)を求める古典処理なので、量子ゲートだけをまとめるgateではなくdefを使います。

比較gatedef
主目的ユニタリな量子ゲート列一般的な処理
戻り値なし持てる
測定・古典処理原則不向き扱える
逆操作修飾原則可能一般には同じ意味で扱わない

理解チェック

  1. 90度はラジアンでいくつか。

    答えを見る: 90度はラジアンでいくつか。

    π/2。OpenQASMではpi / 2と書ける。

  2. |+>へRZ(π)をかけた直後のZ基底測定確率はどうなるか。

    答えを見る: |+>へRZ(π)をかけた直後のZ基底測定確率はどうなるか。

    0と1が50%ずつのまま。位相差は後のHで測定結果へ変わる。

  3. CX-RZ-CXの最後のCXは何のためか。

    答えを見る: CX-RZ-CXの最後のCXは何のためか。

    最初のCXで一時的に写した関係を元へ戻し、位相だけを残すため。

  4. 戻り値を返す古典処理にはgateとdefのどちらを使うか。

    答えを見る: 戻り値を返す古典処理にはgateとdefのどちらを使うか。

    defを使う。

CHAPTER 14

論理回路を実機で動かすまで

同じBell回路が、配置・SWAP・基礎ゲート・pulseへ変わる

14.1 出発点は、意図を表すBell回路

この章では、HとCXでBell状態を作る同じ例を最後まで追います。ここで書くq[0]とq[1]は、まだ装置上の部品番号ではありません。まず『Hの後にCXを行い、00または11を得たい』という論理だけを表します。

変換前のBell回路を表す完全なプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
output bit[2] result;
qubit[2] q;
reset q;
h q[0];
cx q[0], q[1];
result = measure q;
qubit[2] q;まだ物理番号を固定しない2個の論理qubit
reset q;論理回路の開始状態を|00>へ初期化
h; cx;Bell状態を作る論理
measure理想的には00と11が約半分ずつ

なぜ物理0から物理2へ直接つながないのでしょうか。実機では、2つのqubitを操作するCXは、装置に物理的な結合(直接リンク)がある組だけに許されるからです。接続が0–1–2なら、0と2は1を飛び越して話せません。古典通信のように信号を遠くへ配る操作ではなく、2qubitゲートそのものが隣接ペア専用です。別の配置を選ぶ、SWAPで隣へ移す、または対応する別の分解を使う、という選択になります。ここでは仕組みが見えるようSWAPを使います。

0–1–2の接続で、SWAP後にCXできる理由
段階物理0の中身物理1の中身物理2の中身
最初q[0]の状態空き/別の状態q[1]の状態
SWAP 0,1の後別の状態q[0]の状態q[1]の状態
次のCX使わない制御側標的側
SWAP = CX(A→B) → CX(B→A) → CX(A→B)
入力 (A,B)1回目2回目3回目の結果
00000000
01011110
10110101
11101011

Bell回路が装置へ届くまで

論理は同じでも、対象装置に合わせて見た目と命令数が変わります。

  1. STEP 1論理回路を書く

    q[0]へH、そのq[0]を制御としてq[1]へCXを行います。この段階の目標は00/11の相関です。

    理想分布
    00:50%, 11:50%
    h q[0];cx q[0], q[1];
  2. STEP 2論理qubitを物理qubitへ配置する

    例としてq[0]を物理0、q[1]を物理2へ置きます。装置の接続が0–1–2なら、CXは直接リンクのある0–1または1–2にしかかけられません。0から2へ飛び越す『長距離CX』は、この装置の命令にはありません。

    直接接続
    0–1、1–2
  3. STEP 3SWAPで隣へ移してからCXする

    SWAPは物理0と1の中身を交換する操作です。q[0]の状態が物理1へ移り、q[1]の状態は物理2に残るので、隣り合う1–2へCXをかけられます。これはq[0]を物理2へ送る操作ではありません。q[0]を2へ直接送る道がないため、まず1へ一歩移すのです。コンパイラは最後の測定先も新しい対応へ合わせます。

    追加操作
    SWAP
  4. STEP 4装置の基礎ゲートへ分解する

    SWAPを直接実行できない装置では、SWAPをCX(A→B)→CX(B→A)→CX(A→B)の3個へ置き換えます。1回目でBを一時的に変え、2回目でAへ元のBを渡し、3回目でAの元の値をBへ渡す、という順です。装置がCXを基本命令として持つから、この置き換えができます。

    SWAP 1個
    CX 3個へ分解可能
  5. STEP 5校正済みpulseとして実行する

    最後に各基礎ゲートが、対象qubit用に校正された物理信号として再生されます。ここで実機の誤差や時間が結果へ影響します。

    出力
    実機の測定counts
図 16論理Bell回路から実機制御までの5段階

14.2 barrier・delay・pulseを時間軸で分ける

OpenQASM 3.1snippet
h q[0];
barrier q;
cx q[0], q[1];
OpenQASM 3.1snippet
delay[100ns] q[0];
図 17barrier・delay・pulseが表すものの違い

14.3 shotsの揺れとノイズを、出る候補から見分ける

理想Bell状態で出る候補は00と11だけです。100 shotsなら46対54のように割合は揺れますが、理想実行では01と10は出ません。実機で01や10が繰り返し現れるなら、有限shotsだけでは説明できず、ゲートや読み出しの誤差を調べます。

図 18理想分布、有限shotsの揺れ、ノイズを含む分布

理解チェック

  1. 物理0と物理2が直接つながらないとき、トランスパイラは何を追加することがあるか。

    答えを見る: 物理0と物理2が直接つながらないとき、トランスパイラは何を追加することがあるか。

    状態を隣接qubitへ移すSWAPを追加することがある。

  2. barrierはノイズを防いだり理想状態を反転したりするか。

    答えを見る: barrierはノイズを防いだり理想状態を反転したりするか。

    しない。指定qubitについてゲートの移動や結合を制限する境界である。

  3. 理想Bell回路を100 shots実行して00:46、11:54なら、直ちに故障と言えるか。

    答えを見る: 理想Bell回路を100 shots実行して00:46、11:54なら、直ちに故障と言えるか。

    言えない。有限shotsの自然な揺れであり得る。

  4. Bell回路で01と10が継続して出たら、まず何と比較するか。

    答えを見る: Bell回路で01と10が継続して出たら、まず何と比較するか。

    状態計算と理想シミュレータの分布に戻り、その後で実機ノイズを切り分ける。

CHAPTER 15

アルゴリズム・回路・Oracleを分ける

4候補のうち10だけを、判定表から位相反転する

この章で追うものは、候補の名前と振幅の向きの2つです。Hは4候補を準備し、Oracleは10の振幅だけを+1/2から−1/2へ変え、測定はまだ行いません。つまりOracleは『答えを表示する操作』ではなく、『後で増幅できる目印を付ける操作』です。

15.1 まず『何を解くか』と『どう実行するか』を分ける

この章では候補00、01、10、11から、条件に合う候補を探します。条件は『左のbitが1、右のbitが0』です。答え10を箱の中へ直接保存するのではなく、どの候補にも同じ条件を適用できる判定規則を作ります。

『誰が何を知っているか』を分ける
役割することこの例
問題設定探したい条件を決める左=1 かつ 右=0
判定関数 f1候補を検査して0/1を返すf(10)=1、それ以外=0
Groverfを利用して該当候補の振幅を増やす10を測りやすくする
古典探索とGroverの違い(Oracleを1回呼ぶ費用を1とする)
候補数N古典探索Grover(理想的な規模)見え方
4平均約2回/最悪4回約√4回の規模差は小さい。教材向き
1,000,000平均約500,000回/最悪1,000,000回約1,000回の規模大きなNで差が出る
4候補・1反復・100 shotsの中身
言葉何を数えるかこの例
候補数 N重ね合わせに入る候補の数4個: 00,01,10,11
Grover反復Oracle→拡散のまとまり1回
shot回路1回+測定1回100回
最終結果100回の測定を集計した分布理想なら10が約100%
層この章の例問い
問題4候補から条件一致を探す何を解くか
判定関数左=1かつ右=0なら1候補をどう判定するか
アルゴリズム均等化→印付け→増幅→測定どんな手順で見つけるか
量子回路H、Oracle、拡散どのゲート列で実行するか
OpenQASMh、x、cz…回路をどう文字で書くか
図 19問題からOpenQASMまでの5つの層

15.2 判定関数f(x)を4行で確定する

条件は『q[0]=1かつq[1]=0』
候補x=q[0]q[1]左は1?右は0?f(x)
00いいえはい0
01いいえいいえ0
10はいはい1 ← 条件一致
11はいいいえ0

15.3 X–CZ–Xで10だけを印付けする

CZは11の振幅だけ符号反転します。10を印付けたいので、最初にq[1]へXをかけて10を11へ一時的に移し、CZで符号反転し、最後のXで候補ラベルを10へ戻します。他の候補も一時的に入れ替わりますが、CZに当たるのは元の10だけです。

10へ位相印を付ける完全なプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
output bit[2] result;
qubit[2] q;
reset q;
h q;
x q[1];
cz q[0], q[1];
x q[1];
result = measure q;
reset q;2qubitを|00>へ初期化
h q;00、01、10、11を各振幅+1/2で準備
x q[1];印を付けたい10を、一時的に11の位置へ移す
cz q[0], q[1];11の位置にある元の10だけ符号反転
x q[1];候補ラベルを元へ戻す
measureOracleだけでは、まだ4候補が各25%

判定表から位相印まで

候補10を一貫して強調し、規則・ゲート・振幅を対応させます。

  1. STEP 1f(10)=1を判定する

    4候補へ同じ条件『左=1、右=0』を当てると、10だけが1です。

    条件一致
    10
  2. STEP 2Hで4候補を均等にする

    2qubitへHをかけると、4振幅はすべて+1/2です。各確率は25%です。

    各候補の確率
    25%
    h q;
  3. STEP 3X–CZ–Xを実行する

    q[1]のXで10を11へ移し、CZで符号反転し、最後のXでラベルを戻します。

    x q[1];cz q[0], q[1];x q[1];
  4. STEP 410の振幅だけ−1/2になる

    候補ラベルは元の順です。変わったのは10の振幅の向きだけなので、直後の測定確率はまだ各25%です。

    状態カード
    [1/2, 1/2, −1/2, 1/2]

理解チェック

  1. 判定関数f(x)は何を返すか。

    答えを見る: 判定関数f(x)は何を返すか。

    候補xが条件を満たせば1、満たさなければ0を返す。

  2. なぜ10を印付ける前後にx q[1];を置くのか。

    答えを見る: なぜ10を印付ける前後にx q[1];を置くのか。

    CZが印付けする11の位置へ10を一時的に移し、CZ後に候補ラベルを元へ戻すため。

  3. Oracle直後の10の測定確率はいくつか。

    答えを見る: Oracle直後の10の測定確率はいくつか。

    25%。振幅は+1/2から−1/2へ変わるが、絶対値の2乗は1/4のまま。

  4. Oracleは探索前から答え10を出力する箱か。

    答えを見る: Oracleは探索前から答え10を出力する箱か。

    違う。4候補へ適用できる判定規則を回路化した部品。

CHAPTER 16

Groverを4候補で完全計算する

−1/2の印を、10が100%になる振幅へ変える

16.1 resetからmeasureまでを1行ずつつなぐ

ここでは、最初のresetから最後のmeasureまで、コードの各行で『何が起きるか』と『なぜそうなるか』を切れ目なく追います。候補の順番は[00,01,10,11]、振幅の並びもこの順で固定します。

最初のresetから測定までの完全なQASM

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";

output bit[2] result;
qubit[2] q;

reset q;

// 均等化
h q;

// Oracle: 10を印付け
x q[1];
cz q[0], q[1];
x q[1];

// Diffusion
h q;
x q;
cz q[0], q[1];
x q;
h q;

result = measure q;

完全計算:コードを1行ずつ追う

ここがこの章の詳説です。コードの実行順を保ったまま、状態ラベル、位相、干渉を順に追います。

  1. LINE 1|00>から始める

    q[0]とq[1]を|00>へそろえます。振幅は[1,0,0,0]で、まだ測定すれば00が100%です。後の計算を比較できるよう、出発点を固定します。

    測定
    00が100%
    reset q;
  2. LINE 24候補を均等化する

    2量子ビットの両方へHをかけます。0が0と1へ分かれるので、全組み合わせの振幅が+1/2になります。これが均等化です。

    状態カード
    [+1/2,+1/2,+1/2,+1/2]
    h q;
  3. LINE 310を11の位置へ移す

    q[1]だけを反転するので、00↔01、10↔11です。元の10は一時的に11へ来ます。状態の場所は動きますが、振幅の符号はそのままです。CZが11だけを見られるから、この移動が必要です。

    元の正解
    10→11
    x q[1];
  4. LINE 411だけ位相反転する

    CZは状態ラベルを移動させず、11の振幅だけを−倍します。そこにいるのは元の10の振幅なので、元の10だけが+1/2から−1/2になります。確率ではなく向きだけが変わります。

    CZの規則
    11だけ符号反転
    cz q[0], q[1];
  5. LINE 5ラベルを戻してOracle終了

    もう一度q[1]を反転すると、11にいたマイナス振幅が10へ戻ります。Oracleは正解10だけの位相を反転しましたが、絶対値は同じなので4候補の確率はまだ25%ずつです。

    状態カード
    [+1/2,+1/2,−1/2,+1/2]
    x q[1];
  6. LINE 6位相差を4成分へ展開する

    Hは2つのqubitに同時にかかります。1qubitの公式で4つの寄与を作り、最後に同じ出力列どうしを足します。図では、各行が『元の1つの項の寄与』、各列が『最後に合計する出力』です。

    h q;
  7. LINE 7両bitを反転し、位相ごと移す

    00↔11、01↔10です。振幅の符号は消えず、その振幅について移動します。たとえば01の−は10の−になります。Xはラベルを変えますが、位相印を消す操作ではありません。

    X後
    [+1/2,+1/2,−1/2,+1/2]
    x q;
  8. LINE 8現在の11を反転する

    Diffusion側のCZも状態を動かしません。現在の11の+だけを−にします。Oracleでは元の10を11へ運んでいたのに対し、ここではDiffusionの基準位置を反転して、平均まわりの反転を作る一部として使います。

    CZ後
    [+1/2,+1/2,−1/2,−1/2]
    cz q[0], q[1];
  9. LINE 9ラベルをもう一度戻す

    再び両bitを反転します。符号付き振幅が一緒に移るので、11の−は00へ、10の−は01へ移ります。次の最後のHがこの配置をまとめて干渉させます。

    X後
    [−1/2,−1/2,+1/2,+1/2]
    x q;
  10. LINE 10最後の干渉で10だけ残す

    各入力成分をHで展開し、列ごとに足します。00、01、11の列はプラスとマイナスが打ち消し合います。10の列だけは4本すべてが−1/4になり、完全に強め合って−1になります。

    最終状態
    [0,0,−1,0]
    h q;
  11. LINE 1110を測定する

    測定確率は振幅の絶対値の2乗です。00、01、11は0、10は|−1|²=1なので、理想的には10が100%で出ます。Oracleの位相差が、Diffusionの干渉によって測定可能な振幅差へ変わりました。

    確率
    P(10)=1
    result = measure q;
復習用:5つのチェックポイント
チェック地点振幅 [00,01,10,11]確認すること
reset後[1,0,0,0]既知の|00>から始める
均等化後[+1/2,+1/2,+1/2,+1/2]4候補は各25%
Oracle後[+1/2,+1/2,−1/2,+1/2]10だけ位相反転。確率はまだ各25%
Diffusion後[0,0,−1,0]10だけ振幅の大きさが1
測定10理想確率100%

16.2 同じDiffusionを『平均の鏡』で確認する

Oracle後の平均はm=(1/2+1/2−1/2+1/2)/4=1/4です。『平均まわり』とは、平均から上へある値を、同じ距離だけ平均の下へ移すことです。反対に平均より下の値は、同じ距離だけ上へ移ります。代表式は、新振幅=2m−古い振幅です。

候補古い振幅x2m−x(2m=1/2)新振幅(代表)
001/21/2−1/20
011/21/2−1/20
10 正解−1/21/2−(−1/2)1
111/21/2−1/20
図 204つの振幅を、平均1/4を鏡として反対側へ移す

16.3 反復しすぎると成功率は下がる

一般には候補数N、正解数Mに対して、およそ√(N/M)回の規模でOracleと拡散を繰り返します。しかし成功振幅は上がり続けず、行き過ぎると下がります。このN=4、M=1の例では1回が最適です。

Oracle+拡散の回数10の理想確率判断
0回25%まだ均等
1回100%ここで測る
2回25%行き過ぎ

理解チェック

  1. Oracle直後の状態カードは何か。

    答えを見る: Oracle直後の状態カードは何か。

    [1/2,1/2,−1/2,1/2]。候補順は[00,01,10,11]。

  2. Oracle後の4振幅の平均mはいくつか。

    答えを見る: Oracle後の4振幅の平均mはいくつか。

    1/4。

  3. 10の代表振幅2m−xを計算するといくつか。

    答えを見る: 10の代表振幅2m−xを計算するといくつか。

    2×1/4−(−1/2)=1。掲載回路の直接の値−1とは全体位相だけが異なる。

  4. この2bit例でOracleと拡散を2回行うべきか。

    答えを見る: この2bit例でOracleと拡散を2回行うべきか。

    行わない。1回で10が100%になり、2回目は成功率を25%へ下げる。

CHAPTER 17

QUBOからQAOA回路へ

得点を位相へ写すCostと、出やすさへ変えるMixerを分けて読む

QAOAは1個のゲート名ではなく、同じ流れを繰り返す枠組みです。最初に全候補を同じ割合で用意し、Costで『良い候補と悪い候補の向き』を変え、Mixerで候補どうしを混ぜ、測定結果を見ます。γとβを変えるのは回路の外側の古典プログラムです。

17.1 第1幕: 4候補へ得点を付ける

2人を別グループへ分ける最小のMaxCutを考えます。x0とx1は0または1で、0ならグループA、1ならBです。別グループなら得点1、同じなら0です。正解は01と10の2個です。

候補x0x1グループ同じ/別得点C
00A・A同じ0
01A・B別1 ← 最適
10B・A別1 ← 最適
11B・B同じ0

17.2 QUBO式へしても、4行の得点は変わらない

この得点はC(x)=x0+x1−2x0x1と書けます。難しい式として暗記せず、4候補を代入して上の表と同じになることを確認します。

x0x1x0+x1−2x0x1C
000+0−2×0×00
010+1−2×0×11
101+0−2×1×01
111+1−2×1×10
発展QUBOからIsing式とRZの符号を導く本文のCost→Mixerを理解してから、数式で同じ回路を確かめたい人向けです。

17.3 0/1をZの+1/−1へ写す

量子回路のZは、|0>へ+1、|1>へ−1を対応させます。そこでz=1−2x、逆にx=(1−z)/2と置きます。代入するとC=(1−z0z1)/2です。候補は変わらず、数字の書き方だけが変わります。

x0x1z0z1z0z1の積(1−z0z1)/2得点
00+1,+1+100
01+1,−1−111
10−1,+1−111
11−1,−1+100
図 21得点表からCost回路まで、候補の意味を変えずに翻訳する

17.4 第2幕: Costの位相をMixerで確率へ変える

図 22Costは得点を確率ではなく時計の向きへ写す
γ=π/2のCostは、指数関数を計算できなくてもこの2行で追える
得点Ce^{-iγC}振幅の向き
0(00・11)e^0 = 10度のまま
1(01・10)e^{-iπ/2} = −i−90度へ回す

γ=π/2、β=π/8を1回だけ実行する

この角度では、最適候補01と10へ確率がすべて集まります。

  1. STEP 1Hで4候補を均等にする

    reset後の|00>から、全振幅が+1/2の均等状態を作ります。

    状態
    [1/2,1/2,1/2,1/2]
    h q;
  2. STEP 2Cost(π/2)で得点1へ−90度の位相

    この例では『得点0なら時計を回さない、得点1なら−90度回す』と決めます。00・11は0度、01・10は−90度です。4本の長さはすべて1/2なので、確率はまだ各25%です。RZの符号が−になる理由は上の発展欄で確認できます。

    γ
    π/2
    cx q[0], q[1];rz(-gamma) q[1];cx q[0], q[1];
  3. STEP 3Mixer(π/8)で位相差を確率へ変える

    各qubitへRX(π/4)をかけると、00と11の振幅は0になり、01と10の振幅の大きさは1/√2になります。

    β
    π/8
    平均得点
    1
    rx(2 * beta) q;
  4. STEP 4測定して得点を計算する

    理想的には01か10だけが出ます。どちらも得点1なので、この角度の平均得点は1です。

    最大得点
    1

2変数・1層QAOAの完全なOpenQASM

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
input angle gamma;
input angle beta;
output bit[2] result;
qubit[2] q;
reset q;
h q;
// U_C(gamma): e^{-i gamma C}
cx q[0], q[1];
rz(-gamma) q[1];
cx q[0], q[1];
// U_B(beta)
rx(2 * beta) q;
result = measure q;
reset q;QAOA層を|00>から開始
h q;4候補を均等に準備
cx; rz(-gamma); cx;規約U_C=e^{-iγC}に一致するCost
rx(2 * beta) q;Mixer。RXの角度は2β
gamma=pi/2, beta=pi/8この例では01/10が各50%
measure候補bit列を古典側へ返す

17.5 角度を更新するのは回路の外側

図 23QAOAで量子回路と古典処理が交互に働く流れ

理解チェック

  1. 候補01をC=x0+x1−2x0x1へ代入した得点はいくつか。

    答えを見る: 候補01をC=x0+x1−2x0x1へ代入した得点はいくつか。

    0+1−2×0×1=1。

  2. 規約U_C=e^{-iγC}で、なぜRZの角度を−γにするか。

    答えを見る: 規約U_C=e^{-iγC}で、なぜRZの角度を−γにするか。

    C=(I−ZZ)/2なので、共通位相を除くCostはe^{+iγZZ/2}。CX-RZ(θ)-CXはe^{-iθZZ/2}を作るため、θ=−γとする。

  3. γ=π/2、β=π/8の理想測定分布は何か。

    答えを見る: γ=π/2、β=π/8の理想測定分布は何か。

    01が50%、10が50%、00と11は0%。

  4. γとβを次の値へ更新する処理は通常どこで行うか。

    答えを見る: γとβを次の値へ更新する処理は通常どこで行うか。

    OpenQASM回路の外側にある古典オプティマイザで行う。

CHAPTER 18

OpenQASM 2→3移行とデバッグの型

意味を保って書き換え、文法・論理・実機・ノイズを順に切り分ける

この章での『正しい』には4段階あります。文字として読める、量子状態の計算が意図どおり、装置の制約内で実行できる、実機でも許容範囲に収まる、の順です。前の段階が通っていないのに次の段階を調べても、原因は見つかりません。

18.1 同じBell回路を、2つの版で最後まで読む

移行は単語の一括置換ではありません。まず古いコードが作る状態と理想分布を確定し、その意味を新しい宣言・測定構文で書き直します。題材はHとCXで00/11を作る同じBell回路です。

意味を保ったまま、書き方だけを移す

左と右で同じBell状態と00/11の分布を作ります。変わる行だけを対応させてください。

移行前 · OpenQASM 2.0

完全なBellプログラム

OpenQASM 2.0program
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0], q[1];
measure q -> c;
qreg q[2];量子registerを2個宣言
creg c[2];古典registerを2個宣言
h; cx;Bell状態を作る論理は3でも同じ
measure q -> c;矢印で測定結果をcへ保存

移行後 · OpenQASM 3.1

完全なBellプログラム

OpenQASM 3.1program
OPENQASM 3.1;
include "stdgates.inc";
output bit[2] result;
qubit[2] q;
reset q;
h q[0];
cx q[0], q[1];
result = measure q;
qubit[2] q;qregの代わりにqubit型を宣言
output bit[2] result;返す古典値をbit型として明示
reset q;宣言直後は未定義なので、意図する開始状態|00>を明示
h; cx;作りたいBell状態は変えない
result = measure q;代入式として測定結果を保存

Bell回路を意味ごとに移行する

各段階で『変わる文法』と『変えない回路の意味』を分けます。

  1. STEP 1版と標準ライブラリを替える

    2.0のqelib1.incから、3.1のstdgates.incへ替えます。使いたいhとcxが対象版で定義されることを確認します。

    OPENQASM 3.1;include "stdgates.inc";
  2. STEP 2型で宣言し、開始状態も明示する

    qregはqubit、cregはbitへ移します。3.1では返したいbitへoutputを付けられます。さらに宣言直後のqubitは状態未定義なので、Bell回路の意味を保つためreset q;で|00>を明示します。

    output bit[2] result;qubit[2] q;reset q;
  3. STEP 3HとCXの論理は保つ

    Bell状態を作るh q[0];とcx q[0],q[1];は同じです。制御と標的を変えないことが重要です。

    理想状態
    (|00>+|11>)/√2
    h q[0];cx q[0], q[1];
  4. STEP 4測定を代入式へ移す

    measure q -> c;をresult = measure q;へ移します。保存先の幅2と測定対象2qubitが一致することを確認します。

    理想分布
    00:50%, 11:50%
    result = measure q;
よく使う移行対応
OpenQASM 2OpenQASM 3.1確認する意味
OPENQASM 2.0;OPENQASM 3.1;対象版
include "qelib1.inc";include "stdgates.inc";ゲート名の定義元
qreg q[2];qubit[2] q; + reset q;量子データ2個と|00>の開始状態
creg c[2];bit[2] c;古典データ2個
measure q -> c;c = measure q;測定結果の保存
if (c==1) x q[0];if (c == 1) { x q[0]; }古典条件の分岐

18.2 エラーを3層へ分ける

図 24不具合を上から順に分類する4つの問い

18.3 3つの故障を、同じ順番で診断する

症状から原因を1層ずつ狭める

ソース/フロントエンド、論理、実機制約の代表例を1件ずつ修正します。

  1. CASE Aソース: qubit宣言の;がない

    パーサがqubit[2] qの行付近で止まります。まず失敗行の文末を確認し、;を追加します。状態計算や実機を疑う段階ではありません。

    分類
    ソース/フロントエンド
    qubit[2] qh q[0];
  2. CASE B論理: CXの制御と標的が逆

    h q[0]の後にcx q[1],q[0]と書くと、制御q[1]は0なのでCXが働きません。結果は00/10で、狙った00/11ではありません。cx q[0],q[1]へ直します。

    分類
    論理エラー
    h q[0];// 誤り: 制御と標的が逆cx q[1], q[0];
  3. CASE C実機制約: 物理0と2が直接つながらない

    理想シミュレータでは正しいのに実機が拒否します。ISAが0–1–2だけなら、0と2の直接CXは使えません。対象実機へトランスパイルし、SWAPを含むroutingを確認します。

    分類
    実機制約エラー
症状最初に見る層最小テスト
parse error版、;、括弧、宣言失敗行まで削り1行ずつ戻す
undefined gateincludeと標準ゲート名最小の1ゲートだけparse
結果が逆/候補が違う制御/標的、ゲート順、bit順片方だけXの回路
50:50のはずが必ず0H、測定基底、状態カード1ゲートずつ状態を更新
実機だけ拒否ISA、接続、対応機能対象実機へトランスパイル
少数の理想外結果shotsとノイズ理想シミュレータと比較

18.4 デバッグの固定手順

  1. 1期待する入力、各ゲート後の状態カード、理想測定分布を先に書く。
  2. 2コードを最小化し、対象版でparseと静的検証を通す。
  3. 3理想シミュレータで理想分布と一致するか確認する。
  4. 4片方だけXを置き、結果文字列のbit表示順を確認する。
  5. 5対象実機へトランスパイルし、配置、追加SWAP、基礎ゲート、深さを確認する。
  6. 6最後に実機結果を理想分布と比較し、有限shotsとノイズを調べる。

18.5 マスター制作と合格基準

制作課題必須成果物
A 量子コイントス入力角theta、RYの理想確率、shotsの揺れ、完全QASM
B Bell相関テスター4成分状態、Z/X基底の予測、理想分布、完全QASM
C 2bit Groverf(x)表、変更可能なOracle、全振幅計算、完全QASM
D 2変数QAOA得点表、QUBO/Ising、Cost/Mixer、外側の角度更新
E 移行・デバッグQASM2→3の差分、3層の故障、診断記録、修正版
どの制作課題を選んでも、5観点すべてを満たす
観点未達合格マスター
予測実行後の結果だけ実行前に理想分布を書く各ゲート後の状態まで根拠を示す
コード断片または未parse対象版でparseできる完全QASM各行と状態変化を対応させる
検証実機結果だけ理想シミュレータと比較bit順・shots・ノイズを別々に検証
境界全処理をQASMと説明回路内外を区別入力、shots、最適化、トランスパイルの担当を図示
説明用語だけを列挙数字と図で因果を説明別の入力や条件にも同じ方法を適用

理解チェック

  1. OpenQASM 2のmeasure q -> c;は、3.1でどう書けるか。

    答えを見る: OpenQASM 2のmeasure q -> c;は、3.1でどう書けるか。

    c = measure q;と代入式で書ける。

  2. コードがparseできるが00/10しか出ないBell回路は、まず何エラーを疑うか。

    答えを見る: コードがparseできるが00/10しか出ないBell回路は、まず何エラーを疑うか。

    論理エラー。Hを置いたqubitとCXの制御/標的を確認する。

  3. 理想シミュレータでは正しいが実機がCXを拒否した。次に何を見るか。

    答えを見る: 理想シミュレータでは正しいが実機がCXを拒否した。次に何を見るか。

    対象実機のISA、特に物理qubitの接続と基礎ゲートを確認し、トランスパイルする。

  4. マスター成果物に、コード以外で最低限必要なものは何か。

    答えを見る: マスター成果物に、コード以外で最低限必要なものは何か。

    実行前の予測、状態変化、理想分布、回路外処理、理想と実機の差を説明する検証記録。

付録 A

最小用語集

用語この本での意味
qubit測定前の状態を振幅で記録し、通常測定で0/1を返す量子情報単位
振幅確率を計算する前の数。絶対値の2乗が確率
H[a,b]を[(a+b)/√2,(a−b)/√2]へ変えるゲート
Z[a,b]を[a,−b]へ変えるゲート
干渉複数振幅が同じ出力振幅の足し引きへ入り、大きさが変わること
Z基底|0>と|1>を区別する通常測定
X基底|+>と|->を区別する測定。H後に通常測定
CX制御が1の成分で標的へXを適用する2qubitゲート
もつれ全体状態を各qubit独立の状態として表せない状態
shot準備から測定までの量子プログラム全体の独立1回実行
Oracle候補が条件を満たすかを回路で判定し、位相印を付ける部品
QUBO0/1変数の一次・二次式で表した最適化問題
QAOACostとMixerを使い、古典側で角度を更新するゲート型アルゴリズム

付録 B

ゲート早見表

ゲートOpenQASM最初に確認する役割
Xx q;|0>と|1>を交換
Hh q;和と差で振幅を作り直す
Zz q;1側振幅の符号を反転
CXcx a,b;aが1の成分でbをX反転
RYry(theta) q;0/1の出やすさを実数振幅で動かす
RXrx(theta) q;出やすさを動かし、1側へ複素位相も付ける
RZrz(theta) q;Z基底確率を保って相対位相を動かす
RZZcx; rz(theta); cx;2qubitが同じ組か違う組かで位相を分ける
SWAPswap a,b;2qubitの状態を交換

付録 C

数学メモ

  • •1/√2 ≈ 0.707、(1/√2)² = 1/2。
  • •確率の合計は1。1qubitの実数振幅ならa²+b²=1。
  • •負の振幅は負の確率ではない。確率は振幅の絶対値の2乗。
  • •H[a,b]=[(a+b)/√2,(a−b)/√2]。
  • •Grover拡散の学習用計算: 新振幅=2×全振幅の平均−古い振幅。

付録 D

学習チェックリスト

  • X/H/Zを状態カードで計算できる
  • H-Z-Hで0側と1側の足し引きを書ける
  • Z基底とX基底を回路で区別できる
  • CXの4入力を暗記でなく規則から答えられる
  • Bell回路の4成分状態を追える
  • OpenQASMの宣言・ゲート・測定を書ける
  • 中間測定とshotsを区別できる
  • Oracleが答え生成器でない理由を説明できる
  • 2bit Groverの振幅を全計算できる
  • QUBOとQAOA回路を区別できる
  • 論理回路と実機向け回路を区別できる
  • RX・RY・RZ・RZZが何を変え、何をすぐには変えないか説明できる

付録 E

公式資料

検討中の課題から、話しましょう。

量子計算とAIが効く課題なのか、既存手法と何が違うのか。まだ決めきれていない段階で構いません。

課題と制約、評価基準を一緒に整理するところから始めます。