Nota
Esta página foi gerada a partir do tutorials/simulators/5_noise_transformation.ipynb.
Transformação de ruídos¶
Introdução¶
Este notebook mostra como utilizar as funções utilitárias approximate_quantum_error
e approximate_noise_model
do Qiskit Aer para transformar canais de ruído quântico em um canal de ruído diferente, mais adequado.
Our guiding example is Clifford simulation. A Clifford simulator can efficiently simulate quantum computations which include gates only from a limited, non-universal set of gates (the Clifford gates). Not all quantum noises can be added to such simulations; hence, we aim to find a «close» noise channel which can be simulated in a Clifford simulator.
Começamos importando as funções de transformação dos utilitários do provedor Aer
[1]:
from qiskit_aer.utils import approximate_quantum_error, approximate_noise_model
The name «approximate» suggests that these functions generate the closest (in the Hilbert-Schmidt metric) error possible to the given one.
Demonstramos a aproximação usando vários canais de erro padrão definidos no Qiskit.
[2]:
import numpy as np
# Import Aer QuantumError functions that will be used
from qiskit_aer.noise import amplitude_damping_error, reset_error, pauli_error
from qiskit.quantum_info import Kraus
Visão geral¶
Um canal quântico de 1 qubit é uma função \(\mathcal{C}:\mathbb{C}^{2\times2}\to\mathbb{C}^{2\times2}\) mapeando operadores de densidade para operadores de densidade (para garantir que a imagem é um operador de densidade, é necessário que \(\mathcal{C}\) seja completamente positivo e preserve o traço, CPTP).
Dados canais quânticos \(\mathcal{E}_{1},\dots,\mathcal{E}_{r}\), e probabilidades \(p_1, p_2, \dots, p_r\) tais que \(0\le p_i \le 1\) e \(p_1+\dots +p_r = 1\), um novo canal quântico \(\mathcal{C}_\mathcal{E}\) pode ser construído de tal forma que \(\mathcal{C}_\mathcal{E}(\rho)\) tem o efeito de escolher o canal \(\mathcal{E}_i\) com probabilidade \(p_i\) e aplicá-lo à \(\rho\).
The noise transformation function solves the following optimization problem: Given a channel \(\mathcal{C}\) («goal») and a list of channels \(\mathcal{E}_{1},\dots,\mathcal{E}_{r}\), find the probabilities \(p_1, p_2, \dots, p_r\) minimizing \(D(\mathcal{C}, \mathcal{C}_\mathcal{E})\) according to some distance metric \(D\) (the Hilbert-Schmidt metric is currently used).
To ensure the approximation is honest, in the sense that the approximate error channel serves as an «upper bound» for the actual error channel, we add the additional honesty constraint:
Onde \(\text{F}\) é uma medida de fidelidade e \(I\) é o canal identidade.
Exemplo: Aproximando o ruído de amortecimento de amplitude com ruído de reset.¶
Ruído de Amortecimento de Amplitude é descrito por um único parâmetro \(0\le \gamma \le 1\) e é dado pelos operadores de Kraus:
O erro de reset é descrito pelas probabilidades \(0\le p, q\le 1\) tais que \(p+q\le 1\) e é dado pelos operadores de Kraus:
This can be thought of as «resetting» the quantum state of the affected qubit to \(\left|0\right\rangle\) with probability \(p\), to \(\left|1\right\rangle\) with probability \(q\), and do nothing with probability \(1-(p+q)\).
Não é muito difícil determinar de forma analítica os melhores valores de \(p,q\) para aproximar um canal de amortecimento de amplitude \(\gamma\), veja os detalhes aqui. A melhor aproximação é:
[3]:
gamma = 0.23
error = amplitude_damping_error(gamma)
results = approximate_quantum_error(error, operator_string="reset")
Nós só precisávamos do código acima para realizar a aproximação real.
[4]:
print(results)
p = (1 + gamma - np.sqrt(1 - gamma)) / 2
q = 0
print("")
print("Expected results:")
print("P(0) = {}".format(1-(p+q)))
print("P(1) = {}".format(p))
print("P(2) = {}".format(q))
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.8237482193044617, Circuit =
┌───┐
q: ┤ I ├
└───┘
P(1) = 0.17625178069553835, Circuit =
q: ─|0>─
P(2) = 2.158685879252966e-23, Circuit =
┌───┐
q: ─|0>─┤ X ├
└───┘
Expected results:
P(0) = 0.8237482193696062
P(1) = 0.17625178063039387
P(2) = 0
Obtivemos os resultados previstos analiticamente.
Diferentes tipos de entrada¶
A função de aproximação recebe duas entradas: O canal de erro a ser aproximado, e um conjunto de canais de erro que podem ser usados na construção da aproximação.
O canal de erro a ser aproximado pode ser dado como qualquer entrada que possa ser convertida para o objeto QuantumError
.
Como um exemplo, construímos explicitamente as matrizes de Kraus de amortecimento de amplitude e passamos para a mesma função de aproximação de antes:
[5]:
gamma = 0.23
K0 = np.array([[1,0],[0,np.sqrt(1-gamma)]])
K1 = np.array([[0,np.sqrt(gamma)],[0,0]])
results = approximate_quantum_error(Kraus([K0, K1]), operator_string="reset")
print(results)
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.8237482193044623, Circuit =
┌───┐
q: ┤ I ├
└───┘
P(1) = 0.1762517806955376, Circuit =
q: ─|0>─
P(2) = 6.463899246563026e-23, Circuit =
┌───┐
q: ─|0>─┤ X ├
└───┘
Os operadores de erro que são usados para construir o canal de aproximação também podem ser fornecidos como uma lista, um dicionário ou uma string indicando canais codificados.
Any channel can be either a list of Kraus operators, or “QuantumError” objects.
O canal identidade não precisa ser passado diretamente; ele é sempre utilizado implicitamente.
Como um exemplo, nós aproximamos o amortecimento de amplitude usando uma representação explícita de Kraus para ruídos de reset:
[6]:
reset_to_0 = Kraus([np.array([[1,0],[0,0]]), np.array([[0,1],[0,0]])])
reset_to_1 = Kraus([np.array([[0,0],[1,0]]), np.array([[0,0],[0,1]])])
reset_kraus = [reset_to_0, reset_to_1]
gamma = 0.23
error = amplitude_damping_error(gamma)
results = approximate_quantum_error(error, operator_list=reset_kraus)
print(results)
QuantumError on 1 qubits. Noise circuits:
P(0) = 0.8237482193044617, Circuit =
┌───┐
q: ┤ I ├
└───┘
P(1) = 0.17625178069553835, Circuit =
┌───────┐
q: ┤ kraus ├
└───────┘
P(2) = 2.158685879252966e-23, Circuit =
┌───────┐
q: ┤ kraus ├
└───────┘
Observe a diferença no canal de saída: As probabilidades são as mesmas, mas os operadores de Kraus da entrada foram convertidos em canais de Kraus gerais, que não podem ser usados em um simulador de Clifford. Por isso, é sempre melhor passar um objeto QuantumError
em vez das matrizes de Kraus, quando possível.
[7]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.24.0.dev0+dba2eff |
qiskit-aer | 0.11.2 |
qiskit-ignis | 0.7.1 |
qiskit-ibmq-provider | 0.20.0 |
qiskit | 0.41.0 |
System information | |
Python version | 3.8.11 |
Python compiler | Clang 12.0.5 (clang-1205.0.22.11) |
Python build | default, Jul 27 2021 10:46:38 |
OS | Darwin |
CPUs | 8 |
Memory (Gb) | 64.0 |
Wed Feb 15 14:17:23 2023 JST |
This code is a part of Qiskit
© Copyright IBM 2017, 2023.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.
[ ]: