忍者ブログ
統計、機械学習、AIを学んでいきたいと思います。 お役に立てば幸いです。

【Qiskit】Hゲートで重ね合わせ状態を作ろう!1量子ビットの確率実験

前回は、何も操作しない初期状態の量子ビットを測定すると、必ず 0(100%)になることを確認しました。今回はついに、量子コンピュータの真骨頂である「Hゲート(アダマールゲート)」を使って、量子を「確率の波(重ね合わせ状態)」に変換する実験をしてみます!

1. サンプルコード

量子ビットにHゲートを適用し、確率の波を作ってから測定するコードです。

from qiskit import QuantumCircuit
from qiskit.providers.basic_provider import BasicSimulator

# 1量子ビット、1古典ビットを準備
qc = QuantumCircuit(1, 1)

# Hゲート(アダマールゲート)を適用して「確率の波」にする
qc.h(0)

# 測定
qc.measure(0, 0)

# 回路図をテキスト形式で出力
print("--- 回路図 ---")
print(qc.draw(output='text'))

# シミュレータで1000回実行
simulator = BasicSimulator()
result = simulator.run(qc, shots=1000).result()
counts = result.get_counts()

print("\n--- 実行結果 ---")
print(f"実行結果: {counts}")

2. 実行結果と回路図

上記のコードを実行すると、次のような回路図と結果が得られます。

--- 回路図 ---
     ┌───┐┌─┐
  q: ┤ H ├┤M├
     └───┘└╥┘
c: 1/══════╩═
           0 

--- 実行結果 ---
実行結果: {'1': 463, '0': 537}

3. 解説:ついに重ね合わせ状態ができた!

実行結果を見ると、先ほどまで 100% だった 0 だけでなく、1 もほぼ半々の確率(この時は463回と537回)で出現しています!

  • Hゲートの物理的効果:極低温で静止していた純粋な |0> の状態に対し、外部から絶妙なエネルギー(パルス)を加えることで、状態をぐるっと回転させました。
  • 確率の波の誕生:これにより、量子は「0 でもあるし 1 でもある」という確率の波(重ね合わせ状態)に変換されます。
  • 測定による収縮:その波の状態のまま測定器にかけることで、毎回ランダムに 01 が決定されるようになります。
Hゲートによって量子が「波」になり、ついにランダムな確率の世界が姿を現しました!
この確率の波こそが、量子コンピュータが並列計算を行える最大の原動力です。
PR

【Qiskit】1量子ビットの測定実験:「何もしないと0」の物理的意味

量子コンピュータのコードを書くとき、初期状態の量子ビットをそのまま測定するとどうなるでしょうか?今回は、あえて操作を加えずに 1量子ビット を定義して測定するシンプルな実験と、その裏にある物理的な意味を解説します。

1. サンプルコード

1量子ビットと1つの古典ビットを準備し、Hゲートなどの操作を行わずにそのまま測定するコードです。

from qiskit import QuantumCircuit
from qiskit.providers.basic_provider import BasicSimulator

# 1量子ビット、1古典ビットを準備
qc = QuantumCircuit(1, 1)

# (操作を加えずにそのまま測定)
qc.measure(0, 0)

# シミュレータで1000回実行
simulator = BasicSimulator()
result = simulator.run(qc, shots=1000).result()
counts = result.get_counts()

print(f"実行結果: {counts}")

2. 実行結果

上記のコードを実行すると、何度(何回shotsを回しても)結果は必ず以下のようになります。

実行結果: {'0': 1000}

3. 解説:なぜ「1」は出ないのか?

「量子力学=ランダムに確率で変わるもの」というイメージがあると 1 も混ざりそうになりますが、ここには明確な理由があります。

  • 初期状態は純粋な |0>:実際のハードウェア(超伝導回路など)は極低温に冷却され、余計なエネルギーが奪われた状態(基底状態)からスタートするため、何も操作しなければ 100% 確実な 0 です。
  • 「波」にするにはエネルギーが必要:Hゲート(アダマールゲート)などで外部からエネルギーを加え、量子を揺らがせて「確率の波(重ね合わせ)」に変換して初めて、01 が確率的に出現するようになります。
  • 測定と初期状態の違い:初期状態の 0 は静まり返った純粋な状態ですが、測定後の 0 は「波」の状態で漂っていたものが測定の衝撃で強制的に収縮させられた結果です。
量子は「何もしなければピシッと0」!
Hゲートなどのエネルギー操作で「波」に変換して初めて、量子らしい確率の世界が始まります。

【Qiskit】CNOTゲートの仕組みを徹底検証!制御ビットで対象が変わる動きを確認しよう

前回までに、1量子ビットでの重ね合わせと測定、そしてQiskit標準シミュレータ(BasicSimulator)を使った実行方法を学びました。

今回はステップアップして、**2量子ビットを使った量子プログラミングの基本パーツ「CNOTゲート(制御NOTゲート)」**の動きを検証してみたいと思います。CNOTゲートが「条件によって標的を反転させる」という挙動を、実際のコードとシミュレーション結果から確かめてみましょう。

1. CNOTゲートとは?

CNOTゲートは、量子コンピュータにおける「もし〜なら〜する(if文)」のような役割を持つ超重要パーツです。2つの量子ビットを使い、次のようなルールで動作します。

  • 制御ビット(Control):条件を決める側の量子ビットです。
  • 標的ビット(Target):制御ビットの状態に応じて値が反転するかどうか変わる側の量子ビットです。
  • 制御が「0」の場合:標的ビットは何もしません(そのまま)。
  • 制御が「1」の場合:標的ビットの値を反転(0なら1に、1なら0に)させます。

2. 比較検証のサンプルコード

制御ビットが「0」の場合と「1」の場合で、CNOTゲートを通った後に標的ビットがどう変わるのかを比較するコードを作成します。

from qiskit import QuantumCircuit
from qiskit.providers.basic_provider import BasicSimulator

simulator = BasicSimulator()

print("=== パターンA: 制御ビットが「0」の場合 ===")
qc_a = QuantumCircuit(2, 2)
# 制御ビット(0番目)は何もしない(初期状態の「0」のまま)
qc_a.cx(0, 1)  # CNOTゲート適用(制御=0, 標的=1)
qc_a.measure(0, 0)
qc_a.measure(1, 1)

result_a = simulator.run(qc_a, shots=1000).result()
print(f"回路図:\n{qc_a.draw(output='text')}")
print(f"実行結果: {result_a.get_counts()}\n")

print("=== パターンB: 制御ビットが「1」の場合 ===")
qc_b = QuantumCircuit(2, 2)
qc_b.x(0)      # Xゲートで制御ビット(0番目)を「1」にする
qc_b.cx(0, 1)  # CNOTゲート適用(制御=0, 標的=1)
qc_b.measure(0, 0)
qc_b.measure(1, 1)

result_b = simulator.run(qc_b, shots=1000).result()
print(f"回路図:\n{qc_b.draw(output='text')}")
print(f"実行結果: {result_b.get_counts()}")

3. 実際の実行結果と回路図

ターミナルでスクリプトを実行すると、それぞれのパターンで以下のような回路図と実行結果が得られます。

=== パターンA: 制御ビットが「0」の場合 ===
回路図:
         ┌─┐   
q_0: ──■──┤M├───
     ┌─┴─┐└╥┘┌─┐
q_1: ┤ X ├─╫─┤M├
     └───┘ ║ └╥┘
c: 2/══════╩══╩═
           0  1 
実行結果: {'00': 1000}

=== パターンB: 制御ビットが「1」の場合 ===
回路図:
     ┌───┐    ┌─┐   
q_0: ┤ X ├──■──┤M├───
     └───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
         └───┘ ║ └╥┘
c: 2/═══════════╩══╩═
                0  1 
実行結果: {'11': 1000}

4. 結果の解説:CNOTゲートの動き

得られた結果を整理してみましょう。

  • パターンA(制御が「0」):制御ビットが 0 のため、標的ビットは反転せずそのまま 0 を維持しました。そのため、結果はすべて 00(1,000回)になっています。
  • パターンB(制御が「1」):Xゲートで制御ビットを 1 にしたため、CNOTゲートが働いて標的ビットが反転(0 から 1 へ)しました。その結果、両方とも 1 になり、結果はすべて 11(1,000回)になっています。
CNOTゲートの「条件分岐」動作を完全確認!
制御ビットの値(0か1か)によって、もう一方の標的ビットの運命が変わる様子がシミュレーションでハッキリと証明できました。

まとめ

今回は、2量子ビットの基本操作であるCNOTゲートの挙動をコードとシミュレーションで確認しました。制御ビットの状態に応じて標的が変わる仕組みがよく分かったと思います。このCNOTゲートの組み合わせこそが、量子もつれ(エンタングルメント)を生み出す鍵になります!


【Qiskit】追加インストールなし!標準シミュレータで量子回路を実行してみよう

前回までに、Hゲートを使った「重ね合わせ」の作り方と、結果を取り出すための「測定(Measure)」の仕組み、そして回路図の見方を学びました。

今回は、追加のパッケージ(qiskit-aerなど)をわざわざインストールしなくても使えるQiskit標準のシミュレータ(BasicSimulator)を利用して、実際に回路を動かし、確率的な計算結果を取得してみたいと思います。

1. 実行用サンプルコード

以下のコードを sample_run.py として保存して実行します。Qiskitのコア機能だけで完結するため、環境構築が非常にシンプルです。

from qiskit import QuantumCircuit
from qiskit.providers.basic_provider import BasicSimulator

# 1量子ビットと、測定結果を記録する古典ビットを1つ準備
qc = QuantumCircuit(1, 1)

# Hゲートで重ね合わせ状態を作成
qc.h(0)

# 0番目の量子ビットを測定し、0番目の古典ビットに保存
qc.measure(0, 0)

# Qiskit標準の内蔵シミュレータを準備
simulator = BasicSimulator()

# 回路を1000回実行(シミュレーション)
result = simulator.run(qc, shots=1000).result()

# 実行結果から「0」と「1」が出た回数を取得
counts = result.get_counts()

print(f"実行結果: {counts}")

2. 実際の実行結果

ターミナルでこのスクリプトを実行すると、以下のような結果が出力されます。

% python sample_run.py
実行結果: {'1': 508, '0': 492}

3. 結果の解説:なぜこの数値になるのか?

得られた結果を詳しく見てみましょう。

  • 0 が 492回、1 が 508回という内訳になっています。合計するとちょうど 1,000回(shots=1000)の試行が行われていることがわかります。
  • Hゲート(アダマールゲート)を通った量子ビットは、「0である確率」と「1である確率」がちょうど半々(50%ずつ)の重ね合わせ状態になります。
  • それを1,000回測定したため、理論値である 50:50(各500回前後)に非常に近い、確率的な揺らぎを持った数値が再現されました。
量子コンピュータの確率的振る舞いをコードで実証!
ただの理論だけでなく、シミュレーションを通じて「半々の確率で0と1がランダムに出現する」という量子力学の現象を手元のPCで確認できました。

まとめ

今回は、Qiskit標準の BasicSimulator を使って、重ね合わせ回路の実行から統計データの取得までを体験しました。回路を作って測定し、結果を数字として受け取るという、量子プログラミングの基本サイクルがこれでバッチリ完了です!



【Qiskit】量子回路の基本:回路構築から「測定」の前まで

量子コンピュータのプログラミングでは、量子ゲートを使って回路を構築するだけでは計算結果を得ることができません。量子ビットは計算が終わるまで確率的に揺らぎ続けているため、最終的な結果を取り出すためには、必ず「測定(Measure)」という工程が必要になります。

1. 測定を含む量子回路の構築

Qiskitにおいて結果を確認するための回路を作成します。QuantumCircuit(1, 1) と記述することで、1つの量子ビットと、測定結果を書き込むための「1つの古典ビット」を準備します。この古典ビットを用意して測定を行わない限り、量子計算の結果を数値として読み出すことはできません。

from qiskit import QuantumCircuit

# 1量子ビットの回路と、測定結果を記録する古典ビットを1つ準備
qc = QuantumCircuit(1, 1)

# Hゲートで重ね合わせ状態を作成
qc.h(0)

# 0番目の量子ビットを測定し、その結果を0番目の古典ビットに保存
qc.measure(0, 0)

# 回路を描画
print(qc.draw(output='text'))

2. 実行結果(回路図)

ターミナルで実行すると、以下のように測定ゲート(M)が配置された回路図が表示されます。

% python sample_measure.py
     ┌───┐┌─┐
q: ┤ H ├┤M├
     └───┘└╥┘
c: 1/══════╩═
           0

3. 回路図の読み方と「0」の意味

この回路図には、重要な情報が可視化されています。

  • c: 1/ : 測定結果を保存するための古典的な記録領域です。ここへ情報を書き出すことではじめて、人間が結果を読み取れます。
  • ╩(二重線) : 測定(M)によって、量子情報が古典ビットへと「確定」して送られる様子を表しています。
  • 一番下の「0」 : これは「結果が0だった」という意味ではありません。「0番目の量子ビットの測定結果を、0番目の古典ビットという『宛先(ID)』に保存する」という接続指示を指しています。

このように、Qiskitで qc.measure(0, 0) を実行することで、量子ビットの確率的な情報を「古典ビットという箱」に固定することができます。これによって、後続のシミュレータ実行時に「0」または「1」という確定した値として結果を得ることができるようになるのです。

量子コンピュータの「観測」プロセスを実装!
Hゲートで確率を作ったら、必ずMeasureで測定して結果を確定させる。これが量子プログラミングの基本です。

次のステップ

測定する場所が確保できたので、次回はいよいよシミュレータを使って、この回路を実際に動かし、統計的な結果(0と1の出現回数)を取得してみたいと思います。


        
  • 1
  • 2