Skip to main content
IBM Quantum Platform

Crie um modelo de função Qiskit para simulação hamiltoniana

Este modelo encapsula um fluxo de trabalho para simular a evolução temporal de um estado inicial em relação a um Hamiltoniano baseado em spin definido pelo usuário e retorna um conjunto de valores esperados especificados usando o complemento AQC-Tensor Qiskit.

Esse modelo é estruturado como um padrão Qiskit com as seguintes etapas:

1. Coleta de informações e mapeamento do problema

Esta seção recebe como entrada o Hamiltoniano a ser simulado, um estado inicial na forma de um QuantumCircuit, um conjunto de observáveis para estimar os valores de expectativa e uma especificação de opções para o complemento AQC. Essa etapa valida se todos os dados de entrada necessários estão presentes e se estão no formato correto.

Os argumentos de entrada são então usados para construir os circuitos e operadores quânticos relevantes para o fluxo de trabalho. Um circuito de destino é criado e uma representação do estado do produto da matriz desse circuito é encontrada usando o complemento AQC. Depois disso, um circuito ansatz é gerado e otimizado usando métodos de rede tensorial, produzindo um circuito final que executa o restante da evolução temporal.

2. Prepare os circuitos gerados para execução

Os circuitos gerados pelo complemento AQC são então transpilados para execução em um backend escolhido. Uma instância EstimatorV2 é criada com um conjunto padrão de opções de atenuação de erros para gerenciar a execução do circuito.

3. Execução

Por fim, o circuito ansatz é transpilado e executado em uma QPU e coleta estimativas para todos os valores de expectativa especificados, que são retornados em um formato serializável para acesso pelo usuário.


Escreva o modelo da função

Primeiro, escreva um modelo de função para simulação hamiltoniana que utilize o complemento AQC-Tensor Qiskit para mapear a descrição do problema para um circuito de profundidade reduzida para execução em hardware.

Se você baixar esta página e a visualizar localmente em um editor de blocos de notas, verá que algumas das células de código contêm o comando mágico %%writefile. Este comando mágico salva o código em ./source_files/template_hamiltonian_simulation.py, que é o modelo de função que você pode enviar para o e executar remotamente usando Qiskit Serverless.

Coletar e validar as entradas

Comece obtendo as entradas para o modelo. Esse exemplo tem entradas específicas do domínio relevantes para a simulação hamiltoniana (como o hamiltoniano e o observável) e opções específicas do recurso (como o quanto você deseja comprimir as camadas iniciais do circuito de Trotter usando o AQC-Tensor ou opções avançadas para o ajuste fino da supressão e atenuação de erros além dos padrões que fazem parte deste exemplo).

./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
)

Quando o modelo de função está em execução, é útil retornar informações nos logs usando instruções de impressão, para que você possa avaliar melhor o progresso da carga de trabalho. A seguir, um exemplo simples de impressão do site estimator_options para que haja um registro das opções reais do Estimator usadas. Há muitos outros exemplos semelhantes em todo o programa para informar o progresso durante a execução, incluindo o valor da função objetiva durante o componente iterativo do AQC-Tensor e a profundidade de dois qubits do circuito final da arquitetura do conjunto de instruções (ISA) destinado à execução no hardware.

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

Valide as entradas

Um aspecto importante para garantir que o modelo possa ser reutilizado em uma variedade de entradas é a validação de entrada. O código a seguir é um exemplo de verificação de que a fidelidade de parada durante o AQC-Tensor foi especificada adequadamente e, caso contrário, retorna uma mensagem de erro informativa sobre como corrigir o erro.

./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."
    )

Prepare as saídas da função

Primeiro, prepare um dicionário para armazenar todas as saídas do modelo de função. As chaves serão adicionadas a esse dicionário durante todo o fluxo de trabalho, e ele será retornado no final do programa.

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

Mapeie o problema e pré-processe o circuito com AQC

A otimização do AQC-Tensor ocorre na etapa 1 de um padrão Qiskit. Primeiro, um estado-alvo é construído. Neste exemplo, ele é construído a partir de um circuito-alvo que evolui o mesmo Hamiltoniano para o mesmo período de tempo que a parte AQC. Em seguida, um ansatz é gerado a partir de um circuito equivalente, mas com menos etapas de Trotter. Na parte principal do algoritmo AQC, esse ansatz é iterativamente aproximado do estado-alvo. Por fim, o resultado é combinado com o restante das etapas de Trotter necessárias para atingir o tempo de evolução desejado.

Observe os exemplos adicionais de registro incorporados no código a seguir.

./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)

Otimize o circuito final para execução

Após a parte AQC do fluxo de trabalho, o final_circuit é transpilado para o hardware como de costume.

./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

Saia antecipadamente se estiver usando o modo de execução em seco

Se o modo de execução a seco tiver sido selecionado, o programa será interrompido antes de ser executado no hardware. Isso pode ser útil se, por exemplo, você quiser primeiro inspecionar a profundidade de dois qubits do circuito ISA antes de decidir executar no hardware.

./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)

Execute o circuito no hardware

./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]

Salve a saída

Esse modelo de função retorna o resultado relevante em nível de domínio para esse fluxo de trabalho de simulação hamiltoniana (valores de expectativa), além de metadados importantes gerados ao longo do caminho.

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

Implemente a função em IBM Quantum Platform

A seção anterior criou um programa para ser executado remotamente. O código nesta seção faz o upload desse programa para o Qiskit Serverless.

Use qiskit-ibm-catalog para se autenticar em QiskitServerless com sua chave de API, que pode ser encontrada no painel da IBM Quantum Platform, e faça o upload do programa.

Opcionalmente, você pode usar save_account() para salvar suas credenciais (consulte o guia Configurar sua conta IBM Cloud ). Observe que isso grava suas credenciais no mesmo arquivo que QiskitRuntimeService.save_account().

from qiskit_ibm_catalog import QiskitServerless, QiskitFunction

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

Esse programa tem dependências personalizadas do site pip . Adicione-os a uma matriz dependencies ao criar a instância QiskitFunction :

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)

Por fim, verifique se o upload do programa foi bem-sucedido, use serverless.list():

serverless.list()

Output:

 QiskitFunction(template_hamiltonian_simulation),


Execute o modelo de função remotamente

O modelo de função foi carregado, para que você possa executá-lo remotamente com o Qiskit Serverless. Primeiro, carregue o modelo pelo nome:

template = serverless.load("template_hamiltonian_simulation")

Em seguida, execute o modelo com as entradas em nível de domínio para a simulação hamiltoniana. Esse exemplo especifica um modelo XXZ de 50 qubits com acoplamentos aleatórios e um estado inicial e observável.

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

Verifique o status do trabalho:

job.status()

Output:

'QUEUED'

Depois que o trabalho estiver em execução, você poderá buscar os logs criados a partir das saídas do print() . Eles podem fornecer informações acionáveis sobre o progresso do fluxo de trabalho da simulação hamiltoniana. Por exemplo, o valor da função objetiva durante o componente iterativo do AQC ou a profundidade de dois qubits do circuito ISA final destinado à execução no hardware.

print(job.logs())

Output:

No logs yet.

Bloqueia o restante do programa até que um resultado esteja disponível. Depois que o trabalho for concluído, você poderá recuperar os resultados. Isso inclui o resultado em nível de domínio da simulação hamiltoniana (valor de expectativa) e metadados úteis.

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}

Depois que o trabalho for concluído, toda a saída de registro estará disponível.

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.


Próximas etapas

Recomendações

Para se aprofundar no complemento AQC-Tensor do Qiskit, confira o tutorial Improved Trotterized Time Evolution with Approximate Quantum Compilation ou o repositório qiskit-addon-aqc-tensor.

  • Aqui está todo o código-fonte do ./source_files/template_hamiltonian_simulation.py como um bloco de código.

    ./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)
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.