diff --git a/translations/ja/algorithm-design/ansatz/ansatz.ipynb b/translations/ja/algorithm-design/ansatz/ansatz.ipynb
new file mode 100644
index 00000000..23873ec9
--- /dev/null
+++ b/translations/ja/algorithm-design/ansatz/ansatz.ipynb
@@ -0,0 +1,342 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "ansatz": {
+ "text": "参照演算子と変分形式の組み合わせで、探索する探索空間を記述する。",
+ "title": "Ansatz"
+ },
+ "variational": {
+ "text": "パラメーター化されたゲートを一定回数繰り返す層で、コスト関数を最小化するためにアルゴリズム中にゲートのパラメーターを最適化する。",
+ "title": "変分形式"
+ }
+ }
+ },
+ "source": [
+ "## Ansatzと変分フォーム\n",
+ "\n",
+ "すべての変分アルゴリズムの中心には、状態と状態の違いを分析するという重要なアイデアがあります。状態間の違いは、一連のパラメーターまたは変数から適切に動作するマッピング (たとえば、連続、微分可能) を通じて便利に関連付けられます。したがって、この名前が付けられました。\n",
+ "\n",
+ "はじめに、パラメーター化された回路を手作業で構築する方法を探ります。この回路を使って [*変分形式*](gloss:variational) を定義し、変分アルゴリズムが探索するパラメーター化された状態の集合を定義します。そして、この変分形式を参照状態に適用することで、 [*Ansatz*](gloss:ansatz) を構築します。\n",
+ "\n",
+ "また、この探索空間を探索する際に、速度と精度のトレードオフをどのように行うかを検討します。\n",
+ "\n",
+ "![Ansatz Workflow](images/ansatz_workflow.png)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## パラメーター化された量子回路\n",
+ "\n",
+ "変分アルゴリズムは、有限の $k$ 個のパラメーター $\\vec{\\theta} = (\\theta^0, \\ldots, \\theta^{k-1})$ に依存する量子状態 $|\\psi(\\vec{\\theta})\\rangle$ を探索・比較することで動作します。これらの状態は、パラメーター化された量子回路を用いて準備することができ、そのゲートは調整可能なパラメーターで定義されています。このパラメーター化された量子回路は、特定の角度に縛られることなく作成することが可能です:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit import QuantumCircuit, Parameter\n",
+ "\n",
+ "theta = Parameter(\"θ\")\n",
+ "\n",
+ "qc = QuantumCircuit(3)\n",
+ "qc.rx(theta, 0)\n",
+ "qc.cx(0, 1)\n",
+ "qc.x(2)\n",
+ "\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from math import pi\n",
+ "\n",
+ "angle_list = [pi / 3, pi / 2]\n",
+ "circuits = [qc.bind_parameters({theta: angle}) for angle in angle_list]\n",
+ "\n",
+ "for circuit in circuits:\n",
+ " display(circuit.draw(\"mpl\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 変分形式とAnsatz\n",
+ "\n",
+ "参照状態 $|\\rho\\rangle$ から目標状態 $|\\psi(\\vec\\theta)\\rangle$ へ反復最適化するために、変分アルゴリズムが探索するパラメーター化された状態の集合を表す変分形式 $U_V(\\vec{\\theta})$ を定義する必要があります:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "|0\\rangle \\xrightarrow{U_R} U_R|0\\rangle\n",
+ "\n",
+ "& = |\\rho\\rangle \\xrightarrow{U_V(\\vec{\\theta})} U_A(\\vec{\\theta})|0\\rangle \\\\[1mm]\n",
+ "\n",
+ "& = U_V(\\vec{\\theta})U_R|0\\rangle \\\\[1mm]\n",
+ "\n",
+ "& = U_V(\\vec{\\theta})|\\rho\\rangle \\\\[1mm]\n",
+ "\n",
+ "& = |\\psi(\\vec{\\theta})\\rangle \\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "パラメーター化された状態は、パラメーターに依存しない参照状態 $|\\rho\\rangle$ と、常にパラメーターに依存する変分形式 $U_V(\\vec{\\theta})$ の両方に依存していることに注意してください。 この2つを組み合わせたもの $U_A(\\vec\\theta) := U_V(\\vec\\theta)U_R$ をansatzと呼日ます。\n",
+ "\n",
+ "変分アルゴリズムが探索するパラメーター化された状態の集合を表現するために、このansatzを構築するとき、重要な問題に気づきます。次元性です。 $n$ 量子ビットのシステム(ヒルベルト空間)の構成空間には、膨大な数の量子状態が存在します。これを完全に探索するためには、扱いにくい数のパラメーターが必要になります。定量的には、その次元性は $D = 2^{2n}$ です。さらに悪いことに、探索アルゴリズムなどの実行複雑度は、この次元性によって指数関数的に増大し、文献ではしばしば次元の呪いと呼ばれている現象となります。\n",
+ "\n",
+ "この欠点に対処するために、最も関連性の高い状態のみを探索するような合理的な制約を変分形式に課すことが一般的です。効率的に切り捨てられたansatzを見つける研究は盛んに行われていますが、ここでは2つの一般的なデザインを取り上げることにします。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## ヒューリスティックAnsatzとトレードオフ\n",
+ "\n",
+ "次元数を制限するのに役立つ特定の問題に関する情報がない場合、 $2^{2n}$ 未満のパラメーターを持つ任意のパラメーター化された回路ファミリーを試すことができます。しかし、次のような考慮すべきトレードオフがいくつかあります:\n",
+ "\n",
+ "- **速度**: 探索空間を縮小することで、アルゴリズムの実行速度を向上させることができます。\n",
+ "- **精度**: ただし、探索空間を小さくすると、問題の実際の解を除外してしまい、最適な解が得られない可能性があります。\n",
+ "- **ノイズ**: 深い回路はノイズの影響を受けるため、ansatzの接続性、ゲート、ゲートフィデリティを実験する必要があります。\n",
+ "\n",
+ "品質(あるいは解きやすさ)と速度の間には基本的なトレードオフがあります:パラメーターが多ければ多いほど、正確な結果が得られる可能性が高くなりますが、アルゴリズムの実行にかかる時間は長くなってしまうのです。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### N-local 回路\n",
+ "\n",
+ "ヒューリスティックansatzで最も広く使われている例の1つが [N-local回路](https://qiskit.org/documentation/apidoc/circuit_library.html#n-local-circuits) です:\n",
+ "\n",
+ "- **効率的な実装**: N-local回路は、一般的にシンプルなローカルゲートで構成されており、少数の物理量子ビットを用いて量子コンピューター上で効率的に実装することができます。これにより、量子回路の構築や最適化が容易になります。\n",
+ "- **重要な相関関係をとらえる**: N-local ansatzは、少ないゲート数でも量子系における量子ビット間の重要な相関を捉えることができます。これは、ローカルゲートが隣接する量子ビットに作用し、量子ビット間にエンタングルメントを生じさせることができるためで、複雑な量子系をシミュレーションする上で重要な意味を持ちます。\n",
+ "\n",
+ "これらの回路は、以下のように交互に1回以上繰り返される回転層とエンタングルメント層で構成されています:\n",
+ "\n",
+ "- 各層は最大 $N$ 個のゲートで形成され、 $N$ は量子ビット数より小さくなければなりません。\n",
+ "- 回転層では、ゲートは互いに積み重ねます。[`RX`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.RXGate.html) や [`CRZ`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CRZGate.html) のような標準的な回転演算を使用することができます。\n",
+ "- エンタングルメント層には、エンタングルメントを作る [`とフォリ` ゲート ](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CCXGate.html) や [`CX`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CXGate.html#qiskit.circuit.library.CXGate) のようなゲートを使用できます。\n",
+ "- どちらの層も、パラメーター化することもしないこともできますが、少なくとも1つの層はパラメーターを含む必要があります。そうでなければ、1つもパラメーターがないことになり、変化が生まれません!\n",
+ "- オプションとして、回路の末尾に回転層を追加することもできます。\n",
+ "\n",
+ "例えば、 [`RX`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.RXGate.html) ゲートと [`CRZ`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CRZGate.html) ゲートで形成される回転ブロック、量子ビット $[0,1,2]$, $[0,2,3]$, $[4,2,1]$ $[3,1,0]$ に作用する [`トフォリ` ゲート](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CCXGate.html) で形成されるエンタングルメントブロックが各層2回の繰り返される $5$ 量子ビットの [`NLocal`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.NLocal.html) 回路を作ってみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import NLocal, CCXGate, CRZGate, RXGate\n",
+ "from qiskit.circuit import Parameter\n",
+ "\n",
+ "theta = Parameter(\"θ\")\n",
+ "ansatz = NLocal(\n",
+ " num_qubits=5,\n",
+ " rotation_blocks=[RXGate(theta), CRZGate(theta)],\n",
+ " entanglement_blocks=CCXGate(),\n",
+ " entanglement=[[0, 1, 2], [0, 2, 3], [4, 2, 1], [3, 1, 0]],\n",
+ " reps=2,\n",
+ " insert_barriers=True,\n",
+ ")\n",
+ "ansatz.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In the above example, the largest gate 上記の例では、最大のゲートは 三量子ビットに作用するトフォリゲートであり、この回路は $3$ local となります。最もよく使われるタイプの $N$ -local回路は、1量子ビット回転ゲートと $2$ 量子ビットエンタングルゲートを持つ [$2$-local]((https://qiskit.org/documentation/stubs/qiskit.circuit.library.TwoLocal.html)) 回路です。\n",
+ "\n",
+ "Qiskitの [`TwoLocal`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.TwoLocal.html) クラスを使って、$2$ -local回路を作成してみましょう。構文は `NLocal` と同じですが、いくつかの相違点があります。例えば、 `RX`, `RZ`, `CNOT`, `RZ`, and `CNOT`などのほとんどのゲートは、ゲートをインポートしたり `Parameter` インスタンスを作成したりせずに、文字列として渡すことができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "\n",
+ "ansatz = TwoLocal(\n",
+ " num_qubits=5,\n",
+ " rotation_blocks=[\"rx\", \"rz\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=2,\n",
+ " insert_barriers=True,\n",
+ ")\n",
+ "ansatz.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ここでは、各量子ビットが次の量子ビットとエンタングルする、線形エンタングルメント分布を使用しました。他の戦略については、[`TwoLocal` のドキュメント](https://qiskit.org/documentation/stubs/qiskit.circuit.library.TwoLocal.html) を参照してください。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### EfficientSU2\n",
+ "\n",
+ "[`EfficientSU2`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.EfficientSU2.html) は、SU(2)にまたがる1量子ビット演算の層と `CX` エンタングルメントのそうで構成されるハードウェアに対して効率の高い回路です。変分量子アルゴリズムの試行波動関数の準備や、機械学習の分類回路として利用できるヒューリスティックなパターンです。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import EfficientSU2\n",
+ "\n",
+ "ansatz = EfficientSU2(4, su2_gates=[\"rx\", \"y\"], entanglement=\"linear\", reps=1)\n",
+ "ansatz.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 問題固有のansatze\n",
+ "\n",
+ "ヒューリスティックな方法とハードウェア効率の良いansatzeは、素朴な方法で問題を解決するのに役立つ一方、問題固有の知識を使用して、回路の検索空間を特定のタイプに制限することもできます。これにより、検索プロセスの精度を落とすことなく、速度を上げることができるようになります。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 量子化学\n",
+ "\n",
+ "化学分野での典型的なアプリケーションは、特定の分子系の基底状態を求めることです。 [*Unitary Coupled-Cluster (UCC)*](https://qiskit.org/ecosystem/nature/stubs/qiskit_nature.second_q.circuit.library.UCC.html) ansatzは当初、基底状態の探索に変分境界を追加し、探索空間の探索速度を向上させるために提案されました。以下の例では、Hartree-Fock近似を参照状態として使用し、Hartree-Fock基底状態からの二重励起でUnitary Coupled-Clusterを使用する例を示します。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit_nature.second_q.drivers import PySCFDriver\n",
+ "from qiskit_nature.second_q.circuit.library import HartreeFock, UCC\n",
+ "from qiskit_nature.second_q.mappers import JordanWignerMapper\n",
+ "from qiskit_nature.second_q.formats.molecule_info import MoleculeInfo\n",
+ "\n",
+ "molecule = MoleculeInfo(\n",
+ " # Coordinates in Angstrom\n",
+ " symbols=[\"Li\", \"H\"],\n",
+ " coords=([0.0, 0.0, 0.0], [0.2, 0.0, 0.0]),\n",
+ " multiplicity=1, # = 2*spin + 1\n",
+ " charge=0,\n",
+ ")\n",
+ "\n",
+ "driver = PySCFDriver.from_molecule(molecule)\n",
+ "LiH_problem = driver.run()\n",
+ "\n",
+ "mapper = JordanWignerMapper()\n",
+ "LiH_reference_state = HartreeFock(\n",
+ " num_spatial_orbitals=LiH_problem.num_spatial_orbitals,\n",
+ " num_particles=LiH_problem.num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ ")\n",
+ "\n",
+ "ansatz = UCC(\n",
+ " num_spatial_orbitals=LiH_problem.num_spatial_orbitals,\n",
+ " num_particles=LiH_problem.num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ " initial_state=LiH_reference_state,\n",
+ " excitations=2,\n",
+ ")\n",
+ "\n",
+ "ansatz.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 量子機械学習\n",
+ "\n",
+ "機械学習で一般的なアプリケーションは、データを2つ以上のカテゴリーに [分類](https://learn.qiskit.org/course/machine-learning/variational-classification) することです。この場合、古典的な特徴量ベクトルを量子ヒルベルト空間にマッピングする特徴量マップに [データ点を符号化](https://learn.qiskit.org/course/machine-learning/data-encoding) する必要があります。古典的なシミュレーションが困難なパラメーター化された量子回路に基づいて量子特徴量マップを構築することは、古典的な機械学習アプローチに対する潜在的な優位性を得るための重要なステップであり、現在活発に研究が行われている分野です。\n",
+ "\n",
+ "[ZZFeatureMap](https://qiskit.org/documentation/stubs/qiskit.circuit.library.ZZFeatureMap.html) は、パラメーター化された回路を作成するために使用することができます。特徴量マップ( $x$ )と重みをパラメーターとして渡すための別の変分形式( $\\theta$ )にデータ点を渡します。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import ZZFeatureMap, TwoLocal\n",
+ "\n",
+ "data = [0.1, 0.2]\n",
+ "\n",
+ "zz_feature_map_reference = ZZFeatureMap(feature_dimension=2, reps=2)\n",
+ "zz_feature_map_reference = zz_feature_map_reference.bind_parameters(data)\n",
+ "\n",
+ "variation_form = TwoLocal(2, [\"ry\", \"rz\"], \"cz\", reps=2)\n",
+ "vqc_ansatz = zz_feature_map_reference.compose(variation_form)\n",
+ "vqc_ansatz.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "このレッスンでは、変分形式を使って探索空間を定義する方法を学びました:\n",
+ "\n",
+ "- ゲートが調整可能なパラメータで定義された、 *パラメーター化された* 量子回路で状態を準備します。\n",
+ "- 速度と精度をトレードオフするansatzeの組み立て方\n",
+ "- ヒューリスティックなansatze\n",
+ "- 問題に固有のansatze\n",
+ "\n",
+ "このハイレベルな変分の作業は次のようになります:\n",
+ "\n",
+ "![Ansatz Circuit](images/ansatz_circuit.png)\n",
+ "\n",
+ "各変形パラメーター $\\vec\\theta$ に対して、異なる量子状態が生成されます。最適なパラメーターを見つけるために、問題に応じた *コスト関数* を定義して、ansatzのパラメーターを繰り返し更新する必要があります。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/ansatz/images/ansatz_circuit.png b/translations/ja/algorithm-design/ansatz/images/ansatz_circuit.png
new file mode 100644
index 00000000..4aff5d6d
Binary files /dev/null and b/translations/ja/algorithm-design/ansatz/images/ansatz_circuit.png differ
diff --git a/translations/ja/algorithm-design/ansatz/images/ansatz_workflow.png b/translations/ja/algorithm-design/ansatz/images/ansatz_workflow.png
new file mode 100644
index 00000000..2cec5ec4
Binary files /dev/null and b/translations/ja/algorithm-design/ansatz/images/ansatz_workflow.png differ
diff --git a/translations/ja/algorithm-design/applications/applications.ipynb b/translations/ja/algorithm-design/applications/applications.ipynb
new file mode 100644
index 00000000..eab58a3c
--- /dev/null
+++ b/translations/ja/algorithm-design/applications/applications.ipynb
@@ -0,0 +1,1195 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 例とアプリケーション\n",
+ "\n",
+ "このレッスンでは、いくつかの変分アルゴリズムの例とその適用方法について説明します。\n",
+ "\n",
+ "- カスタム変分アルゴリズムの書き方\n",
+ "- 変分アルゴリズムを適用して最小固有値を見つける方法\n",
+ "- 変分アルゴリズムを利用してアプリケーションのユースケースを解決する方法"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 問題の定義\n",
+ "\n",
+ "変分アルゴリズムを使用して、次の観測可能量の固有値を見つけたいと想像してください。\n",
+ "\n",
+ "$$\n",
+ "\\hat{O}_1 = 2 II - 2 XX + 3 YY - 3 ZZ,\n",
+ "$$\n",
+ "\n",
+ "この観測可能量は次の固有値を持ちます。\n",
+ "\n",
+ "$$\n",
+ "\\left\\{\n",
+ "\\begin{array}{c}\n",
+ "\\lambda_0 = -6 \\\\\n",
+ "\\lambda_1 = 4 \\\\\n",
+ "\\lambda_2 = 4 \\\\\n",
+ "\\lambda_3 = 6\n",
+ "\\end{array}\n",
+ "\\right\\}\n",
+ "$$\n",
+ "\n",
+ "そして固有状態:\n",
+ "\n",
+ "$$\n",
+ "\\left\\{\n",
+ "\\begin{array}{c}\n",
+ "|\\phi_0\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)\\\\\n",
+ "|\\phi_1\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle - |11\\rangle)\\\\\n",
+ "|\\phi_2\\rangle = \\frac{1}{\\sqrt{2}}(|01\\rangle - |10\\rangle)\\\\\n",
+ "|\\phi_3\\rangle = \\frac{1}{\\sqrt{2}}(|01\\rangle + |10\\rangle)\n",
+ "\\end{array}\n",
+ "\\right\\}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "\n",
+ "observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## カスタム VQE\n",
+ "\n",
+ "最初に、VQE インスタンスを手動で構築して $\\hat{O}_1$ の最小固有値を見つける方法を調べます。これには、このコースで説明したさまざまなテクニックが組み込まれています。 "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "from qiskit import QuantumCircuit\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService, Estimator\n",
+ "import numpy as np\n",
+ "\n",
+ "# Add your token below\n",
+ "service = QiskitRuntimeService(\n",
+ " channel=\"ibm_quantum\",\n",
+ ")\n",
+ "\n",
+ "def cost_function_vqe(theta):\n",
+ " observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])\n",
+ " reference_circuit = QuantumCircuit(2)\n",
+ " reference_circuit.x(0)\n",
+ "\n",
+ " variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ " )\n",
+ " ansatz = reference_circuit.compose(variational_form)\n",
+ "\n",
+ " backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ " \n",
+ " # Use estimator to get the expected values corresponding to each ansatz\n",
+ " estimator = Estimator(session=backend)\n",
+ " job = estimator.run(ansatz, observable, theta)\n",
+ " values = job.result().values\n",
+ "\n",
+ " return values"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "このコスト関数を使用して、最適なパラメーターを計算できます"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "\n",
+ "initial_theta = np.ones(8)\n",
+ "optimizer = COBYLA()\n",
+ "\n",
+ "optimizer_result = optimizer.minimize(fun=cost_function_vqe, x0=initial_theta)\n",
+ "\n",
+ "optimal_parameters = optimizer_result.x\n",
+ "print(optimal_parameters)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "最後に、最適パラメーターを使用して最小固有値を計算できます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])\n",
+ "reference_circuit = QuantumCircuit(2)\n",
+ "reference_circuit.x(0)\n",
+ "\n",
+ "variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ ")\n",
+ "ansatz = reference_circuit.compose(variational_form)\n",
+ "solution = ansatz.bind_parameters(optimal_parameters)\n",
+ "\n",
+ "backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ "estimator = Estimator(session=backend)\n",
+ "job = estimator.run(solution, observable)\n",
+ "values = job.result().values\n",
+ "\n",
+ "experimental_min_eigenvalue = values[0]\n",
+ "print(experimental_min_eigenvalue)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from numpy.linalg import eigvalsh\n",
+ "\n",
+ "solution_eigenvalue = min(eigvalsh(observable.to_matrix()))\n",
+ "print(\n",
+ " f\"Percent error: {abs((experimental_min_eigenvalue - solution_eigenvalue)/solution_eigenvalue):.2e}\"\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ご覧のとおり、結果は理想に非常に近いものになっています。 "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Qiskit の VQE の構成"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "便宜上、既存の Qiskit [VQE](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.VQE.html)の実装を使うことができて、最初の観測可能量 $\\hat{O}_1$ の最小固有値を見つけ、すべての出力結果を調べることもできます。\n",
+ "\n",
+ "この場合、以下を使用します。\n",
+ "\n",
+ "- 参照演算子 $\\equiv I$ の調査を開始して、これにより速度が向上することを示します。\n",
+ "- Qiskit Terra の[`Estimator`](https://qiskit.org/documentation/stubs/qiskit.primitives.Estimator.html#qiskit.primitives.Estimator)\n",
+ "- [`SLSQP`](https://qiskit.org/documentation/stubs/qiskit.algorithms.optimizers.SLSQP.html) (つまり、逐次最小二乗法プログラミング) オプティマイザー\n",
+ "- さらに、 `SLSQP`オプティマイザーの初期ポイントを $\\vec\\theta_0 = (1, \\cdots, 1)$ に設定します。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.primitives import Estimator\n",
+ "from qiskit.algorithms.optimizers import SLSQP\n",
+ "from qiskit.algorithms.minimum_eigensolvers import VQE\n",
+ "import numpy as np\n",
+ "\n",
+ "estimator = Estimator()\n",
+ "optimizer = SLSQP()\n",
+ "ansatz = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ ")\n",
+ "\n",
+ "vqe = VQE(estimator, ansatz, optimizer, initial_point=np.ones(8))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`VQE`インスタンスを初期化したので、 [`VQE.compute_minimum_eigenvalue`](https://qiskit.org/documentation/stubs/qiskit.algorithms.minimum_eigensolvers.VQE.compute_minimum_eigenvalue.html#qiskit.algorithms.minimum_eigensolvers.VQE.compute_minimum_eigenvalue)メソッドで結果を取得できます。結果を見てみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "result = vqe.compute_minimum_eigenvalue(observable)\n",
+ "print(result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`optimizer_result`を見てみましょう:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(result.optimizer_result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ただし、これらすべての情報の中で最も重要な部分は固有値です。理論値と比較してみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from numpy.linalg import eigvalsh\n",
+ "\n",
+ "eigenvalues = eigvalsh(observable.to_matrix())\n",
+ "min_eigenvalue = eigenvalues[0]\n",
+ "\n",
+ "print(\"EIGENVALUES:\")\n",
+ "print(f\" - Theoretical: {min_eigenvalue}.\")\n",
+ "print(f\" - VQE: {result.eigenvalue}\")\n",
+ "print(\n",
+ " f\"Percent error >> {abs((result.eigenvalue - min_eigenvalue)/min_eigenvalue):.2e}\"\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ご覧のとおり、結果は理想に非常に近いものになっています。\n",
+ "\n",
+ "ただし、固有状態は`results`の一部ではなかったため、まだ見ていません。この目的のために、最適なパラメーター値`result.optimal_parameters` を `results.optimal_circuit`にバインドし、そのバインドされた (つまり、パラメーター化されていない) 回路から[`Statevector`](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html)を定義します。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.quantum_info import Statevector\n",
+ "\n",
+ "optimal_circuit = result.optimal_circuit.bind_parameters(result.optimal_parameters)\n",
+ "optimal_vector = Statevector(optimal_circuit)\n",
+ "\n",
+ "rounded_optimal_vector = np.round(optimal_vector.data, 3)\n",
+ "print(f\"EIGENSTATE: {rounded_optimal_vector}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この結果は、 $\\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle) \\equiv [\\frac{1}{\\sqrt{2} },0,0,\\frac{1}{\\sqrt{2}}]$ の理論上のものにあまり近くないようです。ただし、固有ベクトルは定数倍まで定義されていることに注意してください。さらに、量子状態は常に正規化されてグローバル位相まで等価であるため、これら 2 つの状態ベクトルが等価であることを簡単に確認できます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from numpy.linalg import eigh\n",
+ "\n",
+ "_, eigenvectors = eigh(observable.to_matrix())\n",
+ "min_eigenvector = eigenvectors.T[0] # Note: transpose to extract by index\n",
+ "\n",
+ "optimal_vector.equiv(min_eigenvector, atol=1e-4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "得られた状態は、 $10^{-4}$ までは理想的な状態と同等であると結論付けることができます。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 参照状態を追加\n",
+ "\n",
+ "前の例では、参照演算子 $U_R$ を使用していません。ここで、理想的な固有状態 $\\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)$ がどのように得られるかを考えてみましょう。次の回路を考えてみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit import QuantumCircuit\n",
+ "\n",
+ "ideal_qc = QuantumCircuit(2)\n",
+ "ideal_qc.h(0)\n",
+ "ideal_qc.cx(0, 1)\n",
+ "\n",
+ "ideal_qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この回路が目的の状態になることをすぐに確認できます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "Statevector(ideal_qc)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "解の状態を準備する回路がどのようになるかを見てきたので、アダマール ゲートを参照回路として使用するのが合理的であるように思われるため、完全な ansatz は次のようになります。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reference = QuantumCircuit(2)\n",
+ "reference.h(0)\n",
+ "# Include barrier to separate reference from variational form\n",
+ "reference.barrier()\n",
+ "\n",
+ "ref_ansatz = ansatz.decompose().compose(reference, front=True)\n",
+ "\n",
+ "ref_ansatz.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この新しい回路では、すべてのパラメーターを $0$ に設定して理想的な解に到達できるため、参照回路の選択が妥当であることが確認されます。\n",
+ "\n",
+ "ここで、コスト関数の評価、オプティマイザーの反復、および所要時間を前回の試行と比較してみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "num_evaluations = result.cost_function_evals\n",
+ "num_iterations = result.optimizer_result.nit\n",
+ "time = result.optimizer_time\n",
+ "\n",
+ "print(\"NO REFERENCE STATE:\")\n",
+ "print(f\" - Number of evaluations: {num_evaluations}\")\n",
+ "print(f\" - Number of iterations: {num_iterations}\")\n",
+ "print(f\" - Time: {time:.5f} seconds\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# You can change the ansatz of the already defined vqe object instead of creating a new one\n",
+ "vqe.ansatz = ref_ansatz\n",
+ "\n",
+ "ref_result = vqe.compute_minimum_eigenvalue(observable)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "num_evaluations_ref = ref_result.cost_function_evals\n",
+ "num_iterations_ref = ref_result.optimizer_result.nit\n",
+ "time_ref = ref_result.optimizer_time\n",
+ "\n",
+ "print(\"ADDED REFERENCE STATE:\")\n",
+ "print(f\" - Number of evaluations: {num_evaluations_ref}\")\n",
+ "print(f\" - Number of iterations: {num_iterations_ref}\")\n",
+ "print(f\" - Time: {time_ref:.5f} seconds\")\n",
+ "print()\n",
+ "\n",
+ "if num_evaluations_ref < num_evaluations:\n",
+ " print(\">> Number of cost function evaluations improved\")\n",
+ "elif num_evaluations_ref > num_evaluations:\n",
+ " print(\">> Number of cost function evaluations worsened\")\n",
+ "if num_iterations_ref < num_iterations:\n",
+ " print(\">> Number of iterations improved\")\n",
+ "elif num_iterations_ref > num_iterations:\n",
+ " print(\">> Number of iterations worsened\")\n",
+ "if time_ref < time:\n",
+ " print(\">> Time improved\")\n",
+ "elif time_ref > time:\n",
+ " print(\">> Time worsened\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 初期点の変更"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "参照状態を追加する効果を見たので、異なる初期点 $\\vec{\\theta_0}$ を選択するとどうなるかを見ていきます。特に、 $\\vec{\\theta_0}=(0,0,0,0,6,0,0,0)$ と $\\vec{\\theta_0}=(6,6,6,6,6,6,6,6,6)$を使用します。参照状態が導入されたときに説明したように、すべてのパラメーターが $0$ のときに理想的な解が見つかることを思い出してください。したがって、最初の初期点では、評価、反復、および時間が少なくて済みます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vqe.initial_point = [0, 0, 0, 0, 6, 0, 0, 0]\n",
+ "\n",
+ "result = vqe.compute_minimum_eigenvalue(observable)\n",
+ "\n",
+ "num_evaluations = result.cost_function_evals\n",
+ "num_iterations = result.optimizer_result.nit\n",
+ "time = result.optimizer_time\n",
+ "\n",
+ "print(f\"INITIAL POINT: {vqe.initial_point}\")\n",
+ "print(f\" - Number of evaluations: {num_evaluations}\")\n",
+ "print(f\" - Number of iterations: {num_iterations}\")\n",
+ "print(f\" - Time: {time:.5f} seconds\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vqe.initial_point = 6 * np.ones(8)\n",
+ "\n",
+ "result = vqe.compute_minimum_eigenvalue(observable)\n",
+ "\n",
+ "num_evaluations = result.cost_function_evals\n",
+ "num_iterations = result.optimizer_result.nit\n",
+ "time = result.optimizer_time\n",
+ "\n",
+ "print(f\"INITIAL POINT: {vqe.initial_point}\")\n",
+ "print(f\" - Number of evaluations: {num_evaluations}\")\n",
+ "print(f\" - Number of iterations: {num_iterations}\")\n",
+ "print(f\" - Time: {time:.5f} seconds\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## VQD の例"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ここで、観測可能量の最小固有値だけを探す代わりに、すべての $4$ を探します。前の章の表記 (および Qiskit の[VQD](https://qiskit.org/documentation/stubs/qiskit.algorithms.eigensolvers.VQD.html)クラスの表記) に従うと、これは $k=4$ を意味します。\n",
+ "\n",
+ "VQD のコスト関数は次のとおりです。\n",
+ "\n",
+ "$$\n",
+ "C_{l}(\\vec{\\theta}) := \n",
+ "\\langle \\psi(\\vec{\\theta}) | \\hat{H} | \\psi(\\vec{\\theta})\\rangle + \n",
+ "\\sum_{j=0}^{l-1}\\beta_j |\\langle \\psi(\\vec{\\theta})| \\psi(\\vec{\\theta^j})\\rangle |^2 \n",
+ "\\quad \\forall l\\in\\{1,\\cdots,k\\}=\\{1,\\cdots,4\\}\n",
+ "$$\n",
+ "\n",
+ "これは、 `VQD` オブジェクトを定義するときに、ベクトル$\\vec{\\beta}=(\\beta_0,\\cdots,\\beta_{k-1})$ (この場合は $(\\beta_0, \\beta_1, \\beta_2, \\beta_3)$)を引数として渡さなければならないので、特に重要です。\n",
+ "\n",
+ "また、QiskitのVQDの実装では、前のノートブックで説明した実効的な観測可能量を考慮する代わりに、 [`ComputeUncompute`](https://qiskit.org/documentation/stubs/qiskit.algorithms.state_fidelities.ComputeUncompute.html) アルゴリズムによって、忠実度 $|\\langle \\psi(\\vec{\\theta})| \\psi(\\vec{\\theta^j})\\rangle |^2$ を直接計算しています。これは `Sampler` Primitiveを使って、回路 $U_A^\\dagger(\\vec{\\theta})U_A(\\vec{\\theta^j})$ に対して $|0\\rangle$ を得る確率をサンプリングするものです。この確率は以下のとおりですから、このことは厳密に機能しています。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\n",
+ "p_0\n",
+ "\n",
+ "& = |\\langle 0|U_A^\\dagger(\\vec{\\theta})U_A(\\vec{\\theta^j})|0\\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "& = |\\big(\\langle 0|U_A^\\dagger(\\vec{\\theta})\\big)\\big(U_A(\\vec{\\theta^j})|0\\rangle\\big)|^2 \\\\[1mm]\n",
+ "\n",
+ "& = |\\langle \\psi(\\vec{\\theta}) |\\psi(\\vec{\\theta^j}) \\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "最後に、新しいオプティマイザーを試すために、 SLSQP
の代わりにCOBYLA
を使用してみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.primitives import Sampler\n",
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "from qiskit.algorithms.state_fidelities import ComputeUncompute\n",
+ "from qiskit.algorithms.eigensolvers import VQD\n",
+ "\n",
+ "optimizer = COBYLA()\n",
+ "sampler = Sampler()\n",
+ "estimator = Estimator()\n",
+ "fidelity = ComputeUncompute(sampler)\n",
+ "\n",
+ "k = 4\n",
+ "betas = [40, 60, 30, 30]\n",
+ "\n",
+ "vqd = VQD(estimator, fidelity, ansatz, optimizer, k=k, betas=betas)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "前の例との唯一の API の違いとして、`VQE.compute_minimum_eigenvalue`メソッドを呼び出す代わりに、 [`VQD.compute_eigenvalues`](https://qiskit.org/documentation/stubs/qiskit.algorithms.eigensolvers.VQD.compute_eigenvalues.html)を呼び出すことに注意してください。次の観測可能量を調べることから始めましょう。\n",
+ "\n",
+ "$$\n",
+ "\\hat{O}_2 := 2 II - 3 XX + 2 YY - 4 ZZ\n",
+ "$$\n",
+ "\n",
+ "この観測可能量は次の固有値を持ちます。\n",
+ "\n",
+ "$$\n",
+ "\\left\\{\n",
+ "\\begin{array}{c}\n",
+ "\\lambda_0 = -7 \\\\\n",
+ "\\lambda_1 = 3\\\\\n",
+ "\\lambda_2 = 5 \\\\\n",
+ "\\lambda_3 = 7\n",
+ "\\end{array}\n",
+ "\\right\\}\n",
+ "$$\n",
+ "\n",
+ "そして固有状態:\n",
+ "\n",
+ "$$\n",
+ "\\left\\{\n",
+ "\\begin{array}{c}\n",
+ "|\\phi_0\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)\\\\\n",
+ "|\\phi_1\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle - |11\\rangle)\\\\\n",
+ "|\\phi_2\\rangle = \\frac{1}{\\sqrt{2}}(|01\\rangle + |10\\rangle)\\\\\n",
+ "|\\phi_3\\rangle = \\frac{1}{\\sqrt{2}}(|01\\rangle - |10\\rangle)\n",
+ "\\end{array}\n",
+ "\\right\\}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "observable_2 = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -3), (\"YY\", 2), (\"ZZ\", -4)])\n",
+ "\n",
+ "result = vqd.compute_eigenvalues(observable_2)\n",
+ "print(result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "取得した[`VQDResult`](https://qiskit.org/documentation/stubs/qiskit.algorithms.eigensolvers.VQDResult.html) は、 `VQEResult`と完全に類似しています。各属性が $i$ 番目の要素が $i$ 番目の固有値に対応するリストであるという点だけが異なります。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "さて、固有値を見たところで、実験の固有ベクトルと理論の固有ベクトルを比較してみましょう:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "optimal_circuits = [\n",
+ " circuit.bind_parameters(parameters)\n",
+ " for circuit, parameters in zip(result.optimal_circuits, result.optimal_parameters)\n",
+ "]\n",
+ "eigenstates = [Statevector(c) for c in optimal_circuits]\n",
+ "\n",
+ "for i, (eigenvalue, eigenstate) in enumerate(zip(result.eigenvalues, eigenstates)):\n",
+ " eigenvalue = eigenvalue.real\n",
+ " eigenstate = np.round(eigenstate.data, 3).tolist()\n",
+ " print(f\"RESULT {i}:\")\n",
+ " print(f\" - {eigenvalue = :.3f}\")\n",
+ " print(f\" - {eigenstate = }\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "これらの結果は、小さな近似誤差とグローバル位相を除いて、予想される結果と同じです。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ここで、最初に観測可能量 $\\hat{O}_1 := 2 II - 2 XX + 3 YY - 3 ZZ$ についてこの問題を解いてみましょう。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "result = vqd.compute_eigenvalues(observable)\n",
+ "\n",
+ "optimal_circuits = [\n",
+ " circuit.bind_parameters(parameters)\n",
+ " for circuit, parameters in zip(result.optimal_circuits, result.optimal_parameters)\n",
+ "]\n",
+ "eigenstates = [Statevector(c) for c in optimal_circuits]\n",
+ "\n",
+ "for i, (eigenvalue, eigenstate) in enumerate(zip(result.eigenvalues, eigenstates)):\n",
+ " eigenvalue = eigenvalue.real\n",
+ " eigenstate = np.round(eigenstate.data, 3).tolist()\n",
+ " print(f\"RESULT {i}:\")\n",
+ " print(f\" - {eigenvalue = :.3f}\")\n",
+ " print(f\" - {eigenstate = }\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "ここで、 $\\lambda_1 = \\lambda_2 = 4$ に対応する固有状態は、予想されるものと同じではありません:\n",
+ "\n",
+ "$$\n",
+ "|\\phi_1\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle - |11\\rangle) \\\\\n",
+ "|\\phi_2\\rangle = \\frac{1}{\\sqrt{2}}(|01\\rangle + |10\\rangle)\n",
+ "$$\n",
+ "\n",
+ "これは、 $\\lambda_1=\\lambda_2$ のように、複雑な線形結合も同じ固有値を持つ固有状態であるためです。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\alpha_1 |\\phi_1\\rangle + \\alpha_2 |\\phi_2\\rangle\n",
+ "& = \\frac{1}{\\sqrt{2}}(\\alpha_1 |00\\rangle + \\alpha_2 |01\\rangle - \\alpha_2 |10\\rangle - \\alpha_1 |11\\rangle) \\\\[1mm]\n",
+ "& \\equiv \\frac{1}{\\sqrt{2}}[\\alpha_1, \\alpha_2, -\\alpha_2, -\\alpha_1]\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "それはまさに、これらの結果で私たちが見ているものです。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### ベータの変更"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "インスタンスのレッスンで述べたように、 $\\vec{\\beta}$ の値は固有値の差より大きくなければなりません。 $\\hat{O}_2$ でその条件を満たさない場合に何が起こるか見てみましょう\n",
+ "\n",
+ "$$\n",
+ "\\hat{O}_2 = 2 II - 3 XX + 2 YY - 4 ZZ\n",
+ "$$\n",
+ "\n",
+ "固有値は\n",
+ "\n",
+ "$$\n",
+ "\\left\\{\n",
+ "\\begin{array}{c}\n",
+ "\\lambda_0 = -7 \\\\\n",
+ "\\lambda_1 = 3\\\\\n",
+ "\\lambda_2 = 5 \\\\\n",
+ "\\lambda_3 = 7\n",
+ "\\end{array}\n",
+ "\\right\\}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vqd.betas = np.ones(4)\n",
+ "result = vqd.compute_eigenvalues(observable_2)\n",
+ "\n",
+ "optimal_circuits = [\n",
+ " circuit.bind_parameters(parameters)\n",
+ " for circuit, parameters in zip(result.optimal_circuits, result.optimal_parameters)\n",
+ "]\n",
+ "eigenstates = [Statevector(c) for c in optimal_circuits]\n",
+ "\n",
+ "for i, (eigenvalue, eigenstate) in enumerate(zip(result.eigenvalues, eigenstates)):\n",
+ " eigenvalue = eigenvalue.real\n",
+ " eigenstate = np.round(eigenstate.data, 3).tolist()\n",
+ " print(f\"RESULT {i}:\")\n",
+ " print(f\" - {eigenvalue = :.3f}\")\n",
+ " print(f\" - {eigenstate = }\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "今回、オプティマイザーは、すべての固有状態に対する提案された解として、同じ状態 $|\\phi_0\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)$ を返しますがこれは明らかに誤っています。これは、ベータが小さすぎて、連続するコスト関数の最小固有状態にペナルティを課すことができないために発生します。したがって、アルゴリズムの後の反復で有効な検索スペースから除外されず、可能な最良解として常に選択されるのです。\n",
+ "\n",
+ "$\\vec{\\beta}$ の値を試して、固有値の差よりも大きいことを確認することをお勧めします。 "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 量子化学: 基底状態と励起エネルギーソルバー\n",
+ "\n",
+ "私たちの目的は、観測可能量を表わすエネルギー (ハミルトニアン $\\hat{\\mathcal{H}}$) の期待値を最小化することです。\n",
+ "\n",
+ "$$\n",
+ "\\min_{\\vec\\theta} \\langle\\psi(\\vec\\theta)|\\hat{\\mathcal{H}}|\\psi(\\vec\\theta)\\rangle\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit_nature.units import DistanceUnit\n",
+ "from qiskit_nature.second_q.drivers import PySCFDriver\n",
+ "from qiskit_nature.second_q.circuit.library import HartreeFock, UCC\n",
+ "from qiskit_nature.second_q.mappers import JordanWignerMapper\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "\n",
+ "H2_op = SparsePauliOp.from_list(\n",
+ " [\n",
+ " (\"II\", -1.052373245772859),\n",
+ " (\"IZ\", 0.39793742484318045),\n",
+ " (\"ZI\", -0.39793742484318045),\n",
+ " (\"ZZ\", -0.01128010425623538),\n",
+ " (\"XX\", 0.18093119978423156),\n",
+ " ]\n",
+ ")\n",
+ "\n",
+ "driver = PySCFDriver(\n",
+ " atom=\"H 0 0 0; H 0 0 0.735\",\n",
+ " basis=\"sto3g\",\n",
+ " charge=0,\n",
+ " spin=0,\n",
+ " unit=DistanceUnit.ANGSTROM,\n",
+ ")\n",
+ "\n",
+ "h2_problem = driver.run()\n",
+ "\n",
+ "mapper = JordanWignerMapper()\n",
+ "\n",
+ "h2_reference_state = HartreeFock(\n",
+ " num_spatial_orbitals=h2_problem.num_spatial_orbitals,\n",
+ " num_particles=h2_problem.num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ ")\n",
+ "\n",
+ "ansatz = UCC(\n",
+ " num_spatial_orbitals=h2_problem.num_spatial_orbitals,\n",
+ " num_particles=h2_problem.num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ " initial_state=h2_reference_state,\n",
+ " excitations=2,\n",
+ ")\n",
+ "\n",
+ "ansatz.decompose().decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.algorithms.minimum_eigensolvers import VQE\n",
+ "from qiskit.primitives import Sampler, Estimator\n",
+ "from qiskit.algorithms.state_fidelities import ComputeUncompute\n",
+ "from qiskit_nature.second_q.algorithms import GroundStateEigensolver\n",
+ "\n",
+ "estimator = Estimator()\n",
+ "sampler = Sampler()\n",
+ "fidelity = ComputeUncompute(sampler)\n",
+ "\n",
+ "vqe = VQE(\n",
+ " estimator=estimator,\n",
+ " ansatz=ansatz,\n",
+ " optimizer=optimizer,\n",
+ " initial_point=np.zeros(ansatz.num_parameters),\n",
+ ")\n",
+ "gse = GroundStateEigensolver(qubit_mapper=mapper, solver=vqe)\n",
+ "result = gse.solve(h2_problem)\n",
+ "\n",
+ "print(result)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "VQD を活用して励起状態を解くこともできます"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.algorithms.eigensolvers import VQD\n",
+ "\n",
+ "h2_operators, _ = gse.get_qubit_operators(h2_problem)\n",
+ "\n",
+ "optimizer = COBYLA()\n",
+ "sampler = Sampler()\n",
+ "estimator = Estimator()\n",
+ "fidelity = ComputeUncompute(sampler)\n",
+ "\n",
+ "k = 3\n",
+ "betas = [33, 33, 33]\n",
+ "\n",
+ "vqd = VQD(\n",
+ " estimator=estimator,\n",
+ " ansatz=ansatz,\n",
+ " optimizer=optimizer,\n",
+ " fidelity=fidelity,\n",
+ " initial_point=np.zeros(ansatz.num_parameters),\n",
+ " k=k,\n",
+ " betas=betas,\n",
+ ")\n",
+ "result = vqd.compute_eigenvalues(operator=h2_operators)\n",
+ "vqd_values = result.optimal_values\n",
+ "print(vqd_values)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 最適化: マックスカット\n",
+ "\n",
+ "マックスカット(Max-Cut)問題とは、グラフの頂点を2つの互いに素な集合に分割し、その2つの集合間の辺の数が最大になるようにする組合せ最適化問題です。より正式には、 $V$ が頂点の集合、 $E$ が辺の集合である無向グラフ $G=(V,E)$ が与えられたとき、マックスカット問題は、頂点を2つの互いに素な部分集合 $S$ と$T$に分割する際に、一方の端点が $S$ にあり他方が $T$ にあるような辺の数が最大となるような分割を求めます。\n",
+ "\n",
+ "マックスカットを応用して、クラスタリング、ネットワーク設計、相転移など様々な問題を解くことができます。まず、問題グラフを作成することから始めます:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import networkx as nx\n",
+ "\n",
+ "n = 4\n",
+ "G = nx.Graph()\n",
+ "G.add_nodes_from(range(n))\n",
+ "edge_list = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)]\n",
+ "G.add_weighted_edges_from(edge_list)\n",
+ "\n",
+ "colors = [\"red\" for i in range(n)]\n",
+ "\n",
+ "\n",
+ "def draw_graph(G, colors):\n",
+ " \"\"\"Draws the graph with the chose colors\"\"\"\n",
+ " layout = nx.shell_layout(G)\n",
+ " nx.draw_networkx(G, node_color=colors, pos=layout)\n",
+ " edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
+ " nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=edge_labels)\n",
+ "\n",
+ "\n",
+ "draw_graph(G, colors)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "すべてのエッジの重みに快適にアクセスするには、隣接行列を使用できます。この行列は[networkx.to_numpy_array()](https://networkx.org/documentation/stable/reference/generated/networkx.convert_matrix.to_numpy_array.html)で取得できます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "w = nx.to_numpy_array(G)\n",
+ "print(w)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "[`qiskit_optimization`](https://qiskit.org/documentation/optimization/index.html)モジュールには、隣接行列 $w$ から加重 Max-Cut 問題を定義できる[`Maxcut`](https://qiskit.org/documentation/optimization/stubs/qiskit_optimization.applications.Maxcut.html)というクラスが含まれています。その問題から、前のセクションで[`Maxcut.to_quadratic_program()`](https://qiskit.org/documentation/optimization/stubs/qiskit_optimization.applications.Maxcut.to_quadratic_program.html)を使用して推定した等価な2値最適化問題を得ることができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit_optimization.applications import Maxcut\n",
+ "\n",
+ "max_cut = Maxcut(w)\n",
+ "\n",
+ "quadratic_program = max_cut.to_quadratic_program()\n",
+ "print(quadratic_program.prettyprint())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この問題は、2値最適化問題として表現できます。 $n$ をグラフのノード数とし、 $0 \\leq i < n$ である各ノード(この場合 $n=4$ )に対して、バイナリー変数 $x_i$ を考えます。この変数は、ノード $i$ が $1$ のラベルを貼ったグループの1つであれば値 $1$ を持ち、 $0$ とラベルを貼った他のグループの1つであれば値 $0$ を持つことになります。また、ノード $i$ からノード $j$ に至るエッジの重みを $w_{ij}$ (隣接行列 $w$ の要素 $(i,j)$ )とします。グラフは無向性なので、 $w_{ij}=w_{ji}$ となります。そうすると、問題は以下のコスト関数を最大化するものとして定式化できます:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "C(\\vec{x})\n",
+ "& =\\sum_{i,j=0}^n w_{ij} x_i(1-x_j)\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n w_{ij} x_i - \\sum_{i,j=0}^n w_{ij} x_ix_j\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n w_{ij} x_i - \\sum_{i=0}^n \\sum_{j=0}^i 2w_{ij} x_ix_j\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "この問題を量子コンピューターで解くために、コスト関数を観測可能量の期待値として表現します。ただし、Qiskit が自然に認めている観測可能量は、 $0$ と $1$ の代わりに固有値 $1$ と $-1$ を持つパウリ演算子で構成されています。そのため、変数を次のように変更します。\n",
+ "\n",
+ "ここで、 $\\vec{x}=(x_0,x_1,\\cdots ,x_{n-1})$ です。隣接行列 $w$ を使って、すべてのエッジの重みに快適にアクセスすることができます。これはコスト関数を求めるのに使われます:\n",
+ "\n",
+ "$$\n",
+ "z_i = 1-2x_i \\rightarrow x_i = \\frac{1-z_i}{2}\n",
+ "$$\n",
+ "\n",
+ "これは、次のことを意味します。\n",
+ "\n",
+ "$$\n",
+ "\\begin{array}{lcl} x_i=0 & \\rightarrow & z_i=1 \\\\ x_i=1 & \\rightarrow & z_i=-1.\\end{array}\n",
+ "$$\n",
+ "\n",
+ "したがって、最大化したい新しいコスト関数は次のとおりです。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "C(\\vec{z})\n",
+ "& = \\sum_{i,j=0}^n w_{ij} \\bigg(\\frac{1-z_i}{2}\\bigg)\\bigg(1-\\frac{1-z_j}{2}\\bigg)\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n \\frac{w_{ij}}{4} - \\sum_{i,j=0}^n \\frac{w_{ij}}{4} z_iz_j\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} z_iz_j\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "さらに、量子コンピューターの自然な傾向として、最大値ではなく最小値(通常は最低エネルギー)を見つけるので、 $C(\\vec{z})$ を最大化するのではなく、最小化します:\n",
+ "\n",
+ "$$\n",
+ "-C(\\vec{z}) = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} z_iz_j - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2}\n",
+ "$$\n",
+ "\n",
+ "$-1$ と $1$ の値を持つ変数を最小化するためのコスト関数ができたので、次のようにパウリの $Z$ との類推を行うことができます。\n",
+ "\n",
+ "$$\n",
+ "z_i \\equiv Z_i = \\overbrace{I}^{n-1}\\otimes ... \\otimes \\overbrace{Z}^{i} \\otimes ... \\otimes \\overbrace{I}^{0}\n",
+ "$$\n",
+ "\n",
+ "つまり、変数 $z_i$ は、量子ビット $i$ に作用する $Z$ ゲートと同等になります。さらに:\n",
+ "\n",
+ "$$\n",
+ "Z_i|x_{n-1}\\cdots x_0\\rangle = z_i|x_{n-1}\\cdots x_0\\rangle \\rightarrow \\langle x_{n-1}\\cdots x_0 |Z_i|x_{n-1}\\cdots x_0\\rangle = z_i\n",
+ "$$\n",
+ "\n",
+ "次に、検討する観測可能量は次のとおりです。\n",
+ "\n",
+ "$$\n",
+ "\\hat{H} = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} Z_iZ_j\n",
+ "$$\n",
+ "\n",
+ "後で独立項を追加する必要があります。\n",
+ "\n",
+ "$$\n",
+ "\\texttt{offset} = - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2}\n",
+ "$$\n",
+ "\n",
+ "この変換は、[`QuadraticProgram.to_ising()`](https://qiskit.org/documentation/optimization/stubs/qiskit_optimization.QuadraticProgram.to_ising.html)で行うことができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "observable, offset = quadratic_program.to_ising()\n",
+ "print(\"Offset:\", offset)\n",
+ "print(\"Ising Hamiltonian:\")\n",
+ "print(str(observable))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "VQE インスタンスを使用して、次のように最適なパラメーターを見つけることができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.primitives import Estimator\n",
+ "from qiskit.algorithms.minimum_eigensolvers import VQE\n",
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "from qiskit.circuit.library import TwoLocal\n",
+ "import numpy as np\n",
+ "\n",
+ "ansatz = TwoLocal(observable.num_qubits, \"rx\", reps=1)\n",
+ "optimizer = COBYLA()\n",
+ "\n",
+ "vqe = VQE(\n",
+ " estimator=Estimator(),\n",
+ " ansatz=ansatz,\n",
+ " optimizer=optimizer,\n",
+ " initial_point=np.zeros(ansatz.num_parameters),\n",
+ ")\n",
+ "\n",
+ "result = vqe.compute_minimum_eigenvalue(observable)\n",
+ "\n",
+ "print(result)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.quantum_info import Statevector\n",
+ "\n",
+ "optimal_circuit = result.optimal_circuit.bind_parameters(result.optimal_parameters)\n",
+ "\n",
+ "x = max_cut.sample_most_likely(Statevector(optimal_circuit))\n",
+ "print(\"energy:\", result.eigenvalue.real)\n",
+ "print(\"time:\", result.optimizer_time)\n",
+ "print(\"max-cut objective:\", result.eigenvalue.real + offset)\n",
+ "print(\"solution:\", x)\n",
+ "print(\"solution objective:\", quadratic_program.objective.evaluate(x))\n",
+ "\n",
+ "# plot results\n",
+ "colors = [\"red\" if x[i] == 0 else \"orange\" for i in range(n)]\n",
+ "draw_graph(G, colors)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "このレッスンでは、次のことを学びました。\n",
+ "\n",
+ "- カスタム変分アルゴリズムの書き方\n",
+ "- 変分アルゴリズムを適用して最小固有値を見つける方法\n",
+ "- 変分アルゴリズムを利用してアプリケーションのユースケースを解く方法\n",
+ "\n",
+ "最終レッスンに進み、評価を受けてバッジを獲得しましょう!"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/badge/badge.ipynb b/translations/ja/algorithm-design/badge/badge.ipynb
new file mode 100644
index 00000000..cce31af0
--- /dev/null
+++ b/translations/ja/algorithm-design/badge/badge.ipynb
@@ -0,0 +1,52 @@
+{
+ "cells": [
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## バッジの取得\n",
+ "\n",
+ "変分アルゴリズムデザインのコースを修了された方、おめでとうございます。評価とバッジに進む前に、以下の1分間のアンケートにお答えください!\n",
+ "\n",
+ "\n",
+ " "
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## バッジ評価へのリンク\n",
+ "\n",
+ "[この評価](https://challenges.quantum-computing.ibm.com/algorithm-design) はオープンブックで、このコースで学んだ概念的な知識と実践的な知識をテストします。このコースはいつでも自由に戻って参照することができます!"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/cost_function/cost_function.ipynb b/translations/ja/algorithm-design/cost_function/cost_function.ipynb
new file mode 100644
index 00000000..2afac2f3
--- /dev/null
+++ b/translations/ja/algorithm-design/cost_function/cost_function.ipynb
@@ -0,0 +1,940 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## コスト関数\n",
+ "\n",
+ "このレッスンでは、 *コスト関数* を評価する方法について学びます:\n",
+ "\n",
+ "- まず、 [Qiskit Runtime primitives](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/primitives.html) について学びます。\n",
+ "- *コスト関数* $C(\\vec\\theta)$ を定義します。これは、オプティマイザーが最小化(または最大化)するための問題の目標を定義する問題固有の関数です。\n",
+ "- Qiskit Runtime primitiveで測定のストラテジーを定義し、速度と精度を最適化します。\n",
+ "\n",
+ " \n",
+ "\n",
+ "![Cost function workflow](images/cost_function_workflow.png)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "primitives": {
+ "text": "基本的・基礎的な操作やデータ型。Qiskitは、変分アルゴリズムのような複雑なワークロードを簡単に構築するためのビルディングブロックとして、SamplerとEstimatorのprimitiveを備えています。",
+ "title": "Primitive"
+ }
+ }
+ },
+ "source": [
+ "## Primitive\n",
+ "\n",
+ "古典的なものであれ量子的なものであれ、すべての物理系は異なる状態で存在することができます。例えば、道路を走る車は、その状態を特徴づける特定の質量、位置、速度、または加速度を持つことができます。同様に、量子系も異なる構成や状態を持つことができますが、測定や状態変化の扱い方が古典系と異なります。そのため、 *重ね合わせ* や *エンタングルメント* など、量子力学にしかないユニークな性質が生まれます。車の状態を速度や加速度などの物理的特性で表現できるように、量子系の状態も数学的な対象である *観測量* を用いて表現することができます。\n",
+ "\n",
+ "量子力学では、状態は正規化された複素列ベクトル、または *ケット* ( $|\\psi\\rangle$ )で表され、観測量はケットに作用するエルミート線形演算子( $\\hat{H}=\\hat{H}^{\\dagger}$ ) です。観測量の固有ベクトル ( $|\\lambda\\rangle$ ) は*固有状態*と呼ばれます。その固有状態( $|\\lambda\\rangle$ ) の一つで観測量を測定すると、対応する固有値( $\\lambda$ )を読み出すことができます。\n",
+ "\n",
+ "量子系をどのように測定するのか、何を測定できるのか疑問に思っている方に、Qiskitは2つの [primitive](gloss:primitives) を提供しています:\n",
+ "\n",
+ "- `Sampler`: 量子状態 $|\\psi\\rangle$ が与えられたとき、このprimitiveは、各計算基底状態の確率を求めます。\n",
+ "- `Estimator`: 量子観測量 $\\hat{H}$ と状態 $|\\psi\\rangle$ が与えられたとき、このprimitiveは $\\hat{H}$ の期待値を計算します。\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Sampler primitive\n",
+ "\n",
+ " `Sampler` primitiveは、状態 $|\\psi\\rangle$ を準備する量子回路がある場合、計算基底で各可能な状態 $|k\\rangle$ を得る確率を計算します。つまり以下を計算します:\n",
+ "\n",
+ "$$\n",
+ "p_k = |\\langle k | \\psi \\rangle|^2 \\quad \\forall k \\in \\mathbb{Z}_2^n \\equiv \\{0,1,\\cdots,2^n-1\\},\n",
+ "$$\n",
+ "\n",
+ "ここで、 $n$ は量子ビットの数、 $k$ は出力可能なバイナリー文字列 $\\{0,1\\}^n$ の整数表現(すなわち、整数の基底 $2$ )です。\n",
+ "\n",
+ " [Qiskit Runtime](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Sampler.html) の `Sampler` は、量子デバイス上で回路を複数回実行し、実行ごとに測定を行い、回収したビット列から確率分布を再構築します。実行回数( *ショット数* )が多いほど精度の高い結果が得られますが、その分時間と量子リソースが必要になります。\n",
+ "\n",
+ "しかし、可能な出力の数は量子ビット数 $n$ (すなわち $2^n$ )に対して指数関数的に増加するため、 *密な* 確率分布をえるためには、ショット数も同様に指数関数的に増加する必要があります。したがって、 `Sampler` は、 疎な
確率分布に対してのみ効率的です。つまり、ターゲットとする状態 $|\\psi\\rangle$ は、計算基底状態の線形結合として表現可能でなければならず、項の数は量子ビット数に対して最大でも多項式に増加するものである必要があります\n",
+ "\n",
+ "$$\n",
+ "|\\psi\\rangle = \\sum^{\\text{Poly}(n)}_k w_k |k\\rangle.\n",
+ "$$\n",
+ "\n",
+ "また、`Sampler` は、可能な全状態のサブセットを表す回路のサブセクションから確率を取得するように構成することができます。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "pauli": {
+ "text": "量子コンピューターにおいて、量子状態を表現・操作するために一般的に用いられる行列の集合で、恒等行列と3つのパウリ行列(X、Y、Z)で構成されます。",
+ "title": "パウリ演算子"
+ }
+ }
+ },
+ "source": [
+ "### Estimator primitive\n",
+ "\n",
+ "`Estimator` primitiveは、量子状態 $|\\psi\\rangle$ に対する観測量 $\\hat{H}$ の期待値を計算します。ここで、観測量の確率 $p_\\lambda = |\\langle\\lambda|\\psi\\rangle|^2$ として表現でき、 $|\\lambda\\rangle$ は観測量 $\\hat{H}$ の固有状態です。期待値とは、状態$ |\\psi\\rangle$ を測定したときに得られるすべての可能な結果 $\\lambda$ (すなわち観測量の固有値)の平均を、対応する確率で重み付けしたものと定義されます:\n",
+ "\n",
+ "$$\n",
+ "\\langle\\hat{H}\\rangle_\\psi := \\sum_\\lambda p_\\lambda \\lambda = \\langle \\psi | \\hat{H} | \\psi \\rangle\n",
+ "$$\n",
+ "\n",
+ "しかし、観測量の期待値を計算することは、その固有基底を知らないことが多いため、必ずしも可能ではありません。[Qiskit Runtime](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Estimator.html) の `Estimator` は、複雑な代数的処理を用いて、観測量を固有基底がわかっている他の観測量の組み合わせに分解することで、実際の量子デバイスでの期待値を推定します。\n",
+ "\n",
+ "簡単に言うと、 `Estimator` は、測定方法が分からない観測量を、 [パウリ演算子](gloss:pauli) と呼ばれるより簡単で測定可能な観測量に分解します。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "どんな演算子も $4^n$ 個のパウリ演算子の組み合わせで表すことができます。\n",
+ "\n",
+ "$$\n",
+ "\\hat{P}_k := \n",
+ "\\sigma_{k_{n-1}}\\otimes \\cdots \\otimes \\sigma_{k_0} \\quad \n",
+ "\\forall k \\in \\mathbb{Z}_4^n \\equiv \\{0,1,\\cdots,4^n-1\\}, \\\\\n",
+ "$$\n",
+ "\n",
+ "よって\n",
+ "\n",
+ "$$\n",
+ "\\hat{H} = \\sum^{4^n-1}_{k=0} w_k \\hat{P}_k\n",
+ "$$\n",
+ "\n",
+ "ここで、 $n$ は量子ビット数、 $k_l \\in \\mathbb{Z}_4 \\equiv \\{0, 1, 2, 3\\}$ (つまり整数の基底 $4$ ) の $k \\equiv k_{n-1} \\cdots k_0$ であり、 $(\\sigma_0, \\sigma_1, \\sigma_2, \\sigma_3) := (I, X, Y, Z)$ です。\n",
+ "\n",
+ "この分解を行った後、`Estimator` は各観測量 $\\hat{P}_k$ に対して(つまり元の回路から)新しい回路 $V_k|\\psi\\rangle$ を導出し、計算基底においてパウリ観測量を効果的に *対角化* し、測定します。パウリ観測量を容易に測定できるのは、 $V_k$ を前もって知っているからであり、他の観測量では一般にそうではありません。\n",
+ "\n",
+ "各 `{latex} \\hat{P}_{k}` について、 `Estimator` は対応する回路を量子デバイス上で複数回実行し、計算基底の出力状態を測定し、各出力 $j$ を得る確率 $p_{kj}$ を計算します。次に、各出力 $j$ に対応する $P_k$ の固有値 $\\lambda_{kj}$ を探し、 $w_k$ を掛け、全ての結果を加算して、与えられた状態 $|\\psi\\rangle$ に対する観測量 $\\hat{H}$ の期待値を求めます。\n",
+ "\n",
+ "$$\n",
+ "\\langle\\hat{H}\\rangle_\\psi = \n",
+ "\\sum_{k=0}^{4^n-1} w_k \\sum_{j=0}^{2^n-1}p_{kj} \\lambda_{kj},\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "sampling": {
+ "text": "1つまたは複数の物事を数回に分けて測定すること。",
+ "title": "Sampling"
+ }
+ }
+ },
+ "source": [
+ "$4^n$ 個のパウリの期待値を計算するのは非現実的(つまり指数関数的に大きくなる)なので、 `Estimator` は大量の $w_k$ がゼロのとき(つまり *密*ではなく*疎* のPauli分解)だけ効率化できます。形式的には、この計算が *効率的に解ける* ためには、ゼロでない項の数が量子ビット数 $n$ に対して最大で多項式に増加しなければならないと言うことになります: $\\hat{H} = \\sum^{\\text{Poly}(n)}_k w_k \\hat{P}_k.$\n",
+ "\n",
+ "読者は、確率 [サンプリング](gloss:sampling) も `Sampler` で説明したように効率的である必要があるという暗黙の仮定に気づくかもしれません。つまり、\n",
+ "\n",
+ "$$\n",
+ "\\langle\\hat{H}\\rangle_\\psi = \n",
+ "\\sum_{k}^{\\text{Poly}(n)} w_k \\sum_{j}^{\\text{Poly}(n)}p_{kj} \\lambda_{kj}.\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 期待値算出のためのガイド例\n",
+ "\n",
+ "1量子ビット状態 $|+\\rangle := H|0\\rangle = \\frac{1}{\\sqrt{2}}(|0\\rangle + |1\\rangle)$ とその観測量を以下のように想定します:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\hat{H}\n",
+ "& = \\begin{pmatrix} \n",
+ "-1 & 2 \\\\\n",
+ "2 & -1 \\\\\n",
+ "\\end{pmatrix}\\\\[1mm]\n",
+ "& = 2X - Z\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "理論的な期待値は $\\langle\\hat{H}\\rangle_+ = \\langle+|\\hat{H}|+\\rangle = 2$ です。\n",
+ "\n",
+ "この観測量を測定する方法を知らないので、その期待値を直接計算することはできず、 $\\langle\\hat{H}\\rangle_+ = 2\\langle X \\rangle_+ - \\langle Z \\rangle_+ $ と再表現する必要があります。これは、 $\\langle+|X|+\\rangle = 1$ 、 $\\langle+|Z|+\\rangle = 0$ であることに注意すれば、同じ結果になることを示すことができます。\n",
+ "\n",
+ " $\\langle X \\rangle_+$ と $\\langle Z \\rangle_+$ を直接計算する方法を説明します。 $X$ と $Z$ は交換しない(つまり同じ固有基底を共有しない)ので、同時に測定することはできず、補助回路が必要です:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit import QuantumCircuit\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "\n",
+ "# The following code will work for any other initial single-qubit state and observable\n",
+ "original_circuit = QuantumCircuit(1)\n",
+ "original_circuit.h(0)\n",
+ "\n",
+ "H = SparsePauliOp([\"X\", \"Z\"], [2, -1])\n",
+ "\n",
+ "aux_circuits = []\n",
+ "for pauli in H.paulis:\n",
+ " aux_circ = original_circuit.copy()\n",
+ " aux_circ.barrier()\n",
+ " if str(pauli) == \"X\":\n",
+ " aux_circ.h(0)\n",
+ " elif str(pauli) == \"Y\":\n",
+ " aux_circ.sdg(0)\n",
+ " aux_circ.h(0)\n",
+ " else:\n",
+ " aux_circ.i(0)\n",
+ " aux_circ.measure_all()\n",
+ " aux_circuits.append(aux_circ)\n",
+ "\n",
+ "\n",
+ "print(\"Original circuit:\")\n",
+ "display(original_circuit.draw(\"mpl\"))\n",
+ "for (circuit, pauli) in zip(aux_circuits, H.paulis):\n",
+ " print(f\"Auxiliary circuit for {str(pauli)}\")\n",
+ " display(circuit.draw(\"mpl\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "あとは、 `Sampler` を使って手動で計算を行い、 `Estimator` で結果を確認します:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.primitives import Sampler, Estimator\n",
+ "from qiskit.circuit.library import IGate, ZGate\n",
+ "import numpy as np\n",
+ "\n",
+ "\n",
+ "## SAMPLER\n",
+ "sampler = Sampler()\n",
+ "job = sampler.run(aux_circuits)\n",
+ "probability_dists = job.result().quasi_dists\n",
+ "\n",
+ "expvals = []\n",
+ "for dist, pauli in zip(probability_dists, H.paulis):\n",
+ " val = 0\n",
+ " if str(pauli) == \"I\":\n",
+ " Lambda = IGate().to_matrix().real\n",
+ " else:\n",
+ " Lambda = ZGate().to_matrix().real\n",
+ " val += Lambda[0][0] * dist.get(0, 0)\n",
+ " val += Lambda[1][1] * dist.get(1, 0)\n",
+ " expvals.append(val)\n",
+ "\n",
+ "\n",
+ "print(\"Sampler results:\")\n",
+ "for (pauli, expval) in zip(H.paulis, expvals):\n",
+ " print(f\" >> Expected value of {str(pauli)}: {expval:.5f}\")\n",
+ "\n",
+ "total_expval = np.sum(H.coeffs * expvals).real\n",
+ "print(f\" >> Total expected value: {total_expval:.5f}\")\n",
+ "\n",
+ "\n",
+ "## ESTIMATOR\n",
+ "observables = [\n",
+ " *H.paulis,\n",
+ " H,\n",
+ "] # Note: run for individual Paulis as well as full observable H\n",
+ "\n",
+ "estimator = Estimator()\n",
+ "job = estimator.run([original_circuit] * len(observables), observables)\n",
+ "estimator_expvals = job.result().values\n",
+ "\n",
+ "print(\"Estimator results:\")\n",
+ "for (obs, expval) in zip(observables, estimator_expvals):\n",
+ " if obs is not H:\n",
+ " print(f\" >> Expected value of {str(obs)}: {expval:.5f}\")\n",
+ " else:\n",
+ " print(f\" >> Total expected value: {expval:.5f}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 数学的厳密性(オプション)\n",
+ "\n",
+ "$|\\psi\\rangle$ を $\\hat{H}$ の固有状態の基底 $|\\psi\\rangle = \\sum_\\lambda a_\\lambda |\\lambda\\rangle$ に関して表現すると、次のようになります。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle \\psi | \\hat{H} | \\psi \\rangle\n",
+ "& = \\bigg(\\sum_{\\lambda'}a^*_{\\lambda'} \\langle \\lambda'|\\bigg) \\hat{H} \n",
+ " \\bigg(\\sum_{\\lambda} a_\\lambda | \\lambda\\rangle\\bigg)\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{\\lambda}\\sum_{\\lambda'} a^*_{\\lambda'}a_{\\lambda} \n",
+ " \\langle \\lambda'|\\hat{H}| \\lambda\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{\\lambda}\\sum_{\\lambda'} a^*_{\\lambda'}a_{\\lambda} \\lambda \n",
+ "\\langle \\lambda'| \\lambda\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{\\lambda}\\sum_{\\lambda'} a^*_{\\lambda'}a_{\\lambda} \\lambda \n",
+ "\\cdot \\delta_{\\lambda, \\lambda'}\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_\\lambda |a_\\lambda|^2 \\lambda\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_\\lambda p_\\lambda \\lambda\\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "hermitian": {
+ "text": "エルミート行列とは、自身の共役転置と等しい正方行列、または自己共役である線形演算子のことです。",
+ "title": "エルミート"
+ }
+ }
+ },
+ "source": [
+ "観測対象 $\\hat{H}$ の固有値や固有状態は分からないので、まずその対角化を考える必要があります。 $\\hat{H}$ が [エルミート](gloss:hermitian) であることを考えると、$\\hat{H}=V^\\dagger \\Lambda V$ となるようなユニタリー変換 $V$ が存在し、 $\\Lambda$ は固有値の対角行列なので、 $j\\neq k$ なら $\\langle j | \\Lambda | k \\rangle = 0$ で $\\langle j | \\Lambda | j \\rangle = \\lambda_j$ です。\n",
+ "\n",
+ "これは、期待値が次のように書き換えられることを意味します:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle\\psi|\\hat{H}|\\psi\\rangle\n",
+ "& = \\langle\\psi|V^\\dagger \\Lambda V|\\psi\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\langle\\psi|V^\\dagger \\bigg(\\sum_{j=0}^{2^n-1} |j\\rangle \n",
+ "\\langle j|\\bigg) \\Lambda \\bigg(\\sum_{k=0}^{2^n-1} |k\\rangle \\langle k|\\bigg) V|\\psi\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{j=0}^{2^n-1} \\sum_{k=0}^{2^n-1}\\langle\\psi|V^\\dagger |j\\rangle \n",
+ "\\langle j| \\Lambda |k\\rangle \\langle k| V|\\psi\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{j=0}^{2^n-1}\\langle\\psi|V^\\dagger |j\\rangle \n",
+ "\\langle j| \\Lambda |j\\rangle \\langle j| V|\\psi\\rangle\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{j=0}^{2^n-1}|\\langle j| V|\\psi\\rangle|^2 \\lambda_j\\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "系が $|\\phi\\rangle = V |\\psi\\rangle$ の状態にあるとき、 $| j\\rangle$ を測定する確率が $p_j = |\\langle j|\\phi \\rangle|^2$ であることを考えると、上記の期待値は次のように表すことができる:\n",
+ "\n",
+ "$$\n",
+ "\\langle\\psi|\\hat{H}|\\psi\\rangle = \n",
+ "\\sum_{j=0}^{2^n-1} p_j \\lambda_j.\n",
+ "$$\n",
+ "\n",
+ "確率は $|\\psi\\rangle$ ではなく、状態 $V |\\psi\\rangle$ から取られることが非常に重要です。これが行列 $V$ が絶対に必要な理由です。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "行列 $V$ と固有値 $\\Lambda$ をどうやって求めるのか、疑問に思うかもしれません。もし、すでに固有値があれば、変分アルゴリズムの目的はこの $\\hat{H}$ の固有値を求めることなので、量子コンピューターを使う必要はないでしょう。\n",
+ "\n",
+ "幸い、それを回避する方法があります:任意の $2^n \\times 2^n$ 行列は、 $n$ 個のパウリ行列と恒等演算子の $4^n$ 個のテンソル積の線形結合として書くことができ、これらはすべて、既知の $V$ と $\\Lambda$ を持つエルミート行列でありユニタリー行列です。 これが、Runtimeの `Estimator` が内部で行っていることで、`Estimator` は任意の [Operator](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Operator.html) オブジェクトを[SparsePauliOp](https://qiskit.org/documentation/stubs/qiskit.quantum_info.SparsePauliOp.html) に分解しています。\n",
+ "\n",
+ "ここでは、使用可能な演算子を紹介します:\n",
+ "\n",
+ "$$\n",
+ "\\begin{array}{c|c|c|c}\n",
+ " \\text{Operator} & \\sigma & V & \\Lambda \\\\[1mm]\n",
+ " \\hline\n",
+ " I & \\sigma_0 = \\begin{pmatrix} 1 & 0 \\\\ 0 & 1 \\end{pmatrix} & V_0 = I & \\Lambda_0 = I = \\begin{pmatrix} 1 & 0 \\\\ 0 & 1 \\end{pmatrix} \\\\[4mm]\n",
+ "\n",
+ " X & \\sigma_1 = \\begin{pmatrix} 0 & 1 \\\\ 1 & 0 \\end{pmatrix} & V_1 = H =\\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix} & \\Lambda_1 = \\sigma_3 = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix} \\\\[4mm]\n",
+ "\n",
+ " Y & \\sigma_2 = \\begin{pmatrix} 0 & -i \\\\ i & 0 \\end{pmatrix} & V_2 = HS^\\dagger =\\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & 1 \\\\ 1 & -1 \\end{pmatrix}\\cdot \\begin{pmatrix} 1 & 0 \\\\ 0 & -i \\end{pmatrix} = \\frac{1}{\\sqrt{2}} \\begin{pmatrix} 1 & -i \\\\ 1 & i \\end{pmatrix}\\quad & \\Lambda_2 = \\sigma_3 = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix} \\\\[4mm]\n",
+ "\n",
+ " Z & \\sigma_3 = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix} & V_3 = I & \\Lambda_3 = \\sigma_3 = \\begin{pmatrix} 1 & 0 \\\\ 0 & -1 \\end{pmatrix}\n",
+ "\\end{array}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "では、 $\\hat{H}$ をパウリ演算子と恒等演算子に関して書き換えてみましょう:\n",
+ "\n",
+ "$$\n",
+ "\\hat{H} = \n",
+ "\\sum_{k_{n-1}=0}^3...\n",
+ "\\sum_{k_0=0}^3 w_{k_{n-1}...k_0} \n",
+ "\\sigma_{k_{n-1}}\\otimes ... \\otimes \\sigma_{k_0} = \\sum_{k=0}^{4^n-1} w_k \\hat{P}_k,\n",
+ "$$\n",
+ "\n",
+ "ここで、 $k = \\sum_{l=0}^{n-1} 4^l k_l \\equiv k_{n-1}...k_0$ は $k_{n-1},...,k_0\\in \\{0,1,2,3\\}$ (つまり基底 $4$ )であり、`{latex} \\hat{P}_{k} := \\sigma_{k_{n-1}}\\otimes ... \\otimes \\sigma_{k_0}`:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle\\psi|\\hat{H}|\\psi\\rangle\n",
+ "& = \\sum_{k=0}^{4^n-1} w_k \n",
+ "\\sum_{j=0}^{2^n-1}|\\langle j| V_k|\\psi\\rangle|^2 \\langle j| \\Lambda_k |j\\rangle \\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{k=0}^{4^n-1} w_k \\sum_{j=0}^{2^n-1}p_{kj} \\lambda_{kj}, \\\\[1mm]\n",
+ "\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "ここで $V_k := V_{k_{n-1}}\\otimes ... \\otimes V_{k_0}$ と $\\Lambda_k := \\Lambda_{k_{n-1}}\\otimes ... \\otimes \\Lambda_{k_0}$ は $\\hat{P_k}=V_k^\\dagger \\Lambda_k V_k$ です。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "oracle": {
+ "text": " 特定の機能を果たすが、その内部構造が不明な仮想的な装置またはソフトウェア・コンポーネント。ユーザーはブラックボックスの入力と出力しか知らず、ブラックボックスが入力を処理して出力を生成する方法については知らない。",
+ "title": "ブラックボックスオラクル"
+ }
+ }
+ },
+ "source": [
+ "## コスト関数\n",
+ "\n",
+ "一般に、コスト関数は、問題のゴールと、そのゴールに対して試行状態がどの程度うまくいっているかを記述するために使用されます。この定義は、化学、機械学習、金融、最適化など、さまざまな例に適用することができます。\n",
+ "\n",
+ "あるシステムの基底状態を求めるという簡単な例を考えてみましょう。我々の目的は、エネルギーを表す観測量(ハミルトニアン $\\hat{\\mathcal{H}}$ )の期待値を最小化することです:\n",
+ "\n",
+ "$$\n",
+ "\\min_{\\vec\\theta} \\langle\\psi(\\vec\\theta)|\\hat{\\mathcal{H}}|\\psi(\\vec\\theta)\\rangle\n",
+ "$$\n",
+ "\n",
+ "[*Estimator* primitive](https://github.com/qiskit-community/prototype-zne/blob/main/docs/tutorials/0-estimator.ipynb) を使用して期待値を評価し、この値をオプティマイザーに渡して最小化することができます。最適化が成功すれば、最適なパラメーター値のセット $\\vec\\theta^*$ が返され、そこから提案された解の状態 $|\\psi(\\vec\\theta^*)\\rangle$ を構築し、観測された期待値を $C(\\vec\\theta^*)$ として計算することができるようになります。\n",
+ "\n",
+ "私たちが考えている状態の限られたセットに対してのみ、コスト関数を最小化することができることに注目してください。このことから、2つの別々の可能性があることがわかります:\n",
+ "\n",
+ "- **我々のansatzが、探索空間全体で解の状態を定義していない**: この場合、オプティマイザーは解を見つけることができないので、探索空間をより正確に表現できるかもしれない他のansatzを試してみる必要があります。\n",
+ "- **オプティマイザーが、有効な解を見つけることができない**: 最適化には、大域的な定義と局所的な定義があります。この意味については、後のセクションで説明します。\n",
+ "\n",
+ "全体として、私たちは古典的な最適化ループを実行しますが、コスト関数の評価を量子コンピューターに依存することになります。この観点から、最適化は純粋に古典的な取り組みであり、オプティマイザーがコスト関数を評価する必要があるたびに、 [*ブラックボックスの量子オラクル*](gloss:oracle) を呼び出すと考えることができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "from qiskit import QuantumCircuit\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService, Estimator\n",
+ "\n",
+ "# Add your token below\n",
+ "service = QiskitRuntimeService(channel=\"ibm_quantum\")\n",
+ "\n",
+ "def cost_function_vqe(theta):\n",
+ " observable = SparsePauliOp.from_list([(\"XX\", 1), (\"YY\", -3)])\n",
+ "\n",
+ " reference_circuit = QuantumCircuit(2)\n",
+ " reference_circuit.x(0)\n",
+ "\n",
+ " variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ " )\n",
+ " ansatz = reference_circuit.compose(variational_form)\n",
+ "\n",
+ " backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ " \n",
+ " # Use estimator to get the expected values corresponding to each ansatz\n",
+ " estimator = Estimator(session=backend)\n",
+ " job = estimator.run(ansatz, observable, theta)\n",
+ " values = job.result().values\n",
+ "\n",
+ " return values\n",
+ "\n",
+ "\n",
+ "theta_list = (2 * np.pi * np.random.rand(1, 8)).tolist()\n",
+ "cost_function_vqe(theta_list)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 物理でないシステムへのマッピング例\n",
+ "\n",
+ "マックスカット(Max-Cut)問題とは、グラフの頂点を2つの不連続な集合に分割し、その2つの集合間の辺の数が最大になるようにする組合せ最適化問題です。より正式には、 $V$ が頂点の集合、 $E$ が辺の集合である無向グラフ $G=(V,E)$ が与えられたとき、マックスカット問題は、頂点を2つの不連続な部分集合、 $S$ と$T$ Tに分割する際に、一方の端点が $S$ にあり他方が $T$ にあるような辺の数が最大となるように求めます。\n",
+ "\n",
+ "マックスカットを応用して、クラスタリング、ネットワーク設計、相転移など様々な問題を解くことができます。まず、問題グラフを作成することから始めます:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import networkx as nx\n",
+ "\n",
+ "n = 4\n",
+ "G = nx.Graph()\n",
+ "G.add_nodes_from(range(n))\n",
+ "edge_list = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)]\n",
+ "G.add_weighted_edges_from(edge_list)\n",
+ "\n",
+ "colors = [\"red\" for i in range(n)]\n",
+ "\n",
+ "\n",
+ "def draw_graph(G, colors):\n",
+ " \"\"\"Draws the graph with the chose colors\"\"\"\n",
+ " layout = nx.shell_layout(G)\n",
+ " nx.draw_networkx(G, node_color=colors, pos=layout)\n",
+ " edge_labels = nx.get_edge_attributes(G, \"weight\")\n",
+ " nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=edge_labels)\n",
+ "\n",
+ "\n",
+ "draw_graph(G, colors)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この問題は、2値最適化問題として表現できます。各 $0 \\leq i < n$ ( $n$ はグラフのノード数で、この場合 $n=4$ )に対して、バイナリー変数 $x_i$ を考えます。この変数は、ノード $i$ が $1$ のラベルを貼ったグループの1つであれば値 $1$ を持ち、 $0$ とラベルを貼った他のグループの1つであれば値 $0$ を持つことになります。また、ノード $i$ からノード $j$ に至るエッジの重みを $w_{ij}$ (隣接行列 $w$の要素 $(i,j)$ )とします。グラフは無向性なので、 $w_{ij}=w_{ji}$ となります。そうすると、問題は以下のコスト関数を最大化するものとして定式化できます:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "C(\\vec{x})\n",
+ "& =\\sum_{i,j=0}^n w_{ij} x_i(1-x_j)\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n w_{ij} x_i - \\sum_{i,j=0}^n w_{ij} x_ix_j\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n w_{ij} x_i - \\sum_{i=0}^n \\sum_{j=0}^i 2w_{ij} x_ix_j\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "この問題を量子コンピューターで解決するために、コスト関数を観測量の期待値として表現することになります。しかし、Qiskitがネイティブで認める観測量は、固有値が $0$ と $1$ ではなく $1$ と $-1$ であるパウリ演算子で構成されているため、以下のように変数を変更します:\n",
+ "\n",
+ "ここで、 $\\vec{x}=(x_0,x_1,\\cdots ,x_{n-1})$ です。隣接行列 $w$ を使って、すべてのエッジの重みに快適にアクセスすることができます。これはコスト関数を求めるのに使われます:\n",
+ "\n",
+ "$$\n",
+ "z_i = 1-2x_i \\rightarrow x_i = \\frac{1-z_i}{2}\n",
+ "$$\n",
+ "\n",
+ "これはつまり、\n",
+ "\n",
+ "$$\n",
+ "\\begin{array}{lcl} x_i=0 & \\rightarrow & z_i=1 \\\\ x_i=1 & \\rightarrow & z_i=-1.\\end{array}\n",
+ "$$\n",
+ "\n",
+ "よって私たちが最大化したいコスト関数は新たに\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "C(\\vec{z})\n",
+ "& = \\sum_{i,j=0}^n w_{ij} \\bigg(\\frac{1-z_i}{2}\\bigg)\\bigg(1-\\frac{1-z_j}{2}\\bigg)\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i,j=0}^n \\frac{w_{ij}}{4} - \\sum_{i,j=0}^n \\frac{w_{ij}}{4} z_iz_j\\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} z_iz_j\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "さらに、量子コンピューターの自然な傾向として、最大値ではなく最小値(通常は最低エネルギー)を見つけるので、 $C(\\vec{z})$ を最大化するのではなく、最小化します:\n",
+ "\n",
+ "$$\n",
+ "-C(\\vec{z}) = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} z_iz_j - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2}\n",
+ "$$\n",
+ "\n",
+ "ここで、最小化するコスト関数があり、その変数は $-1$ と $1$ の値を持つので、パウリ $Z$ について、以下のアナロジーを使えます:\n",
+ "\n",
+ "$$\n",
+ "z_i \\equiv Z_i = \\overbrace{I}^{n-1}\\otimes ... \\otimes \\overbrace{Z}^{i} \\otimes ... \\otimes \\overbrace{I}^{0}\n",
+ "$$\n",
+ "\n",
+ "つまり、変数 $z_i$ は、量子ビット $i$ に作用する $Z$ ゲートに相当することになります:\n",
+ "\n",
+ "$$\n",
+ "Z_i|x_{n-1}\\cdots x_0\\rangle = z_i|x_{n-1}\\cdots x_0\\rangle \\rightarrow \\langle x_{n-1}\\cdots x_0 |Z_i|x_{n-1}\\cdots x_0\\rangle = z_i\n",
+ "$$\n",
+ "\n",
+ "そうすると、考えている観測量は以下のように書くことができ:\n",
+ "\n",
+ "$$\n",
+ "\\hat{H} = \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2} Z_iZ_j\n",
+ "$$\n",
+ "\n",
+ "であり、その後に独立した項を追加する必要があります:\n",
+ "\n",
+ "$$\n",
+ "\\texttt{offset} = - \\sum_{i=0}^n \\sum_{j=0}^i \\frac{w_{ij}}{2}\n",
+ "$$\n",
+ "\n",
+ "この変換は、[`QuadraticProgram.to_ising()`](https://qiskit.org/documentation/optimization/stubs/qiskit_optimization.QuadraticProgram.to_ising.html)で行うことができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit_optimization.applications import Maxcut\n",
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "\n",
+ "w = nx.to_numpy_array(G)\n",
+ "\n",
+ "max_cut = Maxcut(w)\n",
+ "quadratic_program = max_cut.to_quadratic_program()\n",
+ "observable, offset = quadratic_program.to_ising()\n",
+ "\n",
+ "\n",
+ "def cost_function_max_cut_vqe(theta):\n",
+ "\n",
+ " ansatz = TwoLocal(\n",
+ " observable.num_qubits, \"rx\", reps=1\n",
+ " )\n",
+ "\n",
+ " backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ "\n",
+ " # Use estimator to get the expected values corresponding to each ansatz\n",
+ " estimator = Estimator(session=backend)\n",
+ " job = estimator.run(ansatz, observable, theta)\n",
+ " values = job.result().values\n",
+ "\n",
+ " return values\n",
+ "\n",
+ "\n",
+ "optimizer = COBYLA()\n",
+ "\n",
+ "initial_theta = np.ones(8)\n",
+ "\n",
+ "optimizer_result = optimizer.minimize(fun=cost_function_max_cut_vqe, x0=initial_theta)\n",
+ "\n",
+ "optimal_parameters = optimizer_result.x\n",
+ "print(optimal_parameters)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "この例をアプリケーションで再確認し、オプティマイザーを活用して探索空間を反復する方法を探ります。一般的には、以下のようなことが挙げられます:\n",
+ "\n",
+ "- オプティマイザーを活用して最適なパラメーターを見つける。\n",
+ "- 固有値を求めるための最適なパラメーターをansatzにバインドする。\n",
+ "- 固有値を我々の問題定義に置き換える。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 測定の戦略:スピード対精度\n",
+ "\n",
+ "すでに述べたように、ノイズの多い量子コンピューターを*ブラックボックスのオラクル*として使用しているため、ノイズによって取得される値が非決定的になり、ランダムな揺らぎが生じて、特定のオプティマイザーが提案した解に収束するのを阻害される、あるいは完全に妨害されることがあります。これは、量子的な利点を得るために段階的に進歩していく中で、私たちが対処しなければならない一般的な問題です:\n",
+ "\n",
+ "![Advantage](images/cost_function_path_to_quantum_advantage.png)\n",
+ "\n",
+ "Qiskit Runtime Primitiveのエラー抑制・エラー緩和オプションを利用してノイズに対応することで、今日の量子コンピューターの実用性を最大化することができます。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "overhead": {
+ "text": "基本的な実装の場合と比べて、新しい技術によってもたらされる余分なコスト。",
+ "title": "オーバーヘッド"
+ }
+ }
+ },
+ "source": [
+ "### エラー抑制\n",
+ "\n",
+ "[エラー抑制](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/how_to/error-suppression.html) とは、コンパイル時に回路を最適化して変換し、エラーを最小化するために使用する技術のことです。これは基本的なエラー処理技術であり、通常、ランタイム全体に対する古典的な前処理 [オーバーヘッド](gloss:overhead) をもたらします。このオーバーヘッドには、以下のような量子ハードウェア上で動作するように回路をトランスパイルすることが含まれます:\n",
+ "\n",
+ "- 量子システムで実行できるネイティブゲートで回路を表現する。\n",
+ "- 仮想量子ビットを物理量子ビットにマッピングする。\n",
+ "- コネクティビティの要件に基づくSWAPの追加。\n",
+ "- 1Qと2Qのゲートを最適化する。\n",
+ "- アイドルの量子ビットに動的デカップリングを追加し、デコヒーレンスの影響を防ぐ。\n",
+ "\n",
+ "Primitiveは、 optimization_level オプションを設定し、高度なトランスパイルオプションを選択することで、[エラー抑制技術](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/how_to/error-suppression.html) を使用することができます。この後のコースで、結果を改善するためのさまざまな回路構築方法を掘り下げますが、ほとんどの場合、`optimization_level=3` を設定することをお勧めします。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "bias": {
+ "text": "測定された量に生じる系統的な偏差のことで、通常は誤差によって生じる。",
+ "title": "偏り"
+ }
+ }
+ },
+ "source": [
+ "### エラー緩和\n",
+ "\n",
+ "[エラー緩和](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/how_to/error-mitigation.html) とは、実行時にデバイスのノイズをモデル化することで、回路エラーを低減させる技術を指します。一般的に、モデルのトレーニングに関連する量子的な前処理オーバーヘッドと、生成されたモデルを使用して生の結果のエラーを軽減するための古典的な後処理オーバーヘッドが発生することになります。\n",
+ "\n",
+ "Qiskit Runtime primitiveの `resilience_level` オプションは、エラーに対して構築する回復力の量を指定します。レベルが高いほど、量子サンプリングのオーバーヘッドによる処理時間の長さを犠牲にして、より正確な結果を生成します。レジリエンスレベルは、primitiveのクエリにエラー緩和を適用する際に、コストと精度のトレードオフを設定するために使用されます。\n",
+ "\n",
+ "どのようなエラー緩和技術を実装する場合でも、結果の [偏り](gloss:bias) は、以前の、緩和されていない偏りに対して減少することが期待されます。場合によっては、偏りが消えることさえあります。しかし、これには代償が伴います。推定量の偏りを減らすと、統計的なばらつき(つまり分散)が大きくなりますが、これはサンプリングプロセスで回路ごとのショット数をさらに増やすことで説明できます。この場合、偏りを減らすために必要な以上のオーバーヘッドが発生するため、デフォルトではこの動作は行われません。以下の例のように、options.executions.shotsで回路あたりのショット数を調整することで、この操作は、簡単に導入できます。\n",
+ "\n",
+ "![Bias Variance Trade-off](images/cost_function_bias_variance_trade_off.png)\n",
+ "\n",
+ "このコースでは、これらのエラー緩和モデルを高いレベルで探求し、完全な実装の詳細を必要とせずに、Qiskit Runtime primitiveが実行できるエラー緩和を説明します。\n",
+ "\n",
+ "### トワイル読み出しエラー消去法 (T-REx)\n",
+ "\n",
+ "トワイル読み出しエラー消去法 (Twirled Readout Error eXtinction, T-REx) は、パウリトワリングとして知られる技法を用いて、量子測定の過程で導入されるノイズを低減します。この手法は、特定の形態のノイズを想定していないため、非常に汎用的で効果的です。\n",
+ "\n",
+ "全体のワークフロー:\n",
+ "\n",
+ "1. ランダム化されたビットフリップを使用してゼロ状態のデータを取得します (測定前のパウリ X)。\n",
+ "2. ランダム化されたビットフリップを使用して目的の (ノイズの多い) 状態のデータを取得します (測定前のパウリ X)。\n",
+ "3. 各データセットの特殊関数を計算し、除算します。\n",
+ "\n",
+ " \n",
+ "\n",
+ "![TRE-X](images/cost_function_trex_data_collection.png)\n",
+ "\n",
+ "以下の例では、 `options.resilience_level = 1`で設定することができます。\n",
+ "\n",
+ "### ゼロ・ノイズ外挿\n",
+ "\n",
+ "ゼロノイズ外挿(ZNE)は、まず目的の量子状態を準備する回路のノイズを増幅し、いくつかの異なるレベルのノイズの測定値を得て、その測定値を用いてノイズのない結果を推論することで機能します。\n",
+ "\n",
+ "全体のワークフロー:\n",
+ "\n",
+ "1. いくつかのノイズ要因に対して回路ノイズを増幅する\n",
+ "2. すべてのノイズ増幅回路を実行する\n",
+ "3. ゼロノイズ限界に外挿する\n",
+ "\n",
+ " \n",
+ "\n",
+ "![ZNE](images/cost_function_zne_stages.png)\n",
+ "\n",
+ "これは `options.resilience_level = 2` で設定することができます。`noise_factors`, `noise_amplifiers`, `extrapolators` をいろいろと試すことで、さらに最適化できますが、これはこの講義コースの範囲外です。ぜひ、 [ここに書かれているようなオプション](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/how_to/error-mitigation.html#advanced-resilience-options) を使って実験してみてください。\n",
+ "\n",
+ "### 確率的エラー・キャンセル\n",
+ "\n",
+ "確率的エラー・キャンセル(PEC)は、平均的にノイズ反転チャネルを模倣する回路のコレクションをサンプリングして、目的の計算のノイズを打ち消します。このプロセスは、ノイズキャンセリングヘッドフォンの仕組みに少し似ており、素晴らしい結果をもたらしますが、他の方法ほど一般的ではなく、サンプリングのオーバーヘッドが指数関数的です。\n",
+ "\n",
+ "全体のワークフロー:\n",
+ "\n",
+ "![PEC](images/cost_function_pec_layers.png)\n",
+ "\n",
+ "ステップ 1: パウリトワリング\n",
+ "\n",
+ "![PEC Twirling](images/cost_function_pec_pauli_twirling.png)\n",
+ "\n",
+ "ステップ 2: レイヤーを繰り返したノイズの学習\n",
+ "\n",
+ "![PEC Learning](images/cost_function_pec_learn_layer.png)\n",
+ "\n",
+ "ステップ 3: 忠実度の導出 (各ノイズ・チャネルの誤差)\n",
+ "\n",
+ "![PEC Fidelity](images/cost_function_pec_curve_fitting.png)\n",
+ "\n",
+ "それぞれの方法には、量子計算の回数(時間)と結果の精度のトレードオフという、関連するオーバーヘッドがあります:\n",
+ "\n",
+ "$$\n",
+ "\\begin{array}{c|c|c|c}\n",
+ " \\text{Methods} & R=1 \\text{, T-REx} & R=2 \\text{, ZNE} & R=3 \\text{, PEC} \\\\[1mm]\n",
+ " \\hline\n",
+ " \\text{Assumptions} & \\text{None} & \\text{Ability to scale noise} & \\text{Full knowledge of noise} \\\\[1mm]\n",
+ " \\text{Qubit overhead} & 1 & 1 & 1 \\\\[1mm]\n",
+ " \\text{Sampling overhead} & 2 & N_{\\text{noise-factors}} & \\mathcal{O}(e^{\\lambda N_{layers}}) \\\\[1mm]\n",
+ " \\text{Bias} & 0 & \\mathcal{O}(\\lambda^{N_{\\text{noise-factors}}}) & 0 \\\\[1mm]\n",
+ "\\end{array}\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Qiskit Runtimeの緩和・抑制オプションの使い方\n",
+ "\n",
+ "Qiskit Runtimeでエラー緩和と抑制を使用しながら、期待値を計算する方法を紹介します。このプロセスは最適化ループの中で何度も発生しますが、エラー緩和と抑制の設定方法を示すために、この例はシンプルにしています。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit import Parameter, QuantumCircuit\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "\n",
+ "theta = Parameter(\"theta\")\n",
+ "\n",
+ "qc = QuantumCircuit(2)\n",
+ "qc.x(1)\n",
+ "qc.h(0)\n",
+ "qc.cp(theta, 0, 1)\n",
+ "qc.h(0)\n",
+ "observables = SparsePauliOp.from_list([(\"ZZ\", 1)])\n",
+ "\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## Setup phases\n",
+ "import numpy as np\n",
+ "\n",
+ "phases = np.linspace(0, 2 * np.pi, 50)\n",
+ "\n",
+ "# phases need to be expressed as a list of lists in order to work\n",
+ "individual_phases = [[phase] for phase in phases]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## Create noise model\n",
+ "from qiskit.providers.fake_provider import FakeManila\n",
+ "from qiskit_aer.noise import NoiseModel\n",
+ "from qiskit_ibm_runtime import Options\n",
+ "\n",
+ "\n",
+ "# Make a noise model\n",
+ "fake_backend = FakeManila()\n",
+ "noise_model = NoiseModel.from_backend(fake_backend)\n",
+ "\n",
+ "# Set options to include the noise model\n",
+ "options = Options()\n",
+ "options.simulator = {\n",
+ " \"noise_model\": noise_model,\n",
+ " \"basis_gates\": fake_backend.configuration().basis_gates,\n",
+ " \"coupling_map\": fake_backend.configuration().coupling_map,\n",
+ " \"seed_simulator\": 42,\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "tags": [
+ "uses-hardware"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "from qiskit_ibm_runtime import Session, QiskitRuntimeService, Estimator\n",
+ "\n",
+ "# Add your token below\n",
+ "service = QiskitRuntimeService(channel=\"ibm_quantum\")\n",
+ "\n",
+ "noisy_exp_values = []\n",
+ "exp_values_with_em_es = []\n",
+ "\n",
+ "with Session(service=service, backend=\"ibmq_qasm_simulator\") as session:\n",
+ " # generate noisy results\n",
+ " estimator = Estimator(options=options)\n",
+ " job = estimator.run(\n",
+ " circuits=[qc] * len(phases),\n",
+ " parameter_values=individual_phases,\n",
+ " observables=[observables] * len(phases),\n",
+ " shots=1000,\n",
+ " )\n",
+ " result = job.result()\n",
+ " noisy_exp_values = result.values\n",
+ "\n",
+ " options.optimization_level = 2\n",
+ " options.resilience_level = 1\n",
+ "\n",
+ " # leverage mitigation and suppression\n",
+ " estimator = Estimator(options=options)\n",
+ " job = estimator.run(\n",
+ " circuits=[qc] * len(phases),\n",
+ " parameter_values=individual_phases,\n",
+ " observables=[observables] * len(phases),\n",
+ " shots=1000,\n",
+ " )\n",
+ " result = job.result()\n",
+ " exp_values_with_em_es = result.values\n",
+ "\n",
+ " session.close()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "plt.plot(phases, noisy_exp_values, \"o\", label=\"Noisy\")\n",
+ "plt.plot(phases, exp_values_with_em_es, \"o\", label=\"Mitigation + Suppression\")\n",
+ "plt.plot(phases, 2 * np.sin(phases / 2) ** 2 - 1, label=\"Theory\")\n",
+ "plt.xlabel(\"Phase\")\n",
+ "plt.ylabel(\"Expectation\")\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "このレッスンでは、コスト関数を作成する方法について学びました:\n",
+ "\n",
+ "- コスト関数を作成する\n",
+ "- [Qiskit Runtime primitives](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/primitives.html) を活用してノイズを軽減・抑制する方法\n",
+ "- スピードと精度を最適化するための測定戦略の定義方法\n",
+ "\n",
+ "このハイレベルな変分の作業は次のようになります:\n",
+ "\n",
+ "![Cost Function Circuit](images/cost_function_circuit.png)\n",
+ "\n",
+ "このコスト関数は、最適化ループの各繰り返しで実行されます。次のレッスンでは、古典的なオプティマイザーが新しいパラメーターを選択するために、コスト関数の評価をどのように利用するかを探ります。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_bias_variance_trade_off.png b/translations/ja/algorithm-design/cost_function/images/cost_function_bias_variance_trade_off.png
new file mode 100644
index 00000000..3c6f94af
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_bias_variance_trade_off.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_circuit.png b/translations/ja/algorithm-design/cost_function/images/cost_function_circuit.png
new file mode 100644
index 00000000..cc6ccfcf
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_circuit.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_path_to_quantum_advantage.png b/translations/ja/algorithm-design/cost_function/images/cost_function_path_to_quantum_advantage.png
new file mode 100644
index 00000000..fb628f25
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_path_to_quantum_advantage.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_pec_curve_fitting.png b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_curve_fitting.png
new file mode 100644
index 00000000..81dbd902
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_curve_fitting.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_pec_layers.png b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_layers.png
new file mode 100644
index 00000000..18a49ff1
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_layers.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_pec_learn_layer.png b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_learn_layer.png
new file mode 100644
index 00000000..79f1f32e
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_learn_layer.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_pec_pauli_twirling.png b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_pauli_twirling.png
new file mode 100644
index 00000000..de67f13d
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_pec_pauli_twirling.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_trex_data_collection.png b/translations/ja/algorithm-design/cost_function/images/cost_function_trex_data_collection.png
new file mode 100644
index 00000000..72072be0
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_trex_data_collection.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_workflow.png b/translations/ja/algorithm-design/cost_function/images/cost_function_workflow.png
new file mode 100644
index 00000000..40ccc85e
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_workflow.png differ
diff --git a/translations/ja/algorithm-design/cost_function/images/cost_function_zne_stages.png b/translations/ja/algorithm-design/cost_function/images/cost_function_zne_stages.png
new file mode 100644
index 00000000..9cb00eb2
Binary files /dev/null and b/translations/ja/algorithm-design/cost_function/images/cost_function_zne_stages.png differ
diff --git a/translations/ja/algorithm-design/instances/images/instances_QSR.png b/translations/ja/algorithm-design/instances/images/instances_QSR.png
new file mode 100644
index 00000000..f3af04c7
Binary files /dev/null and b/translations/ja/algorithm-design/instances/images/instances_QSR.png differ
diff --git a/translations/ja/algorithm-design/instances/images/instances_SSVQE.png b/translations/ja/algorithm-design/instances/images/instances_SSVQE.png
new file mode 100644
index 00000000..f9379deb
Binary files /dev/null and b/translations/ja/algorithm-design/instances/images/instances_SSVQE.png differ
diff --git a/translations/ja/algorithm-design/instances/images/instances_VQD.png b/translations/ja/algorithm-design/instances/images/instances_VQD.png
new file mode 100644
index 00000000..ed840988
Binary files /dev/null and b/translations/ja/algorithm-design/instances/images/instances_VQD.png differ
diff --git a/translations/ja/algorithm-design/instances/images/instances_VQE.png b/translations/ja/algorithm-design/instances/images/instances_VQE.png
new file mode 100644
index 00000000..af8bf7ee
Binary files /dev/null and b/translations/ja/algorithm-design/instances/images/instances_VQE.png differ
diff --git a/translations/ja/algorithm-design/instances/instances.ipynb b/translations/ja/algorithm-design/instances/instances.ipynb
new file mode 100644
index 00000000..acf5465c
--- /dev/null
+++ b/translations/ja/algorithm-design/instances/instances.ipynb
@@ -0,0 +1,455 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Instances and extensions"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This chapter will cover several quantum variational algorithms, including:\n",
+ "\n",
+ "* [Variational Quantum Eigensolver (VQE)](https://arxiv.org/abs/1304.3061)\n",
+ "* [Subspace Search VQE (SSVQE)](https://arxiv.org/abs/1810.09434)\n",
+ "* [Variational Quantum Deflation (VQD)](https://arxiv.org/abs/1805.08138)\n",
+ "* [Quantum Sampling Regression (QSR)](https://arxiv.org/pdf/2012.02338)\n",
+ "\n",
+ "By using these algorithms, we will learn about several design ideas that can be incorporated into custom variational algorithms, such as weights, penalties, oversampling, and undersampling. We encourage you to experiment with these concepts and share your findings with the community."
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Variational Quantum Eigensolver (VQE)\n",
+ "\n",
+ "[VQE](https://arxiv.org/abs/1304.3061) is one of the most widely used variational quantum algorithms, setting up a template for other algorithms to build upon. \n",
+ "\n",
+ "![VQE](images/instances_VQE.png)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "VQE's layout is simple:\n",
+ "\n",
+ "- Prepare reference operators $U_R$\n",
+ " - We start from the state $|0\\rangle$ and go to the reference state $|\\rho\\rangle$\n",
+ "- Apply the variational form $U_V(\\vec\\theta_{i,j})$ to create an ansatz $U_A(\\vec\\theta_{i,j})$\n",
+ " - We go from the state $|\\rho\\rangle$ to $U_V(\\vec\\theta_{i,j})|\\rho\\rangle = |\\psi(\\vec\\theta_{i,j})\\rangle$\n",
+ "- Bootstrap at $i=0$ if we have a similar problem (typically found via classical simulation or sampling)\n",
+ " - Each optimizer will be bootstrapped differently, resulting in an initial set of parameter vectors $\\Theta_0 := \\\\{ {\\vec\\theta_{0,j} | j \\in \\mathcal{J}_\\text{opt}^0} \\\\}$ (e.g., from an initial point $\\vec\\theta_0$).\n",
+ "- Evaluate the cost function $C(\\vec\\theta_{i,j}) := \\langle \\psi(\\vec{\\theta}) | \\hat{H} | \\psi(\\vec{\\theta})\\rangle$ for all prepared states on a quantum computer.\n",
+ "- Use a classical optimizer to select the next set of parameters $\\Theta_{i+1}$.\n",
+ "- Repeat the process until convergence is reached.\n",
+ "\n",
+ "This is a simple classical optimization loop where we evaluate the cost function. Some optimizers may require multiple evaluations to calculate a gradient, determine the next iteration, or assess convergence.\n",
+ "\n",
+ "Here's the example for the following observable:\n",
+ "\n",
+ "$$\n",
+ "\\hat{O}_1 = 2 II - 2 XX + 3 YY - 3 ZZ,\n",
+ "$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "tags": [
+ "uses-hardware"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "from qiskit import QuantumCircuit\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService, Estimator\n",
+ "import numpy as np\n",
+ "\n",
+ "# Add your token below\n",
+ "service = QiskitRuntimeService(\n",
+ " channel=\"ibm_quantum\",\n",
+ ")\n",
+ "\n",
+ "def cost_function_vqe(theta):\n",
+ " observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])\n",
+ " reference_circuit = QuantumCircuit(2)\n",
+ " reference_circuit.x(0)\n",
+ "\n",
+ " variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ " )\n",
+ " ansatz = reference_circuit.compose(variational_form)\n",
+ "\n",
+ " backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ " \n",
+ " # Use estimator to get the expected values corresponding to each ansatz\n",
+ " estimator = Estimator(session=backend)\n",
+ " job = estimator.run(ansatz, observable, theta)\n",
+ " values = job.result().values\n",
+ "\n",
+ " return values"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can use this cost function to calculate optimal parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "\n",
+ "initial_theta = np.ones(8)\n",
+ "optimizer = COBYLA()\n",
+ "\n",
+ "optimizer_result = optimizer.minimize(fun=cost_function_vqe, x0=initial_theta)\n",
+ "\n",
+ "optimal_parameters = optimizer_result.x\n",
+ "print(optimal_parameters)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, we can use our optimal parameters to calculate our minimum eigenvalues:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])\n",
+ "reference_circuit = QuantumCircuit(2)\n",
+ "reference_circuit.x(0)\n",
+ "\n",
+ "variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ ")\n",
+ "ansatz = reference_circuit.compose(variational_form)\n",
+ "solution = ansatz.bind_parameters(optimal_parameters)\n",
+ "\n",
+ "backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ "estimator = Estimator(session=backend)\n",
+ "job = estimator.run(solution, observable)\n",
+ "values = job.result().values\n",
+ "\n",
+ "experimental_min_eigenvalue = values[0]\n",
+ "print(experimental_min_eigenvalue)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Subspace Search VQE (SSVQE)\n",
+ "\n",
+ "[SSVQE](https://arxiv.org/abs/1810.09434) is a variant of VQE that allows obtaining the first $k$ eigenvalues of an observable $\\hat{H}$ with eigenvalues {$\\lambda_0, \\lambda_1,...,\\lambda_{N-1}$}, where $N\\geq k$. Without loss of generality, we assume that $\\lambda_0<\\lambda_1<...<\\lambda_{N-1}$. SSQVE introduces a new idea by adding weights to help prioritize optimizing for the term with the largest weight.\n",
+ "\n",
+ "![SSVQE](images/instances_SSVQE.png)\n",
+ "\n",
+ "To implement this algorithm, we need $k$ mutually orthogonal reference states `{latex} \\{ |\\rho_j\\rangle \\}_{j=0}^{k-1}`, meaning $\\langle \\rho_j | \\rho_l \\rangle = \\delta_{jl}$ for $j,lw_l$, and $U_V(\\vec{\\theta})$ is the user-defined variational form.\n",
+ "\n",
+ "The SSVQE algorithm relies on the fact that eigenstates corresponding to different eigenvalues are mutually orthogonal. Specifically, the inner product of $U_V(\\vec{\\theta})|\\rho_j\\rangle$ and $U_V(\\vec{\\theta})|\\rho_l\\rangle$ can be expressed as:\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle \\rho_j | U_{V}^{\\dagger}(\\vec{\\theta})U_{V}(\\vec{\\theta})|\\rho_l \\rangle\n",
+ "\n",
+ "& = \\langle \\rho_j | I |\\rho_l \\rangle \\\\[1mm]\n",
+ "\n",
+ "& = \\langle \\rho_j | \\rho_l \\rangle \\\\[1mm]\n",
+ "\n",
+ "& = \\delta_{jl}\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "The first equality holds because $U_{V}(\\vec{\\theta})$ is a quantum operator and is therefore unitary. The last equality holds because of the orthogonality of the reference states $|\\rho_j\\rangle$. The fact that orthogonality is preserved through unitary transformations is deeply related to the principle of conservation of information, as expressed in quantum information science. Under this view, non-unitary transformations represent processes where information is either lost or injected.\n",
+ "\n",
+ "Weights $w_j$ help ensure that all the states are eigenstates. If the weights are sufficiently different, the term with the largest weight (i.e., $w_0$) will be given priority during optimization over the others. As a result, the resulting state $U_{V}(\\vec{\\theta})|\\rho_0 \\rangle$ will become the eigenstate corresponding to $\\lambda_0$. Because `{latex} \\{ U_{V}(\\vec{\\theta})|\\rho_j\\rangle \\}_{j=0}^{k-1}` are mutually orthogonal, the remaining states will be orthogonal to it and, therefore, contained in the subspace corresponding to the eigenvalues {$\\lambda_1,...,\\lambda_{N-1}$}.\n",
+ "\n",
+ "Applying the same argument to the rest of the terms, the next priority would then be the term with weight $w_1$, so $U_{V}(\\vec{\\theta})|\\rho_1 \\rangle$ would be the eigenstate corresponding to $\\lambda_1$, and the other terms would be contained in the eigenspace of {$\\lambda_2,...,\\lambda_{N-1}$}.\n",
+ "\n",
+ "By reasoning inductively, we deduce that $U_{V}(\\vec{\\theta})|\\rho_j \\rangle$ will be an approximate eigenstate of $\\lambda_j$ for $0\\leq j < k$.\n",
+ "\n",
+ "SSVQE's can be summarized as follows:\n",
+ "\n",
+ "- Prepare several reference states by applying a unitary U_R to k different computational basis states\n",
+ " - This algorithm requires the usage of $k$ mutually orthogonal reference states `{latex} \\{ |\\rho_j\\rangle \\}_{j=0}^{k-1}`, such that $\\langle \\rho_j | \\rho_l \\rangle = \\delta_{jl}$ for $j,l \\lambda_0$, instead of minimizing the cost function $C_0(\\vec{\\theta}) := \\langle \\psi(\\vec{\\theta}) | \\hat{H} | \\psi(\\vec{\\theta})\\rangle$, we optimize:\n",
+ "\n",
+ "$$\n",
+ "C_1(\\vec{\\theta}) := \n",
+ "C_0(\\vec{\\theta})+ \\beta_0 |\\langle \\psi(\\vec{\\theta})| \\psi(\\vec{\\theta^0})\\rangle |^2 \n",
+ "$$\n",
+ "\n",
+ "The positive value $\\beta_0$ should ideally be greater than $\\lambda_1-\\lambda_0$. \n",
+ "\n",
+ "This introduces a new cost function that can be viewed as a constrained problem, where we minimize $C_\\text{VQE}(\\vec{\\theta}) = \\langle \\psi(\\vec{\\theta}) | \\hat{H} | \\psi(\\vec{\\theta})\\rangle$ subject to the constraint that the state must be orthogonal to the previously obtained $|\\psi(\\vec{\\theta^0})\\rangle$, with $\\beta_0$ acting as a penalty term if the constraint is not satisfied.\n",
+ "\n",
+ "Alternatively, this new problem can be interpreted as running VQE on the new observable:\n",
+ "\n",
+ "$$\n",
+ "\\hat{H_1} := \\hat{H} + \\beta_0 |\\psi(\\vec{\\theta^0})\\rangle \\langle \\psi(\\vec{\\theta^0})|\n",
+ "\\quad \\Rightarrow \\quad \n",
+ "C_1(\\vec{\\theta}) = \\langle \\psi(\\vec{\\theta}) | \\hat{H_1} | \\psi(\\vec{\\theta})\\rangle,\n",
+ "$$\n",
+ "\n",
+ "Assuming that the solution to the new problem is $|\\psi(\\vec{\\theta^1})\\rangle$, the expected value of $\\hat{H}$ (not $\\hat{H_1}$) should be $ \\langle \\psi(\\vec{\\theta^1}) | \\hat{H} | \\psi(\\vec{\\theta^1})\\rangle = \\lambda_1$."
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To obtain the third eigenvalue $\\lambda_2$, the cost function to optimize is:\n",
+ "\n",
+ "$$\n",
+ "C_2(\\vec{\\theta}) := \n",
+ "C_1(\\vec{\\theta}) + \\beta_1 |\\langle \\psi(\\vec{\\theta})| \\psi(\\vec{\\theta^1})\\rangle |^2 \n",
+ "$$\n",
+ "\n",
+ "where $\\beta_1$ is a positive constant large enough to enforce orthogonality of the solution state to both $|\\psi(\\vec{\\theta^0})\\rangle$ and $|\\psi(\\vec{\\theta^1})\\rangle$. This penalizes states in the search space that do not meet this requirement, effectively restricting the search space. Thus, the optimal solution of the new problem should be the eigenstate corresponding to $\\lambda_2$.\n",
+ "\n",
+ "Like the previous case, this new problem can also be interpreted as VQE with the observable:\n",
+ "\n",
+ "$$\n",
+ "\\hat{H_2} := \\hat{H_1} + \\beta_1 |\\psi(\\vec{\\theta^1})\\rangle \\langle \\psi(\\vec{\\theta^1})|\n",
+ "\\quad \\Rightarrow \\quad \n",
+ "C_2(\\vec{\\theta}) = \\langle \\psi(\\vec{\\theta}) | \\hat{H_2} | \\psi(\\vec{\\theta})\\rangle.\n",
+ "$$\n",
+ "\n",
+ "If the solution to this new problem is $|\\psi(\\vec{\\theta^2})\\rangle$, the expected value of $\\hat{H}$ (not $\\hat{H_2}$) should be $ \\langle \\psi(\\vec{\\theta^2}) | \\hat{H} | \\psi(\\vec{\\theta^2})\\rangle = \\lambda_2$."
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Analogously, to obtain the $k$-th eigenvalue $\\lambda_{k-1}$, you would minimize the cost function:\n",
+ "\n",
+ "$$\n",
+ "C_{k-1}(\\vec{\\theta}) := \n",
+ "C_{k-2}(\\vec{\\theta}) + \\beta_{k-2} |\\langle \\psi(\\vec{\\theta})| \\psi(\\vec{\\theta^{k-2}})\\rangle |^2,\n",
+ "$$\n",
+ "\n",
+ "Remember that we defined $\\vec{\\theta^j}$ such that $\\langle \\psi(\\vec{\\theta^j}) | \\hat{H} | \\psi(\\vec{\\theta^j})\\rangle = \\lambda_j, \\forall jRead more.",
+ "title": "最小値"
+ }
+ }
+ },
+ "source": [
+ "## 勾配ありと勾配なしのオプティマイザー\n",
+ "\n",
+ "### 勾配あり\n",
+ "\n",
+ "コスト関数 $C(\\vec\\theta)$ において、初期点から関数 $\\vec{\\nabla} C(\\vec\\theta)$ の勾配にアクセスできる場合、関数を最小化する最も簡単な方法は、パラメータを関数の最急降下の方向に更新することです。 つまり、パラメータを $\\vec\\theta_{n+1} = \\vec\\theta_n - \\eta \\vec{\\nabla} C(\\vec\\theta)$ として更新します。ここで、 $\\eta$ は学習率 (更新のサイズを制御する小さな正の[ハイパーパラメータ](gloss:hyperparameter) ) です。 これをコスト関数の極小値 $C({\\vec\\theta^*})$ に収束するまで続けます。[`qiskit.algorithms`](https://qiskit.org/documentation/stubs/qiskit.algorithms.gradients.html) は、勾配を計算するためのいくつかの異なる方法を提供します。詳細については、[こちら](https://learn.qiskit.org/course/machine-learning/training-quantum-circuits#training-2-0)をご覧ください。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "from qiskit.quantum_info import SparsePauliOp\n",
+ "from qiskit import QuantumCircuit\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService, Estimator\n",
+ "import numpy as np\n",
+ "\n",
+ "# Add your token below\n",
+ "service = QiskitRuntimeService(\n",
+ " channel=\"ibm_quantum\",\n",
+ ")\n",
+ "\n",
+ "def cost_function_vqe(theta):\n",
+ " observable = SparsePauliOp.from_list([(\"II\", 2), (\"XX\", -2), (\"YY\", 3), (\"ZZ\", -3)])\n",
+ " reference_circuit = QuantumCircuit(2)\n",
+ " reference_circuit.x(0)\n",
+ "\n",
+ " variational_form = TwoLocal(\n",
+ " 2,\n",
+ " rotation_blocks=[\"rz\", \"ry\"],\n",
+ " entanglement_blocks=\"cx\",\n",
+ " entanglement=\"linear\",\n",
+ " reps=1,\n",
+ " )\n",
+ " ansatz = reference_circuit.compose(variational_form)\n",
+ "\n",
+ " backend = service.backend(\"ibmq_qasm_simulator\")\n",
+ " \n",
+ " # Use estimator to get the expected values corresponding to each ansatz\n",
+ " estimator = Estimator(session=backend)\n",
+ " job = estimator.run(ansatz, observable, theta)\n",
+ " values = job.result().values\n",
+ "\n",
+ " return values"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "このコスト関数とオプティマイザーを使って、最適なパラメーターを算出することができます"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit.algorithms.optimizers import SPSA\n",
+ "\n",
+ "initial_theta = np.ones(8)\n",
+ "optimizer = SPSA()\n",
+ "\n",
+ "optimizer_result = optimizer.minimize(fun=cost_function_vqe, x0=initial_theta)\n",
+ "\n",
+ "optimal_parameters = optimizer_result.x\n",
+ "print(optimal_parameters)"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "このタイプの最適化の主な欠点は、収束速度が非常に遅くなることと、最適解を達成する保証がないことです。\n",
+ "\n",
+ "![theta に対する f(theta) のグラフ。複数の点は、曲線の最小値を見つける勾配降下法アルゴリズムのさまざまな状態を示します。](images/optimization_gradient_descent.png)\n",
+ "\n",
+ "### 勾配なし\n",
+ "\n",
+ "勾配を必要としない最適化アルゴリズムは、勾配情報を必要としないため、勾配の計算が困難であったり、コストがかかったり、ノイズが多すぎたりする場合に有効です。また、勾配を利用した手法が局所最適値に収束する傾向があるのに対して、大域最適値を見つける上でより頑健である傾向があります。ここでは、勾配なしオプティマイザーが不毛な台地を回避するのに役立ついくつかの例を紹介します。しかし、勾配なし手法は、特に高次元の探索空間を持つ問題に対してより高い計算リソースを必要とします。\n",
+ "\n",
+ "ここでは、代わりに [`COBYLA`](https://qiskit.org/documentation/stubs/qiskit.algorithms.optimizers.COBYLA.html#qiskit.algorithms.optimizers.COBYLA) オプティマイザーを使用する例を紹介します:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit.algorithms.optimizers import COBYLA\n",
+ "\n",
+ "initial_theta = np.ones(8)\n",
+ "optimizer = COBYLA()\n",
+ "\n",
+ "optimizer_result = optimizer.minimize(fun=cost_function_vqe, x0=initial_theta)\n",
+ "\n",
+ "optimal_parameters = optimizer_result.x\n",
+ "print(optimal_parameters)"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "barren-plateaus": {
+ "text": "パラメータ化された量子回路の勾配が量子ビット数に対して指数関数的に小さくなると、最適化が難しくなり、最適化計算が不能になる可能性があります。",
+ "title": "不毛な台地"
+ }
+ }
+ },
+ "source": [
+ "## 不毛な台地\n",
+ "\n",
+ "実際、コストの起伏は、下の例のように丘と谷のように非常に複雑になることがあります。最適化手法は、黒い点と線で示されるように、コストの起伏をナビゲートし、最小値を探します。3つの探索のうち2つは、グローバルな最小値ではなく、ローカルな最小値で終わっていることがわかります。\n",
+ "\n",
+ "![コストの起伏](images/optimization_loss_landscape.png)\n",
+ "\n",
+ "最適化手法の種類にかかわらず、コストの起伏が比較的平坦である場合、その手法が適切な探索方向を決定することは困難な場合があります。このようなシナリオは[不毛な台地](gloss:barren-plateaus)と呼ばれ、コストの起伏が徐々に平坦にります(したがって、最小値への方向性を決定するのがより困難になります)。パラメータ化された幅広い量子回路において、合理的な方向に沿った勾配が一定の精度でゼロでない確率は、量子ビットの数が増えるにつれて指数関数的に減少することが分かっています。\n",
+ "\n",
+ "![Barren Plateaus](images/optimization_barren_plateaus.png)\n",
+ "\n",
+ "この分野はまだ活発な研究が行われていますが、最適化性能を向上させるためのいくつかの推奨事項があります:\n",
+ "\n",
+ "- **ブートストラップ** は、最適化ループが勾配が小さいパラメータ空間で立ち往生するのを避けるのに役立ちます。\n",
+ "- **ハードウェア効率の良いansatzの実験**: ブラックボックスオラクルとしてノイズの多い量子系を使用しているため、その評価の質はオプティマイザーの性能に影響を与えることがあります。[`EfficientSU2`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.EfficientSU2.html) のようなハードウェア効率の良いansatzを使用することで、指数関数的に小さな勾配が発生することを回避できる可能性があります。\n",
+ "- **エラー抑制とエラー緩和の実験**: Qiskit Runtime Primitiveは、様々な `optimization_level`と `resilience_setting` をそれぞれ実験するためのシンプルなインターフェースを提供します。これにより、ノイズの影響を軽減し、最適化プロセスをより効率的に行うことができます。\n",
+ "- **勾配なしオプティマイザーを使った実験**: `COBYLA`のようなオプティマイザーは、勾配ベースの最適化アルゴリズムとは異なり、勾配情報に頼らずにパラメータを最適化するため、不毛な台地の影響を受けにくいです。"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "このレッスンで、あなたは最適化ループを定義する方法を学びました:\n",
+ "\n",
+ "- 最適化ループをブートストラップする。\n",
+ "- ローカルオプティマイザーとグローバルオプティマイザーを使い分けながら、トレードオフを理解する。\n",
+ "- 不毛の台地とそれを避ける方法を探る\n",
+ "\n",
+ "ハイレベルの変分ワークロードは完了です:\n",
+ "\n",
+ "![最適化回路](images/optimization_circuit.png)\n",
+ "\n",
+ "次に、このフレームワークを意識して、具体的な変分アルゴリズムを探っていきます。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/reference/images/reference_circuit.png b/translations/ja/algorithm-design/reference/images/reference_circuit.png
new file mode 100644
index 00000000..e11ef33a
Binary files /dev/null and b/translations/ja/algorithm-design/reference/images/reference_circuit.png differ
diff --git a/translations/ja/algorithm-design/reference/images/reference_workflow.png b/translations/ja/algorithm-design/reference/images/reference_workflow.png
new file mode 100644
index 00000000..ce32b9e0
Binary files /dev/null and b/translations/ja/algorithm-design/reference/images/reference_workflow.png differ
diff --git a/translations/ja/algorithm-design/reference/reference.ipynb b/translations/ja/algorithm-design/reference/reference.ipynb
new file mode 100644
index 00000000..59383800
--- /dev/null
+++ b/translations/ja/algorithm-design/reference/reference.ipynb
@@ -0,0 +1,301 @@
+{
+ "cells": [
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "reference": {
+ "text": "問題の初期状態、決まった開始状態。通常 $|0\\rangle$ を指しますが、問題を適切に表現する様々な状態に設定することができます。",
+ "title": "参照状態"
+ }
+ }
+ },
+ "source": [
+ "## 参照状態\n",
+ "\n",
+ "このレッスンでは、変分アルゴリズムをより速く収束させるために、参照状態で系を初期化する方法について学びます。まず、 [*参照状態*](gloss:reference) を手動で構築する方法を学び、次に変分アルゴリズムで使用可能ないくつかの標準的な選択肢を探ります。\n",
+ "\n",
+ "![Reference Workflow](images/reference_workflow.png)"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## デフォルト状態\n",
+ "\n",
+ "*参照状態* とは、問題に対する最初の固定開始状態を意味します。参照状態を準備するために、量子回路の開始時に適切なパラメータ化されていないユニタリー回路 $U_R$ を適用し、 $|\\rho\\rangle = U_R |0\\rangle$ となるようにする必要があります。既存の最適解からの推測やデータ点がある場合、それを出発点として使用すると変分アルゴリズムが早く収束する可能性があります。\n",
+ "\n",
+ "最も単純な参照状態はデフォルト状態であり、 $n$ 量子ビット回路の開始状態 $|0\\rangle^{\\otimes n}$ を使用します。 デフォルト状態の場合、ユニタリー演算子 $U_R \\equiv I$ が使われます。その単純さゆえに、デフォルト状態は多くのシナリオで使用される有効な参照状態です。"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## 古典的な参照状態\n",
+ "\n",
+ "$3$ 量子ビット系で、デフォルトの状態 $|000\\rangle$ の代わりに状態 $|001\\rangle$ で始めたいとします。これは純粋に古典的な参照状態の例で、これを構築するには、(Qiskitの量子ビット順序に従って)量子ビット $0$ に [X ゲート](https://qiskit.org/documentation/stubs/qiskit.circuit.library.XGate.html) を適用するだけで、 $|001\\rangle = X_0 |000\\rangle$ となります。\n",
+ "\n",
+ "この場合、ユニタリー演算子は $U_R \\equiv X_0$ となり、参照状態 $|\\rho\\rangle \\equiv |001\\rangle$ を作ります。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit import QuantumCircuit\n",
+ "\n",
+ "qc = QuantumCircuit(3)\n",
+ "qc.x(0)\n",
+ "\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## 量子的な参照状態\n",
+ "\n",
+ "例えば、 $\\frac{1}{\\sqrt{2}}(|100\\rangle+|111\\rangle)$ のような重ね合わせやエンタングルメントを含むより複雑な状態から始めたいとします。\n",
+ "\n",
+ "この状態を $|000\\rangle$ から得る方法の一つに、量子ビット $0$ に対して [アダマールゲート](https://qiskit.org/documentation/stubs/qiskit.circuit.library.HGate.html)( $H_0$ )、量子ビット $0$ を制御量子ビット、量子ビット $1$ をターゲット量子ビットとする [CNOT(CX)](https://qiskit.org/documentation/stubs/qiskit.circuit.library.CXGate.html)ゲート( $CNOT_{01}$ )、最後に量子ビット $2$ に対する $X$ ゲート( $X_2$ )を適用する方法があります。\n",
+ "\n",
+ "このとき、ユニタリー演算子は $U_{R} \\equiv X_2CNOT_{01}H_0|000\\rangle$ 、参照状態は $|\\rho\\rangle \\equiv \\frac{1}{\\sqrt{2}}(|100\\rangle+|111\\rangle)$ です。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "qc = QuantumCircuit(3)\n",
+ "qc.h(0)\n",
+ "qc.cx(0, 1)\n",
+ "qc.x(2)\n",
+ "\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## テンプレート回路を用いた参照状態の構築\n",
+ "\n",
+ "また、複数の調整可能なパラメータやエンタングルメントを簡単に表現できる [`TwoLocal`](https://qiskit.org/documentation/stubs/qiskit.circuit.library.TwoLocal.html) など、様々なテンプレート回路を利用することができます。これらのテンプレート回路については、次回のレッスンで詳しく説明しますが、パラメータをバインドした *場合* 、参照状態に利用することができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit.circuit.library import TwoLocal\n",
+ "from math import pi\n",
+ "\n",
+ "reference_circuit = TwoLocal(2, \"rx\", \"cz\", entanglement=\"linear\", reps=1)\n",
+ "theta_list = [pi / 2, pi / 3, pi / 3, pi / 2]\n",
+ "\n",
+ "reference_circuit = reference_circuit.bind_parameters(theta_list)\n",
+ "\n",
+ "reference_circuit.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "## アプリケーション固有の参照状態"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "### 量子化学\n",
+ "\n",
+ "量子化学では、 *Hartree-Fock* 状態は原子や分子の基底状態の近似値です。正確な基底状態を求める変分アルゴリズムを作成することが目的であれば、この既知の古典的近似を参照状態として使用することで、アルゴリズムの収束を早くすることができます。\n",
+ "\n",
+ "この例では、2つの空間軌道と2つの電子(1つのアルファ・スピン、1つのベータ・スピン)を持つ問題に対して、次のように電子構造の問題を生成することができます。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit_nature.second_q.circuit.library import HartreeFock\n",
+ "from qiskit_nature.second_q.mappers import JordanWignerMapper\n",
+ "\n",
+ "num_spatial_orbitals = 2\n",
+ "num_particles = (1, 1)\n",
+ "\n",
+ "mapper = JordanWignerMapper()\n",
+ "\n",
+ "h2_reference_state = HartreeFock(\n",
+ " num_spatial_orbitals=num_spatial_orbitals,\n",
+ " num_particles=num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ ")\n",
+ "\n",
+ "h2_reference_state.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "また、水素化リチウム(LiH)のような特定の分子を構成することも可能です。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit_nature.second_q.drivers import PySCFDriver\n",
+ "from qiskit_nature.second_q.circuit.library import HartreeFock\n",
+ "from qiskit_nature.second_q.mappers import JordanWignerMapper\n",
+ "from qiskit_nature.second_q.formats.molecule_info import MoleculeInfo\n",
+ "\n",
+ "molecule = MoleculeInfo(\n",
+ " # Coordinates in Angstrom\n",
+ " symbols=[\"Li\", \"H\"],\n",
+ " coords=([0.0, 0.0, 0.0], [0.2, 0.0, 0.0]),\n",
+ " multiplicity=1, # = 2*spin + 1\n",
+ " charge=0,\n",
+ ")\n",
+ "\n",
+ "driver = PySCFDriver.from_molecule(molecule)\n",
+ "LiH_problem = driver.run()\n",
+ "\n",
+ "mapper = JordanWignerMapper()\n",
+ "LiH_reference_state = HartreeFock(\n",
+ " num_spatial_orbitals=LiH_problem.num_spatial_orbitals,\n",
+ " num_particles=LiH_problem.num_particles,\n",
+ " qubit_mapper=mapper,\n",
+ ")\n",
+ "\n",
+ "LiH_reference_state.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "### 量子機械学習\n",
+ "\n",
+ "[変分量子分類器(VQC)](https://learn.qiskit.org/course/machine-learning/variational-classification) の文脈では、訓練データは、 *特徴量マップ* として知られるパラメータ化された回路で量子状態に符号化され、各パラメータの値は訓練データセットのデータ点を表します。 [ZZFeatureMap](https://qiskit.org/documentation/stubs/qiskit.circuit.library.ZZFeatureMap.html) は、この特徴量マップにデータ点($x$) を渡すパラメータ化回路の一種です。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ },
+ "outputs": [
+
+ ],
+ "source": [
+ "from qiskit.circuit.library import ZZFeatureMap\n",
+ "\n",
+ "data = [0.1, 0.2]\n",
+ "\n",
+ "zz_feature_map_reference = ZZFeatureMap(feature_dimension=2, reps=2)\n",
+ "zz_feature_map_reference = zz_feature_map_reference.bind_parameters(data)\n",
+ "zz_feature_map_reference.decompose().draw(\"mpl\")"
+ ]
+ },
+ {
+ "attachments": {
+ },
+ "cell_type": "markdown",
+ "metadata": {
+ },
+ "source": [
+ "このレッスンで、あなたは、以下を使ってシステムを初期化する方法を学びました:\n",
+ "\n",
+ "- デフォルトの参照状態\n",
+ "- 古典的な参照状態\n",
+ "- 量子的な参照状態\n",
+ "- アプリケーション固有の参照状態\n",
+ "\n",
+ "このハイレベルな変分ワークロードは次のようになります。\n",
+ "\n",
+ "![Reference Circuit](images/reference_circuit.png)\n",
+ "\n",
+ "参照状態は固定された最初の出発点であるのに対し、 *変分形式* を使って、変分アルゴリズムが探索するためのパラメータ化された状態の集合を表す *ansatz* を定義することができます。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/algorithm-design/variational/images/variational_workflow.png b/translations/ja/algorithm-design/variational/images/variational_workflow.png
new file mode 100644
index 00000000..96c92448
Binary files /dev/null and b/translations/ja/algorithm-design/variational/images/variational_workflow.png differ
diff --git a/translations/ja/algorithm-design/variational/variational.ipynb b/translations/ja/algorithm-design/variational/variational.ipynb
new file mode 100644
index 00000000..d0601a92
--- /dev/null
+++ b/translations/ja/algorithm-design/variational/variational.ipynb
@@ -0,0 +1,228 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 変分アルゴリズム"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "advantage": {
+ "text": "特定の計算問題を古典コンピューターよりも高速に解決する量子コンピューターの能力の実用的なデモンストレーション。",
+ "title": "量子優位性"
+ },
+ "converge": {
+ "text": "アルゴリズムをさらに繰り返したり修正したりしても、ソリューションが大幅に改善または変更されない、安定した最適解に到達すること。",
+ "title": "収束"
+ }
+ }
+ },
+ "source": [
+ "このコースでは、変分アルゴリズムの詳細と、量子力学の変分定理に基づく近い将来のハイブリッド量子-古典アルゴリズムについて説明します。これらのアルゴリズムは、今日のフォールトトレラントでない量子コンピューターによって提供されるユーティリティを活用できるため、[量子優位性](gloss:advantage)を達成するための理想的な候補になります。\n",
+ "\n",
+ "このコースでは次のことを学びます。\n",
+ "\n",
+ "- 変分アルゴリズム設計ワークフローの各ステップ\n",
+ "- 各ステップに関連するトレードオフ\n",
+ "- [Qiskit Runtimeプリミティブ](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/primitives.html)を使用して速度と精度を最適化する方法\n",
+ "\n",
+ "このコースは、研究者や開発者が量子コンピューターの有用性を探求するための出発点となることを意図していますが、量子コンピューティング全般の理論的・基礎的な知識は[量子情報と計算の基礎](https://qiskit.org/learn/course/basics-quantum-information/)( [YouTubeシリーズ](https://www.youtube.com/playlist?list=PLOFEBzvs-VvqKKMXX4vbi4EB1uaErFMSO)としても視聴可能)を自由に探検してみてください。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 簡素化されたハイブリッドワークフロー\n",
+ "\n",
+ "![Variational Flow](images/variational_workflow.png)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "cost_function": {
+ "text": "モデルまたはアルゴリズムの予測出力と実際の出力との差を測定するために使用される数学関数で、最適化によってこの差を最小限に抑えることを目的としています。",
+ "title": "コスト関数"
+ }
+ }
+ },
+ "source": [
+ "変分アルゴリズムには、アルゴリズム、ソフトウェア、およびハードウェアの進歩に基づいて組み合わせて最適化できるいくつかのモジュラーコンポーネントが含まれています。これには、一連のパラメーターを使用して特定の問題を記述する*コスト関数*、これらのパラメーターを使用して探索空間を表現するための*ansatz* 、および探索空間を繰り返し探索するための*オプティマイザー*が含まれます。各反復中に、オプティマイザーは現在のパラメーターを使用してコスト関数を評価し、最適解に[収束](gloss:converge)するまで次の反復のパラメーターを選択します。この種のアルゴリズムがハイブリッドな点は、コスト関数が量子リソースを使用して評価され、古典リソースによって最適化されることに由来します。\n",
+ "\n",
+ "1. **問題の初期化**: 変分アルゴリズムは、量子コンピューターを*初期状態* $|0\\rangle$ に初期化することから始まり、次にそれを望みの (パラメーター化されていない) 状態 $|\\rho\\rangle$ に変換します。これを*参照状態 *と呼びます。\n",
+ "\n",
+ " この変換は、 $U_R|0\\rangle = |\\rho\\rangle$ のように、既定の状態にユニタリ参照演算子 $U_R$ を適用することで表現されます。\n",
+ "\n",
+ "2. **ansatzの準備**: 初期状態 $|0\\rangle$ からターゲット状態 $|\\psi(\\vec\\theta)\\rangle$ への反復最適化を開始するには、*変分形式* $U_V(\\vec\\theta)$ を定義する必要があります。変分アルゴリズムが探索するパラメータ化された状態のコレクションを表します。\n",
+ "\n",
+ " 参照状態と変分形式の特定の組み合わせをansatzと呼びます。例えば $U_A(\\vec\\theta) := U_V(\\vec\\theta) U_R$ です。
ansatzは最終的に、初期状態 $|0\\rangle$ をターゲット状態 $|\\psi(\\vec\\theta)\\rangle$ に変換できるパラメータ化された量子回路の形を取ります。\n",
+ "\n",
+ " 全体として次のようになります。\n",
+ "\n",
+ " $$\n",
+ " \\begin{aligned}\n",
+ " |0\\rangle \\xrightarrow{U_R} U_R|0\\rangle\n",
+ "\n",
+ " & = |\\rho\\rangle \\xrightarrow{U_V(\\vec{\\theta})} U_A(\\vec{\\theta})|0\\rangle \\\\[1mm]\n",
+ "\n",
+ " & = U_V(\\vec{\\theta})U_R|0\\rangle \\\\[1mm]\n",
+ "\n",
+ " & = U_V(\\vec{\\theta})|\\rho\\rangle \\\\[1mm]\n",
+ "\n",
+ " & = |\\psi(\\vec{\\theta})\\rangle \\\\[1mm]\n",
+ "\n",
+ " \\end{aligned}\n",
+ " $$\n",
+ "\n",
+ "3. **コスト関数の評価**: 問題を*コスト関数* $C(\\vec\\theta)$ にエンコードし、量子系で実行するパウリ演算子の線形結合として使用できます。これは、エネルギーやスピンなどの物理系に関する情報である可能性がありますが、物理でない問題も同じようにエンコードすることができます。 Qiskit Runtimeプリミティブを活用して、コスト関数を評価しながらエラーの抑制と軽減でノイズに対処できます。\n",
+ "\n",
+ "4. **パラメーターの最適化**: 評価結果は古典コンピューターに送られ、そこで古典オプティマイザーが分析し、変分パラメーターの次の値のセットを選択します。既存の最適解がある場合、それを*初期点* $\\vec\\theta_0$ として設定して、最適化を*ブートストラップ*できます。この*初期状態* $|\\psi(\\vec\\theta_0)\\rangle$ を使用すると、オプティマイザーが有効な解をより速く見つけるのに役立ちます。\n",
+ "\n",
+ "5. **結果に基づいた ansatz パラメーターの調整と再実行**: 古典オプティマイザーの終端基準が満たされるまでプロセス全体が繰り返され、パラメーター値の最適なセット $\\vec\\theta^ {em1}$ が返されます。そして、この問題の解の状態は、 $|\\psi(\\vec\\theta^ )\\rangle = U_A(\\vec\\theta^*)|0\\rangle$ と提案されます。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 変分定理\n",
+ "\n",
+ "変分アルゴリズムの一般的な目標は、特定の観測可能量の最小または最大の固有値を持つ量子状態を見つけることです。ここで使用する重要な洞察は、量子力学の*変分定理*です。詳細に入る前に、その背後にある数学的直感をいくつか調べてみましょう."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "decomposition": {
+ "text": "行列を固有値と固有ベクトルの和として表現するプロセス。これにより、その特性と振舞いの分析と操作が可能になります。",
+ "title": "スペクトル分解"
+ },
+ "eigenstate": {
+ "text": "エネルギーや運動量などの大きさが一定の値を持つ物理系の状態。",
+ "title": "固有状態"
+ }
+ }
+ },
+ "source": [
+ "### エネルギーと基底状態の数学的直感\n",
+ "\n",
+ "量子力学では、エネルギーは通常*ハミルトニアン*と呼ばれる観測可能量の形で表され、これを $\\hat{\\mathcal{H}}$ で表します。[スペクトル分解](gloss:decomposition)を考えてみましょう :\n",
+ "\n",
+ "$$\n",
+ "\\hat{\\mathcal{H}} = \\sum_{k=0}^{N-1} \\lambda_k |\\phi_k\\rangle \\langle \\phi_k|\n",
+ "$$\n",
+ "\n",
+ "ここで、 $N$ は状態空間の次元、 $\\lambda_{k}$ は $k$ 番目の固有値、または物理的には $k$ 番目のエネルギー準位、 $|\\phi_k\\rangle$ は $\\hat{\\mathcal{H}}|\\phi_k\\rangle = \\lambda_k |\\phi_k\\rangle$ に対応する[固有状態](gloss:eigenstate): (正規化された) 状態 $|\\psi\\rangle$ の系の期待エネルギーは以下のようになります。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle \\psi | \\hat{\\mathcal{H}} | \\psi \\rangle\n",
+ "\n",
+ "& = \\langle \\psi |\\bigg(\\sum_{k=0}^{N-1} \\lambda_k |\\phi_k\\rangle \\langle \\phi_k|\\bigg) | \\psi \\rangle \\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{k=0}^{N-1} \\lambda_k \\langle \\psi |\\phi_k\\rangle \\langle \\phi_k| \\psi \\rangle \\\\[1mm]\n",
+ "\n",
+ "& = \\sum_{k=0}^{N-1} \\lambda_k |\\langle \\psi |\\phi_k\\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "$\\lambda_0\\leq \\lambda_k, \\forall k$ を考慮すると、次のようになります。\n",
+ "\n",
+ "$$\n",
+ "\\begin{aligned}\n",
+ "\\langle \\psi | \\hat{\\mathcal{H}} | \\psi \\rangle\n",
+ "\n",
+ "& = \\sum_{k=0}^{N-1} \\lambda_k |\\langle \\psi |\\phi_k\\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "& \\geq \\sum_{k=0}^{N-1} \\lambda_0 |\\langle \\psi |\\phi_k\\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "& = \\lambda_0 \\sum_{k=0}^{N-1} |\\langle \\psi |\\phi_k\\rangle|^2 \\\\[1mm]\n",
+ "\n",
+ "& = \\lambda_0 \\\\[1mm]\n",
+ "\n",
+ "\\end{aligned}\n",
+ "$$\n",
+ "\n",
+ "`{latex} \\{ |\\phi_k\\rangle \\}_{k=0}^{N-1}` は正規直交基底であるため、 $|\\phi_{k} \\rangle$ を測定する確率は $p_k = |\\langle \\psi |\\phi_{k} \\rangle |^2$ であり、すべての確率の合計は $\\sum_{k=0}^{N-1} |\\langle \\psi |\\phi_k\\rangle|^2 = \\sum_{k=0}^{N-1}p_k = 1$ となります。要するに、系の期待されるエネルギーは、最小エネルギーまたは基底状態エネルギーよりも高くなります。\n",
+ "\n",
+ "$$\n",
+ "\\langle \\psi | \\hat{\\mathcal{H}} | \\psi \\rangle \\geq \\lambda_0.\n",
+ "$$\n",
+ "\n",
+ "上記の引数は、有効な (正規化された) 量子状態 $|\\psi\\rangle$ に適用されるため、パラメーターベクトル $\\vec\\theta$ に依存するパラメーター化された状態 $|\\psi(\\vec\\theta)\\rangle$ を考慮することは完全に可能です。ここで「変分」の出番です。 $C(\\vec\\theta) := \\langle \\psi(\\vec\\theta)|\\hat{\\mathcal{H}}|\\psi(\\vec\\theta)\\rangle$ で与えられるコスト関数を考えるとそれを最小化したい場合、最小値は常に次を満たします。\n",
+ "\n",
+ "$$\n",
+ "\\min_{\\vec\\theta} C(\\vec\\theta) = \n",
+ "\\min_{\\vec\\theta} \\langle \\psi(\\vec\\theta)|\\hat{\\mathcal{H}}|\\psi(\\vec\\theta)\\rangle \\geq \\lambda_0.\n",
+ "$$\n",
+ "\n",
+ "$C(\\vec\\theta)$ の最小値は、パラメータ化された状態 $|\\psi(\\vec\\theta)\\rangle$ を使用して $\\lambda_0$ に到達できる最も近い値になり、 $|\\psi(\\vec\\theta^{em0})\\rangle = |\\phi_0\\rangle$ となるパラメータベクトル $\\vec\\theta^{/em0}$ が存在する場合にのみ等号が成り立ちます。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "gloss": {
+ "expectation": {
+ "text": "状態の結果の確率によって重み付けされた、特定の状態における量子系の測定値の平均値。",
+ "title": "期待値"
+ }
+ }
+ },
+ "source": [
+ "### 量子力学の変分定理\n",
+ "\n",
+ "量子系の (正規化された) 状態 $|\\psi\\rangle$ がパラメータベクトル $\\vec\\theta$ に依存する場合、基底状態の最適近似 (つまり、最小固有値 $\\lambda_0$ をとる固有状態 $|\\phi_0\\rangle$) は、ハミルトニアン $\\hat{\\mathcal{H}}$ の[期待値](gloss:expectation)を最小化するものです:\n",
+ "\n",
+ "$$\n",
+ "\\langle \\hat{\\mathcal{H}} \\rangle(\\vec\\theta) := \n",
+ "\\langle \\psi(\\vec\\theta) |\\hat{\\mathcal{H}}| \\psi(\\vec\\theta) \\rangle \\geq \n",
+ "\\lambda_0\n",
+ "$$\n",
+ "\n",
+ "変分定理がエネルギー最小値の観点から述べられている理由は、多くの数学的仮定が含まれているためです。\n",
+ "\n",
+ "- 物理的な理由から、 $N\\rightarrow\\infty$ であっても、エネルギー $E \\geq \\lambda_0 > -\\infty$ を満たす有限の下限が存在する必要があります。\n",
+ "- 通常上限は存在しません。\n",
+ "\n",
+ "ただし、数学的に言えば、ハミルトニアン $\\hat{\\mathcal{H}}$ についてこれらの仮定を超える特別なことは何もないため、定理は他の観測可能量とその固有状態に一般化できますが、同じ制約に従う場合に限ります。また、有限の上限が存在する場合、下限を上限に交換することにより、固有値を最大化するために同じ数学的議論を行うことができることに注意してください。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "このレッスンでは、変分アルゴリズムの概要を学習しました。以降のレッスンでは、各ステップとそれに関連するトレードオフについて詳しく説明します。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/translations/ja/basics/multiple-systems.ipynb b/translations/ja/basics/multiple-systems.ipynb
index 4b8e8a09..f1acc553 100755
--- a/translations/ja/basics/multiple-systems.ipynb
+++ b/translations/ja/basics/multiple-systems.ipynb
@@ -1158,7 +1158,7 @@
"4 つのベルの状態のすべての集まり\n",
"\n",
"$$\n",
- " \\bigl\\{\\vert \\phi^+ \\rangle, \\vert \\phi^- \\rangle, \\vert \\psi^+ \\rangle, \\vert \\psi^+ \\rangle\\bigr\\}\n",
+ " \\bigl\\{\\vert \\phi^+ \\rangle, \\vert \\phi^- \\rangle, \\vert \\psi^+ \\rangle, \\vert \\psi^- \\rangle\\bigr\\}\n",
"$$\n",
"\n",
"は、 *ベル基底*として知られています。 2量子ビットの任意の量子状態ベクトル、または実際には 2 ビットの 4 つの古典的な状態に対応する要素を持つ任意の複素ベクトルは、4 つのベル状態の線形結合として表現できます。例えば、次のようになります。\n",
@@ -1704,7 +1704,7 @@
"\n",
"2つのシステムに注目すると、 $\\mathsf{X}$ が古典状態の集合 $\\Sigma$ を持つシステム、 $\\mathsf{Y}$ が古典状態集合 $\\Gamma$ を持つシステムであれば、合成システムの古典状態の集合 $(\\mathsf{X},\\mathsf{Y})$ は $\\Sigma\\times\\Gamma$ です。 したがって、この合成システムに対して実行可能な演算の集合は、行と列が集合 $\\Sigma\\times\\Gamma$ に対応するように配置されたユニタリー行列で表現されます。この行列の行と列の並びは、システム $(\\mathsf{X},\\mathsf{Y})$ の量子状態ベクトルに用いられる並びと同じです。\n",
"\n",
- "例えば、 $\\Sigma = \\{1,2,3\\}$ と $\\Gamma = \\{0,1\\}$ とすると、デカルト積 $\\{1,2,3\\}\\times\\{0,1\\}$ の要素の順番は、 $(1,0)$, $(1,1)$, $(2,0)$, $(2,1)$, $(3,0)$, $(3,1)$ が標準であす。
以下は、 $(\\mathsf{X},\\mathsf{Y})$ 上の演算を表すユニタリー行列の例です。\n",
+ "例えば、 $\\Sigma = \\{1,2,3\\}$ と $\\Gamma = \\{0,1\\}$ とすると、デカルト積 $\\{1,2,3\\}\\times\\{0,1\\}$ の要素の順番は、 $(1,0)$, $(1,1)$, $(2,0)$, $(2,1)$, $(3,0)$, $(3,1)$ が標準です。
以下は、 $(\\mathsf{X},\\mathsf{Y})$ 上の演算を表すユニタリー行列の例です。\n",
"\n",
"$$\n",
"U = \n",
@@ -1874,7 +1874,7 @@
"\n",
"授業を締めくくるために、複数システムでのユニタリー演算の例を 2 つ見てみましょう。*スワップ演算*から始めます。\n",
"\n",
- "$\\mathsf{X}$ と $\\mathsf{Y}$ が、同じ古典的な状態セット $\\Sigma$ を共有するシステムであるとします。ペア $(\\mathsf{X},\\mathsf{Y})$ の*スワップ*操作は、2 つのシステムの内容を交換する操作ですが、それ以外の場合はシステムをそのままにしておきます (したがって、$\\mathsf{X}$ は残ります)。左側に、$\\mathsf{Y}$ が右側に残ります)。\n",
+ "$\\mathsf{X}$ と $\\mathsf{Y}$ が、同じ古典的な状態セット $\\Sigma$ を共有するシステムであるとします。ペア $(\\mathsf{X},\\mathsf{Y})$ の*スワップ*操作は、2 つのシステムの内容を交換する操作ですが、それ以外の場合はシステムをそのままにしておきます (したがって、 $\\mathsf{X}$ は左側に、 $\\mathsf{Y}$ が右側に残ります)。\n",
"\n",
"この演算を $\\operatorname{SWAP}$ と書き、古典的な状態 $a,b\\in\\Sigma$ のすべての選択に対して、次のように操作します。\n",
"\n",
@@ -2053,7 +2053,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "以下の別の例では、 $|{-}\\rangle$ および $\\tfrac{1}{\\sqrt{2}}(|0\\rangle + i|1\\rangle)$ 状態を表す状態ベクトルを作成し、合成して、新しい状態ベクトルを作成します。この新しいベクトルを変数`psi`に割り当てます。"
+ "以下の別の例では、 $|{+}\\rangle$ および $\\tfrac{1}{\\sqrt{2}}(|0\\rangle + i|1\\rangle)$ 状態を表す状態ベクトルを作成し、合成して、新しい状態ベクトルを作成します。この新しいベクトルを変数`psi`に割り当てます。"
]
},
{
diff --git a/translations/ja/quantum-hardware/error-correction-repetition-code.ipynb b/translations/ja/quantum-hardware/error-correction-repetition-code.ipynb
index e8534974..a066fe96 100755
--- a/translations/ja/quantum-hardware/error-correction-repetition-code.ipynb
+++ b/translations/ja/quantum-hardware/error-correction-repetition-code.ipynb
@@ -157,7 +157,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "{'000': 992, '001': 6, '010': 18, '100': 8}\n"
+ "{'001': 6, '100': 10, '010': 11, '000': 997}\n"
]
}
],
@@ -174,6 +174,20 @@
"print(counts)"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "tags": [
+ "sanity-check"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# ...almost all results still come out '000',...\n",
+ "assert counts['000'] > sum(counts.values())*0.95"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -185,14 +199,14 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "{'011': 16, '101': 13, '110': 16, '111': 979}\n"
+ "{'001': 1, '110': 16, '101': 19, '011': 9, '111': 979}\n"
]
}
],
@@ -208,6 +222,21 @@
"print(counts)"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "tags": [
+ "sanity-check"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# ...number of samples that come out with a majority in the wrong state\n",
+ "# (0 in this case) is again much less than 10,...\n",
+ "assert counts.get('000', 0) < 10"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -219,14 +248,14 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "{'000': 127, '001': 123, '010': 133, '011': 152, '100': 117, '101': 122, '110': 118, '111': 132}\n"
+ "{'100': 124, '001': 126, '110': 119, '101': 133, '010': 117, '000': 127, '011': 139, '111': 139}\n"
]
}
],
@@ -236,6 +265,21 @@
"print(counts)"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "tags": [
+ "sanity-check"
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# ...all outcomes occur with equal probability, with\n",
+ "# differences in results being due only to statistical noise.\n",
+ "assert max(counts.values()) < 200"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -280,17 +324,19 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
- "image/png": "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\n",
+ "image/svg+xml": [
+ ""
+ ],
"text/plain": [
- "