Nota
Esta página fue generada a partir de tutorials/simulators/4_custom_gate_noise.ipynb.
Aplicar ruido a compuertas unitarias personalizadas¶
Introducción¶
Este cuaderno muestra cómo añadir compuertas unitarias personalizadas a un circuito cuántico, y utilizarlas para simulaciones de ruido en Qiskit Aer.
[1]:
from qiskit import transpile, QuantumCircuit
import qiskit.quantum_info as qi
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel, amplitude_damping_error
from qiskit.tools.visualization import plot_histogram
Creación de operadores de matriz¶
Podemos utilizar la clase Operator
en qiskit.quantum_info
para representar operadores de matriz arbitrarios. Si el operador es unitario, entonces puede ser añadido a un circuito cuántico y utilizado para simulación en Qiskit Aer.
Vamos a crear dos operadores a continuación para una compuerta CNOT y una compuerta iSWAP:
[2]:
# CNOT matrix operator with qubit-0 as control and qubit-1 as target
cx_op = qi.Operator([[1, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0]])
# iSWAP matrix operator
iswap_op = qi.Operator([[1, 0, 0, 0],
[0, 0, 1j, 0],
[0, 1j, 0, 0],
[0, 0, 0, 1]])
Nota: La matriz está especificada con respecto al producto tensorial: \(U_{b}\otimes U_{a}\) para los qubits especificados por la lista [a, b]
.
Uso de operadores en circuitos¶
Vamos a demostrar cómo se pueden utilizar estos en un circuito. Consideraremos un ejemplo de implementación de una compuerta CNOT descompuesta en términos de compuertas de un solo qubit y la compuerta iSWAP de la siguiente manera.
[3]:
# CNOT in terms of iSWAP and single-qubit gates
cx_circ = QuantumCircuit(2, name='cx<iSWAP>')
# Add gates
cx_circ.sdg(1)
cx_circ.h(1)
cx_circ.sdg(0)
cx_circ.unitary(iswap_op, [0, 1], label='iswap')
cx_circ.sdg(0)
cx_circ.h(0)
cx_circ.sdg(0)
cx_circ.unitary(iswap_op, [0, 1], label='iswap')
cx_circ.s(1)
print(cx_circ)
┌─────┐ ┌────────┐┌─────┐┌───┐┌─────┐┌────────┐
q_0: ┤ SDG ├─────┤0 ├┤ SDG ├┤ H ├┤ SDG ├┤0 ├─────
├─────┤┌───┐│ iswap │└─────┘└───┘└─────┘│ iswap │┌───┐
q_1: ┤ SDG ├┤ H ├┤1 ├───────────────────┤1 ├┤ S ├
└─────┘└───┘└────────┘ └────────┘└───┘
Ten en cuenta que hemos asignado una etiqueta opcional de "iswap"
al unitario cuando es insertado. Esto nos permite identificar este unitario en un NoiseModel
de Qiskit Aer para que podamos añadir errores a estas compuertas unitarias personalizadas en simulaciones de circuito ruidosas.
Podemos confirmar que este circuito devuelve la salida correcta utilizando la clase Operator
como un simulador para el circuito:
[4]:
# Simulate the unitary for the circuit using Operator:
unitary = qi.Operator(cx_circ)
print(unitary)
Operator([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
Y para confirmar que la salida es correcta, podemos calcular la fidelidad promedio de la compuerta:
[5]:
f_ave = qi.average_gate_fidelity(cx_op, unitary)
print("Average Gate Fidelity: F = {:f}".format(f_ave))
Average Gate Fidelity: F = 1.000000
Creación de un unitario personalizado en un modelo de ruido¶
El AerSimulator
de Qiskit Aer admite la simulación de operadores unitarios arbitrarios directamente según lo especificado por la "unitary"
en las compuertas base.
[6]:
'unitary' in AerSimulator().configuration().basis_gates
[6]:
True
Esto nos permite añadir modelos de ruido a unitarios arbitrarios en nuestra simulación cuando los identificamos utilizando el argumento opcional label
de QuantumCircuit.unitary
.
Ahora haremos esto creando un NoiseModel
que incluye un canal de error cuántico en nuestra compuerta iSWAP personalizada. Para nuestro ejemplo crearemos un error de 2 qubits que consiste de dos canales de amortiguamiento de amplitud de un solo bit con diferentes parámetros de amortiguamiento. Por ahora supondremos que todas las otras instrucciones del circuito son ideales.
[7]:
# Error parameters
param_q0 = 0.05 # damping parameter for qubit-0
param_q1 = 0.1 # damping parameter for qubit-1
# Construct the error
qerror_q0 = amplitude_damping_error(param_q0)
qerror_q1 = amplitude_damping_error(param_q1)
iswap_error = qerror_q1.tensor(qerror_q0)
# Build the noise model by adding the error to the "iswap" gate
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(iswap_error, 'iswap')
Ten en cuenta que cuando añadimos un error a una etiqueta personalizada como "iswap"
, el NoiseModel
no sabe a qué compuerta se supone que va a aplicar esta etiqueta, así que debemos añadir manualmente la cadena de compuerta deseada al modelo de ruido basis_gates
. Esto asegura que el compilador se descompondrá a las compuertas base correctas para la simulación del modelo de ruido. Esto se puede hacer utilizando la función NoiseModel.add_basis_gates
:
[8]:
noise_model.add_basis_gates(['unitary'])
print(noise_model.basis_gates)
['cx', 'id', 'u3', 'unitary']
Por defecto, las compuertas base de un modelo de ruido son ['cx','id','u3']
más cualquier compuerta base estándar AerSimulator
que se agregue al modelo de ruido.
Simulación de un modelo de ruido unitario personalizado¶
Primero tomemos nuestro circuito CX anterior y agreguemos una compuerta Hadamard inicial y una medición final para crear un circuito de preparación de estado de Bell que podemos simular en el AerSimulator
tanto para el caso ideal como para el ruidoso:
[9]:
# Bell state circuit where iSWAPS should be inserted at barrier locations
bell_circ = QuantumCircuit(2, 2, name='bell')
bell_circ.h(0)
bell_circ.append(cx_circ, [0, 1])
bell_circ.measure([0,1], [0,1])
print(bell_circ)
┌───┐┌────────────┐┌─┐
q_0: ┤ H ├┤0 ├┤M├───
└───┘│ cx<iSWAP> │└╥┘┌─┐
q_1: ─────┤1 ├─╫─┤M├
└────────────┘ ║ └╥┘
c: 2/════════════════════╩══╩═
0 1
Salida ideal¶
Primero veamos la salida ideal. Dado que esto genera un estado de Bell, esperamos dos picos para 00 y 11.
[10]:
# Create ideal simulator backend and transpile circuit
sim_ideal = AerSimulator()
tbell_circ = transpile(bell_circ, sim_ideal)
ideal_result = sim_ideal.run(tbell_circ).result()
ideal_counts = ideal_result.get_counts(0)
plot_histogram(ideal_counts,
title='Ideal output for iSWAP bell-state preparation')
[10]:

Ejecución del circuito ruidoso¶
Finalmente, vamos ahora a simularlo con nuestro modelo de ruido personalizado. Dado que hay un pequeño error de amortiguamiento de amplitud en las compuertas de dos qubits, esperamos pequeños picos adicionales para las probabilidades de salida 01 y 10.
[11]:
# Create noisy simulator and transpile circuit
sim_noise = AerSimulator(noise_model=noise_model)
tbell_circ_noise = transpile(bell_circ, sim_noise)
# Run on the simulator without noise
noise_result = sim_noise.run(tbell_circ_noise).result()
noise_counts = noise_result.get_counts(bell_circ)
plot_histogram(noise_counts,
title='Noisy output for iSWAP bell-state preparation')
[11]:

[12]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.25.0 |
Terra | 0.17.0 |
Aer | 0.8.0 |
Ignis | 0.6.0 |
Aqua | 0.9.0 |
IBM Q Provider | 0.12.2 |
System information | |
Python | 3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)] |
OS | Darwin |
CPUs | 6 |
Memory (Gb) | 32.0 |
Fri Apr 02 12:12:41 2021 EDT |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
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.
[ ]: