Spanish
Idiomas
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

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:

\[\begin{split}\mbox{CNOT} = \left(\begin{array} & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \end{array}\right), \quad \mbox{iSWAP} = \left(\begin{array} & 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0 \\ 0 & i & 0 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right)\end{split}\]
[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]:
../../_images/tutorials_simulators_4_custom_gate_noise_24_0.png

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]:
../../_images/tutorials_simulators_4_custom_gate_noise_26_0.png
[12]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
Qiskit0.25.0
Terra0.17.0
Aer0.8.0
Ignis0.6.0
Aqua0.9.0
IBM Q Provider0.12.2
System information
Python3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)]
OSDarwin
CPUs6
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.

[ ]: