Skip to main content
IBM Quantum Platform

ハミルトンシミュレーションのためのQiskit関数テンプレートを構築する

このテンプレートは、ユーザー定義のスピンのハミルトニアンに対する初期状態の時間発展をシミュレートするワークフローをカプセル化し、 AQC-Tensor Qiskit アドオンを使用して、指定された期待値のセットを返します。

このテンプレートはQiskitパターンとして構成されており、以下のようなステップを踏む:

1. 入力の収集と問題の整理

このセクションでは、シミュレーションするハミルトニアン、 QuantumCircuit 形式の初期状態、期待値を推定するための観測量セット、AQCアドオンのオプション指定を入力として受け取ります。 このステップでは、必要な入力データがすべて存在し、それらが正しいフォーマットであることを検証する。

入力された引数は、ワークフローに関連する量子回路と演算子の構築に使用される。 ターゲット回路が作成され、AQCアドオンを使用してこの回路の行列積状態表現が求められる。 これに続いて、アンサッツ回路が生成され、テンソルネットワーク法を用いて最適化され、残りの時間発展を実行する最終的な回路が生成される。

2. 生成された回路を実行準備する

AQCアドオンから生成された回路は、選択したバックエンドで実行されるようにトランスパイルされる。 インスタンス EstimatorV2 インスタンスは、回路の実行を管理するためのエラー緩和オプションのデフォルトセットとともに作成される。

3. 実行

最後に、ansatz回路はトランスパイルされ、QPU上で実行され、指定されたすべての期待値の推定値を収集し、ユーザーがアクセスできるようにシリアライズ可能な形式で返される。


関数テンプレートを記述する

まず、 AQC-Tensor Qiskit アドオンを使用して、問題の説明をハードウェア上で実行するための減深回路にマッピングする、ハミルトニアンシミュレーションの関数テンプレートを作成します。

このページをダウンロードして、ノートブックエディタでローカルに開くと、一部のコードセルに「 magic」コマンドが含まれているのが %%writefileわかります。 このマジックコマンドはコードを に保存 ./source_files/template_hamiltonian_simulation.pyします。これは、 Qiskit Serverless を使用してアップロードし、リモートで実行できる関数テンプレートです。

入力値を収集し検証する

テンプレートのインプットを得ることから始める。 この例では、ハミルトニアンシミュレーションに関連するドメイン固有の入力(ハミルトニアンや観測値など)と、能力固有のオプション(AQC-Tensorを使用してトロッター回路の初期レイヤーをどれだけ圧縮するか、あるいは、この例の一部であるデフォルトを超えるエラー抑制と緩和を微調整するための高度なオプションなど)があります。

./source_files/template_hamiltonian_simulation.py
from qiskit import QuantumCircuit
from qiskit_serverless import get_arguments, save_result


# Extract parameters from arguments
#
# Do this at the top of the program so it fails early if any required arguments
# are missing or invalid.

arguments = get_arguments()

dry_run = arguments.get("dry_run", False)
backend_name = arguments["backend_name"]

aqc_evolution_time = arguments["aqc_evolution_time"]
aqc_ansatz_num_trotter_steps = arguments["aqc_ansatz_num_trotter_steps"]
aqc_target_num_trotter_steps = arguments["aqc_target_num_trotter_steps"]

remainder_evolution_time = arguments["remainder_evolution_time"]
remainder_num_trotter_steps = arguments["remainder_num_trotter_steps"]

# Stop if this fidelity is achieved
aqc_stopping_fidelity = arguments.get("aqc_stopping_fidelity", 1.0)
# Stop after this number of iterations, even if stopping fidelity is not achieved
aqc_max_iterations = arguments.get("aqc_max_iterations", 500)

hamiltonian = arguments["hamiltonian"]
observable = arguments["observable"]
initial_state = arguments.get("initial_state",
    QuantumCircuit(hamiltonian.num_qubits))
./source_files/template_hamiltonian_simulation.py (appended)
import numpy as np
import json
from mergedeep import merge


# Configure `EstimatorOptions`, to control the parameters
# of the hardware experiment
#
# Set default options
estimator_default_options = {
    "resilience": {
        "measure_mitigation": True,
        "zne_mitigation": True,
        "zne": {
            "amplifier": "gate_folding",
            "noise_factors": [1, 2, 3],
            "extrapolated_noise_factors": list(np.linspace(0, 3, 31)),
            "extrapolator": ["exponential", "linear", "fallback"],
        },
        "measure_noise_learning": {
            "num_randomizations": 512,
            "shots_per_randomization": 512,
        },
    },
    "twirling": {
        "enable_gates": True,
        "enable_measure": True,
        "num_randomizations": 300,
        "shots_per_randomization": 100,
        "strategy": "active",
    },
}
# Merge with user-provided options
estimator_options = merge(
    arguments.get("estimator_options", {}), estimator_default_options
)

関数テンプレートが実行されているとき、printステートメントを使用してログに情報を返すと、ワークロードの進捗状況をよりよく評価することができます。 以下は estimator_options 、実際に使用したEstimatorオプションの記録を印刷する簡単な例です。 AQC-Tensorの反復コンポーネント中の目的関数の値や、ハードウェア上での実行を目的とした最終的な命令セットアーキテクチャ(ISA)回路の2量子ビット深度など、実行中の進捗状況を報告するために、プログラム全体を通して同様の例が他にもたくさんある。

./source_files/template_hamiltonian_simulation.py (appended)
print("estimator_options =", json.dumps(estimator_options, indent=4))

入力の検証

テンプレートをさまざまな入力で再利用できるようにするための重要な点は、入力の検証である。 以下のコードは、AQC-Tensorの停止フィデリティが適切に指定されているかどうかを検証し、指定されていない場合は、エラーを修正する方法について有益なエラーメッセージを返す例である。

./source_files/template_hamiltonian_simulation.py (appended)
# Perform parameter validation

if not 0.0 < aqc_stopping_fidelity <= 1.0:
    raise ValueError(
        f"Invalid stopping fidelity: {aqc_stopping_fidelity}.  "
        f"It must be a positive float no greater than 1."
    )

関数の出力を準備する

まず、関数テンプレートの出力をすべて保持する辞書を用意する。 キーは、ワークフロー全体を通してこの辞書に追加され、プログラムの最後に返される。

./source_files/template_hamiltonian_simulation.py (appended)
output = {}

問題をマッピングし、AQCを用いて回路を前処理する

AQC-Tensorの最適化は、Qiskitパターンのステップ1で行われる。 まず、目標とする状態を構築する。 この例では、AQC部分と同じハミルトニアンを同じ期間進化させるターゲット回路から構成される。 次に、等価回路から、より少ないトロッターステップで、アナザッツが生成される。 AQCアルゴリズムの主要部分では、このansatzを繰り返し目標状態に近づけていく。 最後に、その結果を、所望の進化時間に到達するために必要な残りのトロッターステップと組み合わせる。

以下のコードにロギングの例が追加されている。

./source_files/template_hamiltonian_simulation.py (appended)
import os
os.environ["NUMBA_CACHE_DIR"] = "/data"

import datetime
import quimb.tensor
from scipy.optimize import OptimizeResult, minimize
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
from qiskit_addon_aqc_tensor.ansatz_generation import (
    generate_ansatz_from_circuit,
    AnsatzBlock,
)
from qiskit_addon_aqc_tensor.simulation import (
    tensornetwork_from_circuit,
    compute_overlap,
)
from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator
from qiskit_addon_aqc_tensor.objective import OneMinusFidelity

print("Hamiltonian:", hamiltonian)
print("Observable:", observable)
simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend="jax")

# Construct the AQC target circuit
aqc_target_circuit = initial_state.copy()
if aqc_evolution_time:
    aqc_target_circuit.compose(
        generate_time_evolution_circuit(
            hamiltonian,
            synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
            time=aqc_evolution_time,
        ),
        inplace=True,
    )

# Construct matrix-product state representation of the AQC target state
aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings)
print("Target MPS maximum bond dimension:", aqc_target_mps.psi.max_bond())
output["target_bond_dimension"] = aqc_target_mps.psi.max_bond()

# Generate an ansatz and initial parameters from a Trotter circuit with fewer steps
aqc_good_circuit = initial_state.copy()
if aqc_evolution_time:
    aqc_good_circuit.compose(
        generate_time_evolution_circuit(
            hamiltonian,
            synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),
            time=aqc_evolution_time,
        ),
        inplace=True,
    )
aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit)
print("Number of AQC parameters:", len(aqc_initial_parameters))
output["num_aqc_parameters"] = len(aqc_initial_parameters)

# Calculate the fidelity of ansatz circuit vs. the target state, before optimization
good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings)
starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2
print("Starting fidelity of AQC portion:", starting_fidelity)
output["aqc_starting_fidelity"] = starting_fidelity

# Optimize the ansatz parameters by using MPS calculations
def callback(intermediate_result: OptimizeResult):
    fidelity = 1 - intermediate_result.fun
    print(f"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}")
    if intermediate_result.fun < stopping_point:
        raise StopIteration


objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings)
stopping_point = 1.0 - aqc_stopping_fidelity

result = minimize(
    objective,
    aqc_initial_parameters,
    method="L-BFGS-B",
    jac=True,
    options={"maxiter": aqc_max_iterations},
    callback=callback,
)
if result.status not in (
    0,
    1,
    99,
):  # 0 => success; 1 => max iterations reached;
    # 99 => early termination via StopIteration
    raise RuntimeError(
        f"Optimization failed: {result.message} (status={result.status})"
    )
print(f"Done after {result.nit} iterations.")
output["num_iterations"] = result.nit
aqc_final_parameters = result.x
output["aqc_final_parameters"] = list(aqc_final_parameters)

# Construct an optimized circuit for initial portion of time evolution
aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)

# Calculate fidelity after optimization
aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings)
aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2
print("Fidelity of AQC portion:", aqc_fidelity)
output["aqc_fidelity"] = aqc_fidelity

# Construct final circuit, with remainder of time evolution
final_circuit = aqc_final_circuit.copy()
if remainder_evolution_time:
    remainder_circuit = generate_time_evolution_circuit(
        hamiltonian,
        synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),
        time=remainder_evolution_time,
    )
    final_circuit.compose(remainder_circuit, inplace=True)

最終回路の実行を最適化する

ワークフローのAQC部分の後、 final_circuit 、通常通りハードウェア用にトランスパイルされる。

./source_files/template_hamiltonian_simulation.py (appended)
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager

service = QiskitRuntimeService()
backend = service.backend(backend_name)

# Transpile PUBs (circuits and observables) to match ISA
pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3)
isa_circuit = pass_manager.run(final_circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)

isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)
print("ISA circuit two-qubit depth:", isa_2qubit_depth)
output["twoqubit_depth"] = isa_2qubit_depth

ドライランモードを使用する場合は早めに終了してください

ドライ・ラン・モードが選択されている場合、プログラムはハードウェア上で実行される前に停止される。 これは、例えば、ハードウェア上で実行するかどうかを決定する前に、まずISA回路の2量子ビット深度を検査したい場合に便利である。

./source_files/template_hamiltonian_simulation.py (appended)
# Exit now if dry run; don't execute on hardware
if dry_run:
    import sys

    print("Exiting before hardware execution since `dry_run` is True.")
    save_result(output)
    sys.exit(0)

回路をハードウェア上で実行する

./source_files/template_hamiltonian_simulation.py (appended)
# ## Step 3: Execute quantum experiments on backend
from qiskit_ibm_runtime import EstimatorV2 as Estimator


estimator = Estimator(backend, options=estimator_options)

# Submit the underlying Estimator job. Note that this is not the
# actual function job.
job = estimator.run([(isa_circuit, isa_observable)])
print("Job ID:", job.job_id())
output["job_id"] = job.job_id()

# Wait until job is complete
hw_results = job.result()
hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results]

# Save hardware results to serverless output dictionary
output["hw_results"] = hw_results_dicts

# Reorganize expectation values
hw_expvals = [pub_result_data["evs"].tolist()
    for pub_result_data in hw_results_dicts]

# Save expectation values to Qiskit Serverless
print("Hardware expectation values", hw_expvals)
output["hw_expvals"] = hw_expvals[0]

出力を保存する

この関数テンプレートは、このハミルトニアン・シミュレーションのワークフローに関連するドメインレベルの出力(期待値)に加え、途中で生成された重要なメタデータを返します。

./source_files/template_hamiltonian_simulation.py (appended)
save_result(output)

関数を IBM Quantum Platform にデプロイする

前のセクションでは、リモートで実行するプログラムを作成した。 このセクションのコードは、そのプログラムをQiskit Serverlessにアップロードします。

IBM Quantum PlatformのダッシュボードにあるAPIキーで、 qiskit-ibm-catalog を使って QiskitServerless に認証し、プログラムをアップロードします。

オプションで、 save_account() 認証情報を保存するために IBM Cloud を使用できます(アカウントの設定ガイドを参照)。 この操作は、認証情報を同じファイルに QiskitRuntimeService.save_account()書き込むことに注意してください。

from qiskit_ibm_catalog import QiskitServerless, QiskitFunction

# Authenticate to the remote cluster and submit the pattern
# for remote execution
serverless = QiskitServerless()

このプログラムにはカスタム pip の依存関係がある。 QiskitFunction インスタンスを構築する際に、それらを dependencies 配列に追加する:

template = QiskitFunction(
    title="template_hamiltonian_simulation",
    entrypoint="template_hamiltonian_simulation.py",
    working_dir="./source_files/",
    dependencies=[
        "qiskit-addon-utils~=0.1.0",
        "qiskit-addon-aqc-tensor[quimb-jax]~=0.1.2",
        "mergedeep==1.3.4",
    ],
)
serverless.upload(template)

Output:

QiskitFunction(template_hamiltonian_simulation)

最後に、プログラムが正常にアップロードされたかどうかを確認するには、 serverless.list() を使用します:

serverless.list()

Output:

 QiskitFunction(template_hamiltonian_simulation),


関数テンプレートをリモートで実行する

関数テンプレートがアップロードされたので、Qiskit Serverlessでリモート実行できる。 まず、テンプレートを名前で読み込む:

template = serverless.load("template_hamiltonian_simulation")

次に、ハミルトニアンシミュレーションのために、ドメインレベルの入力でテンプレートを実行します。 この例では、ランダムな結合を持つ50量子ビットのXXZモデルと、初期状態と観測量を指定する。

from itertools import chain
import numpy as np
from qiskit.quantum_info import SparsePauliOp

L = 50

# Generate the edge list for this spin-chain
edges = [(i, i + 1) for i in range(L - 1)]
# Generate an edge-coloring so we can make hw-efficient circuits
edges = edges[::2] + edges[1::2]

# Generate random coefficients for our XXZ Hamiltonian
np.random.seed(0)
Js = np.random.rand(L - 1) + 0.5 * np.ones(L - 1)

hamiltonian = SparsePauliOp.from_sparse_list(
    chain.from_iterable(
        [
            [
                ("XX", (i, j), Js[i] / 2),
                ("YY", (i, j), Js[i] / 2),
                ("ZZ", (i, j), Js[i]),
            ]
            for i, j in edges
        ]
    ),
    num_qubits=L,
)
observable = SparsePauliOp.from_sparse_list(
    [("ZZ", (L // 2 - 1, L // 2), 1.0)], num_qubits=L
)
from qiskit import QuantumCircuit

initial_state = QuantumCircuit(L)
for i in range(L):
    if i % 2:
        initial_state.x(i)
job = template.run(
    dry_run=True,
    initial_state=initial_state,
    hamiltonian=hamiltonian,
    observable=observable,
    backend_name="ibm_fez",
    estimator_options={},
    aqc_evolution_time=0.2,
    aqc_ansatz_num_trotter_steps=1,
    aqc_target_num_trotter_steps=32,
    remainder_evolution_time=0.2,
    remainder_num_trotter_steps=4,
    aqc_max_iterations=300,
)
print(job.job_id)

Output:

853b0edb-d63f-4629-be71-398b6dcf33cb

ジョブのステータスを確認する:

job.status()

Output:

'QUEUED'

ジョブの実行後、 print() 出力から作成されたログをフェッチできる。 これらは、ハミルトニアン・シミュレーションのワークフローの進捗状況について、実用的な情報を提供することができる。 例えば、AQCの反復コンポーネント中の目的関数の値や、ハードウェア上で実行することを意図した最終的なISA回路の2量子ビット深さなどである。

print(job.logs())

Output:

No logs yet.

結果が出るまで、残りのプログラムをブロックする。 仕事が終わったら、結果を取り出すことができる。 これらには、ハミルトニアン・シミュレーションのドメインレベルの出力(期待値)や有用なメタデータが含まれる。

result = job.result()

del result[
    "aqc_final_parameters"
]  # the list is too long to conveniently display here
result

Output:

{'target_bond_dimension': 5,
 'num_aqc_parameters': 816,
 'aqc_starting_fidelity': 0.9914382555614002,
 'num_iterations': 72,
 'aqc_fidelity': 0.9998108844412502,
 'twoqubit_depth': 33}

ジョブが完了すると、ログ出力全体が利用可能になる。

print(job.logs())

Output:

2024-12-17 14:50:15,580	INFO job_manager.py:531 -- Runtime env is setting up.
estimator_options = {
    "resilience": {
        "measure_mitigation": true,
        "zne_mitigation": true,
        "zne": {
            "amplifier": "gate_folding",
            "noise_factors": [
                1,
                2,
                3
            ],
            "extrapolated_noise_factors": [
                0.0,
                0.1,
                0.2,
                0.30000000000000004,
                0.4,
                0.5,
                0.6000000000000001,
                0.7000000000000001,
                0.8,
                0.9,
                1.0,
                1.1,
                1.2000000000000002,
                1.3,
                1.4000000000000001,
                1.5,
                1.6,
                1.7000000000000002,
                1.8,
                1.9000000000000001,
                2.0,
                2.1,
                2.2,
                2.3000000000000003,
                2.4000000000000004,
                2.5,
                2.6,
                2.7,
                2.8000000000000003,
                2.9000000000000004,
                3.0
            ],
            "extrapolator": [
                "exponential",
                "linear",
                "fallback"
            ]
        },
        "measure_noise_learning": {
            "num_randomizations": 512,
            "shots_per_randomization": 512
        }
    },
    "twirling": {
        "enable_gates": true,
        "enable_measure": true,
        "num_randomizations": 300,
        "shots_per_randomization": 100,
        "strategy": "active"
    }
}
Hamiltonian: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXX', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYY', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'XXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'YYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IXXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IYYIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],
              coeffs=[0.52440675+0.j, 0.52440675+0.j, 1.0488135 +0.j, 0.55138169+0.j,
 0.55138169+0.j, 1.10276338+0.j, 0.4618274 +0.j, 0.4618274 +0.j,
 0.9236548 +0.j, 0.46879361+0.j, 0.46879361+0.j, 0.93758721+0.j,
 0.73183138+0.j, 0.73183138+0.j, 1.46366276+0.j, 0.64586252+0.j,
 0.64586252+0.j, 1.29172504+0.j, 0.53402228+0.j, 0.53402228+0.j,
 1.06804456+0.j, 0.28551803+0.j, 0.28551803+0.j, 0.57103606+0.j,
 0.2601092 +0.j, 0.2601092 +0.j, 0.5202184 +0.j, 0.63907838+0.j,
 0.63907838+0.j, 1.27815675+0.j, 0.73930917+0.j, 0.73930917+0.j,
 1.47861834+0.j, 0.48073968+0.j, 0.48073968+0.j, 0.96147936+0.j,
 0.30913721+0.j, 0.30913721+0.j, 0.61827443+0.j, 0.32167664+0.j,
 0.32167664+0.j, 0.64335329+0.j, 0.51092416+0.j, 0.51092416+0.j,
 1.02184832+0.j, 0.38227781+0.j, 0.38227781+0.j, 0.76455561+0.j,
 0.47807517+0.j, 0.47807517+0.j, 0.95615033+0.j, 0.2593949 +0.j,
 0.2593949 +0.j, 0.5187898 +0.j, 0.55604786+0.j, 0.55604786+0.j,
 1.11209572+0.j, 0.72187404+0.j, 0.72187404+0.j, 1.44374808+0.j,
 0.42975395+0.j, 0.42975395+0.j, 0.8595079 +0.j, 0.5988156 +0.j,
 0.5988156 +0.j, 1.1976312 +0.j, 0.58338336+0.j, 0.58338336+0.j,
 1.16676672+0.j, 0.35519128+0.j, 0.35519128+0.j, 0.71038256+0.j,
 0.40771418+0.j, 0.40771418+0.j, 0.81542835+0.j, 0.60759468+0.j,
 0.60759468+0.j, 1.21518937+0.j, 0.52244159+0.j, 0.52244159+0.j,
 1.04488318+0.j, 0.57294706+0.j, 0.57294706+0.j, 1.14589411+0.j,
 0.6958865 +0.j, 0.6958865 +0.j, 1.391773  +0.j, 0.44172076+0.j,
 0.44172076+0.j, 0.88344152+0.j, 0.51444746+0.j, 0.51444746+0.j,
 1.02889492+0.j, 0.71279832+0.j, 0.71279832+0.j, 1.42559664+0.j,
 0.29356465+0.j, 0.29356465+0.j, 0.5871293 +0.j, 0.66630992+0.j,
 0.66630992+0.j, 1.33261985+0.j, 0.68500607+0.j, 0.68500607+0.j,
 1.37001215+0.j, 0.64957928+0.j, 0.64957928+0.j, 1.29915856+0.j,
 0.64026459+0.j, 0.64026459+0.j, 1.28052918+0.j, 0.56996051+0.j,
 0.56996051+0.j, 1.13992102+0.j, 0.72233446+0.j, 0.72233446+0.j,
 1.44466892+0.j, 0.45733097+0.j, 0.45733097+0.j, 0.91466194+0.j,
 0.63711684+0.j, 0.63711684+0.j, 1.27423369+0.j, 0.53421697+0.j,
 0.53421697+0.j, 1.06843395+0.j, 0.55881775+0.j, 0.55881775+0.j,
 1.1176355 +0.j, 0.558467  +0.j, 0.558467  +0.j, 1.116934  +0.j,
 0.59091015+0.j, 0.59091015+0.j, 1.1818203 +0.j, 0.46851598+0.j,
 0.46851598+0.j, 0.93703195+0.j, 0.28011274+0.j, 0.28011274+0.j,
 0.56022547+0.j, 0.58531893+0.j, 0.58531893+0.j, 1.17063787+0.j,
 0.31446315+0.j, 0.31446315+0.j, 0.6289263 +0.j])
Observable: SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII'],
              coeffs=[1.+0.j])
Target MPS maximum bond dimension: 5
Number of AQC parameters: 816
Starting fidelity of AQC portion: 0.9914382555614002
2024-12-17 14:52:23.400028 Intermediate result: Fidelity 0.99764093
2024-12-17 14:52:23.429669 Intermediate result: Fidelity 0.99788003
2024-12-17 14:52:23.459674 Intermediate result: Fidelity 0.99795970
2024-12-17 14:52:23.489666 Intermediate result: Fidelity 0.99799067
2024-12-17 14:52:23.518545 Intermediate result: Fidelity 0.99803401
2024-12-17 14:52:23.546952 Intermediate result: Fidelity 0.99809821
2024-12-17 14:52:23.575271 Intermediate result: Fidelity 0.99824660
2024-12-17 14:52:23.604049 Intermediate result: Fidelity 0.99845326
2024-12-17 14:52:23.632709 Intermediate result: Fidelity 0.99870497
2024-12-17 14:52:23.660527 Intermediate result: Fidelity 0.99891442
2024-12-17 14:52:23.688273 Intermediate result: Fidelity 0.99904488
2024-12-17 14:52:23.716105 Intermediate result: Fidelity 0.99914438
2024-12-17 14:52:23.744336 Intermediate result: Fidelity 0.99922827
2024-12-17 14:52:23.773399 Intermediate result: Fidelity 0.99929071
2024-12-17 14:52:23.801482 Intermediate result: Fidelity 0.99932432
2024-12-17 14:52:23.830466 Intermediate result: Fidelity 0.99936460
2024-12-17 14:52:23.860738 Intermediate result: Fidelity 0.99938891
2024-12-17 14:52:23.889958 Intermediate result: Fidelity 0.99940607
2024-12-17 14:52:23.918703 Intermediate result: Fidelity 0.99941965
2024-12-17 14:52:23.949744 Intermediate result: Fidelity 0.99944337
2024-12-17 14:52:23.980871 Intermediate result: Fidelity 0.99946875
2024-12-17 14:52:24.012124 Intermediate result: Fidelity 0.99949009
2024-12-17 14:52:24.044359 Intermediate result: Fidelity 0.99952191
2024-12-17 14:52:24.075840 Intermediate result: Fidelity 0.99953669
2024-12-17 14:52:24.106303 Intermediate result: Fidelity 0.99955242
2024-12-17 14:52:24.139329 Intermediate result: Fidelity 0.99958412
2024-12-17 14:52:24.169725 Intermediate result: Fidelity 0.99960176
2024-12-17 14:52:24.198749 Intermediate result: Fidelity 0.99961606
2024-12-17 14:52:24.227874 Intermediate result: Fidelity 0.99963811
2024-12-17 14:52:24.256818 Intermediate result: Fidelity 0.99964383
2024-12-17 14:52:24.285889 Intermediate result: Fidelity 0.99964717
2024-12-17 14:52:24.315228 Intermediate result: Fidelity 0.99966064
2024-12-17 14:52:24.345322 Intermediate result: Fidelity 0.99966517
2024-12-17 14:52:24.374921 Intermediate result: Fidelity 0.99967089
2024-12-17 14:52:24.404309 Intermediate result: Fidelity 0.99968305
2024-12-17 14:52:24.432664 Intermediate result: Fidelity 0.99968889
2024-12-17 14:52:24.461639 Intermediate result: Fidelity 0.99969997
2024-12-17 14:52:24.491244 Intermediate result: Fidelity 0.99971666
2024-12-17 14:52:24.520354 Intermediate result: Fidelity 0.99972441
2024-12-17 14:52:24.549965 Intermediate result: Fidelity 0.99973561
2024-12-17 14:52:24.583464 Intermediate result: Fidelity 0.99973811
2024-12-17 14:52:24.617537 Intermediate result: Fidelity 0.99974074
2024-12-17 14:52:24.652247 Intermediate result: Fidelity 0.99974467
2024-12-17 14:52:24.686831 Intermediate result: Fidelity 0.99974991
2024-12-17 14:52:24.725476 Intermediate result: Fidelity 0.99975230
2024-12-17 14:52:24.764637 Intermediate result: Fidelity 0.99975373
2024-12-17 14:52:24.802499 Intermediate result: Fidelity 0.99975552
2024-12-17 14:52:24.839960 Intermediate result: Fidelity 0.99975885
2024-12-17 14:52:24.877472 Intermediate result: Fidelity 0.99976469
2024-12-17 14:52:24.916233 Intermediate result: Fidelity 0.99976517
2024-12-17 14:52:24.993750 Intermediate result: Fidelity 0.99976875
2024-12-17 14:52:25.034953 Intermediate result: Fidelity 0.99976887
2024-12-17 14:52:25.076197 Intermediate result: Fidelity 0.99977244
2024-12-17 14:52:25.112340 Intermediate result: Fidelity 0.99977638
2024-12-17 14:52:25.149947 Intermediate result: Fidelity 0.99977828
2024-12-17 14:52:25.190049 Intermediate result: Fidelity 0.99978174
2024-12-17 14:52:25.310903 Intermediate result: Fidelity 0.99978222
2024-12-17 14:52:25.347512 Intermediate result: Fidelity 0.99978508
2024-12-17 14:52:25.385201 Intermediate result: Fidelity 0.99978543
2024-12-17 14:52:25.457436 Intermediate result: Fidelity 0.99978770
2024-12-17 14:52:25.497133 Intermediate result: Fidelity 0.99978818
2024-12-17 14:52:25.541179 Intermediate result: Fidelity 0.99978913
2024-12-17 14:52:25.584791 Intermediate result: Fidelity 0.99978937
2024-12-17 14:52:25.621484 Intermediate result: Fidelity 0.99979068
2024-12-17 14:52:25.655847 Intermediate result: Fidelity 0.99979211
2024-12-17 14:52:25.691710 Intermediate result: Fidelity 0.99979700
2024-12-17 14:52:25.767711 Intermediate result: Fidelity 0.99979759
2024-12-17 14:52:25.804517 Intermediate result: Fidelity 0.99979807
2024-12-17 14:52:25.839394 Intermediate result: Fidelity 0.99980236
2024-12-17 14:52:25.874438 Intermediate result: Fidelity 0.99980296
2024-12-17 14:52:25.909900 Intermediate result: Fidelity 0.99980320
2024-12-17 14:52:26.713044 Intermediate result: Fidelity 0.99980320
Done after 72 iterations.
Fidelity of AQC portion: 0.9998108844412502
ISA circuit two-qubit depth: 33
Exiting before hardware execution since `dry_run` is True.


次のステップ

推奨事項

AQC-TensorのQiskitアドオンを深く掘り下げるには、 Improved Trotterized Time Evolution with Approximate Quantum Compilation チュートリアルか qiskit-addon-aqc-tensor リポジトリをご覧ください。

  • 以下は、 ./source_files/template_hamiltonian_simulation.py のソース全体を1つのコードブロックにしたものである。

    ./source_files/template_hamiltonian_simulation_full.py
    from qiskit import QuantumCircuit
    from qiskit_serverless import get_arguments, save_result
    
    
    # Extract parameters from arguments
    #
    # Do this at the top of the program so it fails early
    # if any required arguments are missing or invalid.
    
    arguments = get_arguments()
    
    dry_run = arguments.get("dry_run", False)
    backend_name = arguments["backend_name"]
    
    aqc_evolution_time = arguments["aqc_evolution_time"]
    aqc_ansatz_num_trotter_steps = arguments["aqc_ansatz_num_trotter_steps"]
    aqc_target_num_trotter_steps = arguments["aqc_target_num_trotter_steps"]
    
    remainder_evolution_time = arguments["remainder_evolution_time"]
    remainder_num_trotter_steps = arguments["remainder_num_trotter_steps"]
    
    # Stop if this fidelity is achieved
    aqc_stopping_fidelity = arguments.get("aqc_stopping_fidelity", 1.0)
    # Stop after this number of iterations, even if stopping fidelity is not achieved
    aqc_max_iterations = arguments.get("aqc_max_iterations", 500)
    
    hamiltonian = arguments["hamiltonian"]
    observable = arguments["observable"]
    initial_state = arguments.get("initial_state", QuantumCircuit(hamiltonian.num_qubits))
    
    import numpy as np
    import json
    from mergedeep import merge
    
    
    # Configure `EstimatorOptions` to control the hardware experiment's parameters
    #
    # Set default options
    estimator_default_options = {
        "resilience": {
            "measure_mitigation": True,
            "zne_mitigation": True,
            "zne": {
                "amplifier": "gate_folding",
                "noise_factors": [1, 2, 3],
                "extrapolated_noise_factors": list(np.linspace(0, 3, 31)),
                "extrapolator": ["exponential", "linear", "fallback"],
            },
            "measure_noise_learning": {
                "num_randomizations": 512,
                "shots_per_randomization": 512,
            },
        },
        "twirling": {
            "enable_gates": True,
            "enable_measure": True,
            "num_randomizations": 300,
            "shots_per_randomization": 100,
            "strategy": "active",
        },
    }
    # Merge with user-provided options
    estimator_options = merge(
        arguments.get("estimator_options", {}), estimator_default_options
    )
    
    print("estimator_options =", json.dumps(estimator_options, indent=4))
    
    # Perform parameter validation
    
    if not 0.0 < aqc_stopping_fidelity <= 1.0:
        raise ValueError(
            f"Invalid stopping fidelity: {aqc_stopping_fidelity}.  "
            It must be a positive float no greater than 1."
        )
    
    output = {}
    
    import os
    os.environ["NUMBA_CACHE_DIR"] = "/data"
    
    import datetime
    import quimb.tensor
    from scipy.optimize import OptimizeResult, minimize
    from qiskit.synthesis import SuzukiTrotter
    from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
    from qiskit_addon_aqc_tensor.ansatz_generation import (
        generate_ansatz_from_circuit,
        AnsatzBlock,
    )
    from qiskit_addon_aqc_tensor.simulation import (
        tensornetwork_from_circuit,
        compute_overlap,
    )
    from qiskit_addon_aqc_tensor.simulation.quimb import QuimbSimulator
    from qiskit_addon_aqc_tensor.objective import OneMinusFidelity
    
    print("Hamiltonian:", hamiltonian)
    print("Observable:", observable)
    simulator_settings = QuimbSimulator(quimb.tensor.CircuitMPS, autodiff_backend="jax")
    
    # Construct the AQC target circuit
    aqc_target_circuit = initial_state.copy()
    if aqc_evolution_time:
        aqc_target_circuit.compose(
            generate_time_evolution_circuit(
                hamiltonian,
                synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
                time=aqc_evolution_time,
            ),
            inplace=True,
        )
    
    # Construct matrix-product state representation of the AQC target state
    aqc_target_mps = tensornetwork_from_circuit(aqc_target_circuit, simulator_settings)
    print("Target MPS maximum bond dimension:", aqc_target_mps.psi.max_bond())
    output["target_bond_dimension"] = aqc_target_mps.psi.max_bond()
    
    # Generate an ansatz and initial parameters from a Trotter circuit with fewer steps
    aqc_good_circuit = initial_state.copy()
    if aqc_evolution_time:
        aqc_good_circuit.compose(
            generate_time_evolution_circuit(
                hamiltonian,
                synthesis=SuzukiTrotter(reps=aqc_ansatz_num_trotter_steps),
                time=aqc_evolution_time,
            ),
            inplace=True,
        )
    aqc_ansatz, aqc_initial_parameters = generate_ansatz_from_circuit(aqc_good_circuit)
    print("Number of AQC parameters:", len(aqc_initial_parameters))
    output["num_aqc_parameters"] = len(aqc_initial_parameters)
    
    # Calculate the fidelity of ansatz circuit vs. the target state, before optimization
    good_mps = tensornetwork_from_circuit(aqc_good_circuit, simulator_settings)
    starting_fidelity = abs(compute_overlap(good_mps, aqc_target_mps)) ** 2
    print("Starting fidelity of AQC portion:", starting_fidelity)
    output["aqc_starting_fidelity"] = starting_fidelity
    
    # Optimize the ansatz parameters by using MPS calculations
    def callback(intermediate_result: OptimizeResult):
        fidelity = 1 - intermediate_result.fun
        print(f"{datetime.datetime.now()} Intermediate result: Fidelity {fidelity:.8f}")
        if intermediate_result.fun < stopping_point:
            raise StopIteration
    
    
    objective = OneMinusFidelity(aqc_target_mps, aqc_ansatz, simulator_settings)
    stopping_point = 1.0 - aqc_stopping_fidelity
    
    result = minimize(
        objective,
        aqc_initial_parameters,
        method="L-BFGS-B",
        jac=True,
        options={"maxiter": aqc_max_iterations},
        callback=callback,
    )
    if result.status not in (
        0,
        1,
        99,
    ):  # 0 => success; 1 => max iterations reached; 99 => early termination via StopIteration
        raise RuntimeError(
            f"Optimization failed: {result.message} (status={result.status})"
        )
    print(f"Done after {result.nit} iterations.")
    output["num_iterations"] = result.nit
    aqc_final_parameters = result.x
    output["aqc_final_parameters"] = list(aqc_final_parameters)
    
    # Construct an optimized circuit for initial portion of time evolution
    aqc_final_circuit = aqc_ansatz.assign_parameters(aqc_final_parameters)
    
    # Calculate fidelity after optimization
    aqc_final_mps = tensornetwork_from_circuit(aqc_final_circuit, simulator_settings)
    aqc_fidelity = abs(compute_overlap(aqc_final_mps, aqc_target_mps)) ** 2
    print("Fidelity of AQC portion:", aqc_fidelity)
    output["aqc_fidelity"] = aqc_fidelity
    
    # Construct final circuit, with remainder of time evolution
    final_circuit = aqc_final_circuit.copy()
    if remainder_evolution_time:
        remainder_circuit = generate_time_evolution_circuit(
            hamiltonian,
            synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),
            time=remainder_evolution_time,
        )
        final_circuit.compose(remainder_circuit, inplace=True)
    
    from qiskit.transpiler import generate_preset_pass_manager
    from qiskit_ibm_catalog import QiskitFunctionsCatalog
    
    service = QiskitRuntimeService()
    backend = service.backend(backend_name)
    
    # Transpile PUBs (circuits and observables) to match ISA
    pass_manager = generate_preset_pass_manager(backend=backend, optimization_level=3)
    isa_circuit = pass_manager.run(final_circuit)
    isa_observable = observable.apply_layout(isa_circuit.layout)
    
    isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)
    print("ISA circuit two-qubit depth:", isa_2qubit_depth)
    output["twoqubit_depth"] = isa_2qubit_depth
    
    # Exit now if dry run; don't execute on hardware
    if dry_run:
        import sys
    
        print("Exiting before hardware execution since `dry_run` is True.")
        save_result(output)
        sys.exit(0)
    
    # ## Step 3: Execute quantum experiments on backend
    from qiskit_ibm_runtime import EstimatorV2 as Estimator
    
    
    estimator = Estimator(backend, options=estimator_options)
    
    # Submit the underlying Estimator job. Note that this is not the
    # actual function job.
    job = estimator.run([(isa_circuit, isa_observable)])
    print("Job ID:", job.job_id())
    output["job_id"] = job.job_id()
    
    # Wait until job is complete
    hw_results = job.result()
    hw_results_dicts = [pub_result.data.__dict__ for pub_result in hw_results]
    
    # Save hardware results to serverless output dictionary
    output["hw_results"] = hw_results_dicts
    
    # Reorganize expectation values
    hw_expvals = [pub_result_data["evs"].tolist()
        for pub_result_data in hw_results_dicts]
    
    # Save expectation values to Qiskit Serverless
    output["hw_expvals"] = hw_expvals[0]
    
    save_result(output)
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。