Entradas e saídas do estimador
O código desta página foi desenvolvido com base nos seguintes requisitos. Recomendamos usar essas versões ou versões mais recentes.
qiskit[all]~=2.5.0 qiskit-ibm-runtime~=0.47.0
Esta página apresenta uma visão geral das entradas e saídas da primitiva Estimator do Qiskit Runtime, que executa cargas de trabalho nos recursos de computação d IBM Quantum®. O Estimator permite definir com eficiência cargas de trabalho vetorizadas utilizando uma estrutura de dados chamada Bloco Primitivo Unificado ( PUB ). Eles são utilizados como entradas para o run() método da primitiva Estimator, que executa a carga de trabalho definida como um trabalho. Então, após a conclusão do trabalho, os resultados são retornados em um formato que depende tanto dos PUBs utilizados quanto das opções de execução especificadas na primitiva.
Entradas
Cada PUB tem o seguinte formato:
(<single circuit>, <one or more observables>, <optional one or more parameter values>, <optional precision>),
O parâmetro opcional parameter values pode ser uma lista ou um único parâmetro. Os elementos das variáveis observáveis e os valores dos parâmetros são combinados seguindo as regras de difusã NumPy, conforme descrito no tópico “Entradas e saídas primitivas”, e é retornada uma estimativa do valor esperado para cada elemento da forma difundida.
Se a entrada contiver medidas, elas serão ignoradas.
Para a primitiva Estimator, um objeto PUB pode conter no máximo quatro valores:
- Um único elemento
QuantumCircuit, que pode conter um ou maisParameterobjetos - Uma lista de um ou mais observáveis, que especificam os valores esperados a serem estimados, organizados em uma matriz (por exemplo, um único observável representado como uma matriz de dimensão 0, uma lista de observáveis como uma matriz de dimensão 1 e assim por diante). Os dados podem estar em qualquer um dos
ObservablesArrayLikeformatos, comoPauli,SparsePauliOpPauliList,, oustr.Variáveis observáveis no trajeto diário- As variáveis observáveis de deslocamento no mesmo
PUBsão agrupadas por meio desse método. - Os parâmetros observáveis de deslocamento em diferentes PUBs, mesmo que tenham o mesmo circuito, não são estimados utilizando a mesma medição. Cada PUB representa uma base de mensuração diferente e, portanto, são necessárias mensurações separadas para cada PUB.
- Para garantir que as variáveis observáveis relacionadas ao deslocamento sejam estimadas utilizando a mesma medida, agrupe-as no mesmo
PUB.
- As variáveis observáveis de deslocamento no mesmo
- Um conjunto de valores de parâmetros aos quais o circuito deve ser vinculado. Isso pode ser especificado como um único objeto semelhante a uma matriz, em que o último índice corresponde aos objetos do
Parametercircuito ou pode ser omitido (ou, de forma equivalente, definido comoNone) caso o circuito nãoParameterpossua objetos. - (Opcionalmente) Uma precisão alvo para os valores esperados a serem estimados
O código a seguir mostra um exemplo de conjunto de entradas vetorizadas para a Estimator primitiva e as executa em um backend do tipo IBM® como um único RuntimeJobV2 objeto.
from qiskit.circuit import (
Parameter,
QuantumCircuit,
)
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import (
QiskitRuntimeService,
EstimatorV2 as Estimator,
)
import numpy as np
# Instantiate runtime service and get
# the least busy backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Define a circuit with two parameters.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.ry(Parameter("a"), 0)
circuit.rz(Parameter("b"), 0)
circuit.cx(0, 1)
circuit.h(0)
# Transpile the circuit
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
transpiled_circuit = pm.run(circuit)
layout = transpiled_circuit.layout
# Now define a sweep over parameter values, the last axis of dimension 2 is
# for the two parameters "a" and "b"
params = np.vstack(
[
np.linspace(-np.pi, np.pi, 100),
np.linspace(-4 * np.pi, 4 * np.pi, 100),
]
).T
# Define three observables. The inner length-1 lists cause this array of
# observables to have shape (3, 1), rather than shape (3,) if they were
# omitted.
observables = [
[SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
[SparsePauliOp("XX")],
[SparsePauliOp("IY")],
]
# Apply the same layout as the transpiled circuit.
observables = [
[observable.apply_layout(layout) for observable in observable_set]
for observable_set in observables
]
# Estimate the expectation value for all 300 combinations of observables
# and parameter values, where the pub result will have shape (3, 100).
#
# This shape is due to our array of parameter bindings having shape
# (100, 2), combined with our array of observables having shape (3, 1).
estimator_pub = (transpiled_circuit, observables, params)
# Instantiate the new Estimator object, then run the transpiled circuit
# using the set of parameters and observables.
estimator = Estimator(mode=backend)
job = estimator.run([estimator_pub])
result = job.result()Saídas
Depois que um ou mais PUBs são enviados a uma QPU para execução e um trabalho é concluído com sucesso, os dados são retornados como um objeto PrimitiveResult contêiner, acessado por meio da chamada ao RuntimeJobV2.result() método.
O PrimitiveResult contém uma lista iterável de PubResult objetos que contêm os resultados da execução de cada PUB.
Cada elemento desta lista corresponde a cada objeto PUB enviado ao método da run() primitiva (por exemplo, um trabalho enviado com 20 PUBs retornará um PrimitiveResult objeto que contém uma lista de 20 PubResult objetos, um correspondendo a cada objeto PUB).
Cada primitiva PubResult do Estimador contém, no mínimo, uma matriz de valores esperados (PubResult.data.evs) e desvios-padrão associados (seja PubResult.data.stds ou, PubResult.data.ensemble_standard_error dependendo do resilience_level utilizado), mas pode conter mais dados, dependendo das opções de mitigação de erros especificadas.
Cada PubResult objeto possui um atributo data e um metadata atributo.
- O
dataatributo é um campo personalizadoDataBinque contém os valores reais das medições, os desvios padrão e assim por diante. - O
DataBinpossui vários atributos, dependendo da forma ou estrutura doPUBassociado, bem como das opções de mitigação de erros especificadas pela primitiva usada para enviar o trabalho (por exemplo, ZNE ou PEC ). - O
metadataatributo contém informações sobre o tempo de execução e as opções de mitigação de erros utilizadas (explicadas mais adiante na seção “Metadados do resultado” desta página).
A seguir, apresentamos um esboço visual da estrutura PrimitiveResult de dados da saída do Estimador:
└── PrimitiveResult
├── PubResult[0]
│ ├── metadata
│ └── data ## In the form of a DataBin object
│ ├── evs
│ │ └── List of estimated expectation values in the shape
| | specified by the first pub
│ └── stds
│ └── List of calculated standard deviations in the
| same shape as above
├── PubResult[1]
| ├── metadata
| └── data ## In the form of a DataBin object
| ├── evs
| │ └── List of estimated expectation values in the shape
| | specified by the second pub
| └── stds
| └── List of calculated standard deviations in the
| same shape as above
├── ...
├── ...
└── ...
Em termos simples, uma única função retorna um PrimitiveResult objeto e contém uma lista de um ou mais PubResult objetos. Esses PubResult objetos armazenam, então, os dados de medição de cada PUB que foi enviado para a tarefa.
O trecho de código abaixo descreve o PrimitiveResult formato (e os associados PubResult) da tarefa criada acima.
print(
f"The result of the submitted job had {len(result)} "
f"PUBs and has a value:\n {result}\n"
)
print(
"The associated PubResult of this job has the following data bins:\n "
"{result[0].data}\n"
)
print(f"And this DataBin has attributes: {result[0].data.keys()}")
print(
"Recall that this shape is due to our array of parameter binding sets"
"having shape (100, 2), where 2 is the number of parameters in the "
"circuit, combined with our array of observables having shape (3, 1). \n"
)
with np.printoptions(threshold=200):
print(
"The expectation values measured from this PUB are: \n"
"{result[0].data.evs}\n"
)Output:
The result of the submitted job had 1 PUBs and has a value:
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 100), dtype=float64>), stds=np.ndarray(<shape=(3, 100), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 100), dtype=float64>), shape=(3, 100)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
The associated PubResult of this job has the following data bins:
{result[0].data}
And this DataBin has attributes: dict_keys(['evs', 'stds', 'ensemble_standard_error'])
Recall that this shape is due to our array of parameter binding setshaving shape (100, 2), where 2 is the number of parameters in the circuit, combined with our array of observables having shape (3, 1).
The expectation values measured from this PUB are:
{result[0].data.evs}
Como a primitiva Estimator calcula o erro
Além da estimativa da média das variáveis observáveis passadas nos PUBs de entrada (o evs campo do DataBin), o Estimador também tenta fornecer uma estimativa do erro associado a esses valores esperados. Todas as consultas ao Estimator preencherão o stds campo com uma quantidade semelhante ao erro-padrão da média para cada valor esperado, mas algumas opções de mitigação de erros fornecem informações adicionais, tais como ensemble_standard_error.
Considere um único observável . Na ausência de ZNE, pode-se considerar que cada iteração da execução do Estimador fornece uma estimativa pontual do valor esperado . Se as estimativas pontuais estiverem em um vetor Os, então o valor retornado em ensemble_standard_error é equivalente ao seguinte (em que é o desvio padrão da estimativa do valor esperado e é o número de iterações):
que trata todas as tomadas como parte de um único conjunto. Se você solicitou a rotação de portas (twirling.enable_gates = True), é possível classificar as estimativas pontuais de em conjuntos que compartilham uma rotação comum. Chamemos esses conjuntos de estimativas O_twirlsde, e há num_randomizations (número de voltas) deles. Então, stds é o erro-padrão da média de O_twirls, como em
onde é o desvio padrão de O_twirls e é o número de rotações. Quando você não habilita o efeito giratório, stds e ensemble_standard_error são iguais.
Se você ativar o ZNE, os parâmetros stds descritos acima passarão a ser pesos em uma regressão não linear para um modelo de extrapolação. O que acaba sendo retornado no stds neste caso é a incerteza do modelo ajustado, avaliada com um fator de ruído igual a zero. Quando o ajuste é inadequado ou há grande incerteza no ajuste, o valor relatado stds pode se tornar muito elevado. Quando o ZNE está ativado, pub_result.data.evs_noise_factors e pub_result.data.stds_noise_factors também são preenchidos, para que você possa fazer sua própria extrapolação.
Metadados do resultado
Além dos resultados da execução, tanto o objeto PrimitiveResult quanto PubResult o objeto contêm um atributo de metadados sobre o trabalho que foi enviado. Os metadados que contêm informações sobre todos os PUBs enviados (como as diversas opções de tempo de execução disponíveis) podem ser encontrados no PrimitiveResult.metatada, enquanto os metadados específicos de cada PUB se encontram no PubResult.metadata.
No campo de metadados, as implementações de primitivas podem retornar qualquer informação sobre a execução que seja relevante para elas, e não há pares chave-valor garantidos pela primitiva base. Portanto, os metadados retornados podem variar de acordo com as diferentes implementações das primitivas.
# Print out the results metadata
print("The metadata of the PrimitiveResult is:")
for key, val in result.metadata.items():
print(f"'{key}' : {val},")
print("\nThe metadata of the PubResult result is:")
for key, val in result[0].metadata.items():
print(f"'{key}' : {val},")Output:
The metadata of the PrimitiveResult is:
'dynamical_decoupling' : {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'},
'twirling' : {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'},
'resilience' : {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False},
'version' : 2,
The metadata of the PubResult result is:
'shots' : 4096,
'target_precision' : 0.015625,
'circuit_metadata' : {},
'resilience' : {},
'num_randomizations' : 32,