Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit 0.33


0.33.1

Terra 0.19.1

Preludio

Qiskit Terra 0.19.1 es una versión de corrección de errores, solucionando algunos problemas en 0.19.0 relativos a circuitos construidos por la interfaz del constructor de flujo de control, puertas condicionales y serialización QPY de objetos Terra más recientes.

Notas sobre características en desuso

  • Las funciones sueltas qiskit.circuit.measure.measure() y qiskit.circuit.reset.reset() están obsoletas y se eliminarán en una futura versión. En su lugar, debe acceder a ellos como métodos en QuantumCircuit:

    from qiskit import QuantumCircuit
    circuit = QuantumCircuit(1, 1)
    
    # Replace this deprecated form ...
    from qiskit.circuit.measure import measure
    measure(circuit, 0, 0)
    
    # ... with either of the next two lines:
    circuit.measure(0, 0)
    QuantumCircuit.measure(circuit, 0, 0)

Corrección de errores

  • Corregido un error en las funciones de conversión de circuitos circuit_to_gate() y circuit_to_instruction() (y sus métodos de circuito asociados QuantumCircuit.to_gate() y QuantumCircuit.to_instruction()) al actuar sobre un circuito con bits sin registro, o bits en más de un registro. Anteriormente, el número de bits necesarios para la puerta o instrucción creada se calculaba incorrectamente, lo que a menudo provocaba una excepción durante la conversión.

  • Se ha corregido un problema por el que llamar a QuantumCircuit.copy() en los circuitos "body" de una operación de flujo de control creada con la interfaz del constructor provocaba un error. Por ejemplo, esto antes era un error, pero ahora volverá con éxito:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.if_test((creg, 0)):
        circ.h(0)
    
    if_else_instruction, _, _ = circ.data[0]
    true_body = if_else_instruction.params[0]
    true_body.copy()
  • La interfaz del constructor de flujo de control ahora admite el uso de ClassicalRegistercomo condiciones en ámbitos de flujo de control anidados. Anteriormente, al hacer esto no se producía un error inmediato, pero los bloques del circuito interno no tenían definidos los registros correctos, por lo que la lógica posterior que trabajaba con los bloques internos fallaba.

    Por ejemplo, antes los cajones fallaban al intentar dibujar un bloque interior condicionado a un registro clásico, mientras que ahora lo conseguirán, como en este ejemplo:

    from qiskit import QuantumCircuit
    from qiskit.circuit import QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.for_loop(range(10)) as a:
        circ.ry(a, 0)
        with circ.if_test((creg, 1)):
            circ.break_loop()
    
    print(circ.draw(cregbundle=False))
    print(circ.data[0][0].blocks[0].draw(cregbundle=False))
  • Corregido el soporte de qpy_serialization para serializar QuantumCircuit que utilizan ParameterVector o ParameterVectorElement como parámetros. Anteriormente, un parámetro ParameterVectorElement se trataba simplemente como un parámetro Parameter para la serialización QPY, lo que significaba que el contexto ParameterVector se perdía en QPY y el orden de salida de parameters podía ser incorrecto.

    Para solucionar este problema ha sido necesaria una nueva versión del formato QPY, la versión 3. Esta nueva versión del formato incluye una representación de la clase ParameterVectorElement que se describe en la documentación de qpy_serialization en PARAMETER_VECTOR_ELEMENT.

  • Corregido el soporte de qpy_serialization para serializar un PauliEvolutionGate objeto. Anteriormente, el PauliEvolutionGate se trataba como una puerta personalizada para la serialización y se deserializaba como un objeto Gate que tenía la misma definición y el mismo nombre que el objeto original PauliEvolutionGate. Sin embargo, esto perdería el estado original del PauliEvolutionGate. Esto se ha corregido de modo que a partir de esta versión a PauliEvolutionGate en el circuito se conservará 1:1 a través de la serialización QPY ahora. La única limitación es que no admite clases personalizadas EvolutionSynthesis personalizadas. Sólo las clases disponibles en qiskit.synthesis pueden ser usadas con PauliEvolutionGate para la serialización qpy.

    Para solucionar este problema ha sido necesaria una nueva versión del formato QPY, la versión 3. Esta nueva versión del formato incluye una representación de la PauliEvolutionGate que se describe en la documentación de qpy_serialization en PAULI_EVOLUTION.

  • Dos funciones sueltas qiskit.circuit.measure.measure() y qiskit.circuit.reset.reset() fueron eliminadas accidentalmente sin un periodo de depreciación. Se han restablecido, pero están marcados como obsoletos en favor de los métodos QuantumCircuit.measure() y QuantumCircuit.reset()respectivamente, y se eliminarán en una futura versión.

Otras notas

  • La nueva interfaz del constructor de flujo de control utiliza varios gestores de contexto y objetos de ayuda para realizar su trabajo. No deben considerarse parte de la API pública y pueden modificarse o eliminarse sin previo aviso. El uso de la interfaz del constructor tiene garantías de estabilidad, en el sentido de que el comportamiento descrito por QuantumCircuit.for_loop(), while_loop() y if_test() para la interfaz del constructor están sujetos a las políticas de depreciación estándar, pero los objetos reales utilizados para llevarlo a cabo no lo están. No debe confiar en que los objetos (como IfContext o ControlFlowBuilderBlock) existan en sus ubicaciones actuales o tengan métodos o atributos asociados a ellos.

    Esto no estaba claro en la versión de 0.19.0. Todos estos objetos tienen ahora una advertencia en sus cadenas de documentación que lo hace explícito. Es probable que en el futuro sus ubicaciones y aplicaciones de respaldo sean muy diferentes.

Aer 0.9.1

No cambia

Ignis 0.7.0

No cambia

IBM Proveedor Q 0.18.2

Corrección de errores

  • Arreglo entregado en #1065 para el problema donde el trabajo seguía fallando cuando Parameter era pasado en los metadatos del circuito.
  • Fix entregado en #1094 para el problema en el que qiskit.providers.ibmq.runtime.RuntimeEncoder hace un extra decompose() si el circuito que se serializa es un BlueprintCircuit.

0.33.0

Esta versión marca oficialmente el fin del soporte del proyecto Qiskit Aqua en Qiskit. Originalmente fue obsoleto en la versión 0.25.0 y, como se documentó en esa versión, el paquete qiskit-aqua se ha eliminado del metapaquete Qiskit, lo que significa que pip install qiskit ya no incluirá qiskit-aqua. Sin embargo, debido a limitaciones en el empaquetado de python, no podemos eliminar automáticamente una instalación preexistente de qiskit-aqua al actualizar una versión anterior de Qiskit a esta versión (o a una futura) con pip install -U qiskit. Si está actualizando desde una versión anterior se recomienda que desinstale manualmente Qiskit Aqua con pip uninstall qiskit-aqua o instalar en un entorno python fresco.

Los módulos de aplicación que proporcionaba qiskit-aqua se han dividido en varios paquetes nuevos: qiskit-optimization, qiskit-nature, qiskit-machine-learning, y qiskit-finance. Estos paquetes pueden instalarse por sí mismos (mediante el comando estándar pip install, por ejemplo pip install qiskit-nature) o con el resto del metapaquete Qiskit como extras opcionales (p. ej. pip install 'qiskit[finance,optimization]' o pip install 'qiskit[all]'). Los algoritmos centrales y el flujo de operadores ya forman parte de Qiskit Terra en qiskit.algorithms y qiskit.opflow. Dependiendo del uso que hagas de Aqua, deberás utilizar los paquetes de la aplicación o los nuevos módulos de Qiskit Terra. Para más detalles sobre cómo migrar desde Qiskit Aqua puedes consultar la Guía de migración a Aqua.

Esta versión también deja oficialmente obsoleto el proyecto Qiskit Ignis. En consecuencia, en una futura versión el paquete qiskit-ignis se eliminará del metapaquete Qiskit, lo que significa que en esa futura versión pip install qiskit ya no incluirá qiskit-ignis. Qiskit Ignis ha sido sustituido por el proyecto Qiskit Experiments y el desarrollo activo ha cesado. A pesar de estar obsoleto, se seguirán realizando correcciones de errores críticos y correcciones de compatibilidad para proporcionar a los usuarios una oportunidad suficiente para migrar fuera de Ignis. Una vez transcurrido el periodo de obsoleto (que no será inferior a 3 meses a partir de esta versión), el proyecto se retirará y archivará. Puedes consultar la guía de migración para más detalles sobre cómo cambiar de Qiskit Ignis a Qiskit Experiments.

Terra 0.19.0

Preludio

Los aspectos más destacados del lanzamiento de Qiskit Terra 0.19 son:

  • Una nueva versión de la interfaz abstracta Qiskit/hardware, en forma de BackendV2que incluye una nueva estructura de datos Target para permitir a los backends modelar mejor sus restricciones para el transpilador.
  • Una interfaz de plugin extensible para el UnitarySynthesis transpiler pass, permitiendo a los usuarios u otros paquetes extender las rutinas de síntesis de Qiskit Terra con nuevos métodos.
  • Instrucciones de flujo de control, para representar los bucles for y while y las sentencias if/else en QuantumCircuit. Los simuladores de Qiskit Aer pronto podrán trabajar con estas nuevas instrucciones, lo que permitirá escribir programas cuánticos más dinámicos.
  • Soporte preliminar para la especificación OpenQASM 3 en evolución. Puede utilizar el nuevo módulo qiskit.qasm3 para serializar sus QuantumCircuits en OpenQASM 3, incluidas las nuevas construcciones de flujo de control.

Esta versión marca el fin de la compatibilidad con Python 3.6 en Qiskit. Esta versión de Qiskit Terra, y las posteriores versiones de corrección de errores de la serie 0.19.x, serán las últimas que funcionen con Python 3.6. A partir de la próxima versión menor ( 0.20.0 ) de Qiskit Terra, la versión mínima requerida de Python será 3.7.

Como siempre, hay muchas más funciones y correcciones en esta versión, que puedes consultar a continuación.

Nuevas funciones

  • QuantumCircuit.decompose() y su correspondiente pase de transpilador Decompose aceptan ahora opcionalmente un parámetro que contiene una colección de nombres de puertas. Si se indica este parámetro, sólo se descompondrán las puertas cuyos nombres coincidan. Admite coincidencias con comodines al estilo Unix-shell. Por ejemplo:

    qc.decompose(["h", "r[xz]"])

    descompondrá cualquier puerta h, rx o rz , pero dejará (por ejemplo) las puertas x intactas.

  • Se ha añadido el argumento termination_checker al SPSA optimizador. Esto permite al usuario implementar un criterio de terminación personalizado.

    import numpy as np
    from qiskit.algorithms.optimizers import SPSA
    
    def objective(x):
        return np.linalg.norm(x) + .04*np.random.rand(1)
    
    class TerminationChecker:
    
        def __init__(self, N : int):
            """
            Callback to terminate optimization when the average decrease over
            the last N data points is smaller than the specified tolerance.
            """
            self.N = N
            self.values = []
    
        def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool:
            """
            Returns:
                True if the optimization loop should be terminated.
            """
            self.values.append(value)
    
            if len(self.values) > self.N:
                last_values = self.values[-self.N:]
                pp = np.polyfit(range(self.N), last_values, 1)
                slope = pp[0] / self.N
    
                if slope > 0:
                    return True
            return False
    
    maxiter = 400
    spsa = SPSA(maxiter=maxiter, termination_checker=TerminationChecker(10))
    parameters, value, niter = spsa.optimize(2, objective, initial_point=np.array([0.5, 0.5]))
  • Se ha añadido una nueva versión de la Backend interfaz, BackendV2. Esta nueva versión supone un gran cambio con respecto a la anterior, BackendV1 y cambia tanto el patrón de acceso del usuario a las propiedades del backend (como el número de qubits, etc) como la forma en que el backend representa sus restricciones al transpilador. La ejecución de los circuitos (a través del run() método) permanece inalterada. Con un BackendV2 backend en lugar de tener un configuration(), properties()y defaults() métodos que construyen BackendConfiguration, BackendPropertiesy PulseDefaults respectivamente, como en la interfaz BackendV1 los atributos contenidos en esos objetos de salida son accesibles directamente como atributos del objeto BackendV2 objeto. Por ejemplo, para obtener el número de qubits de un backend con BackendV1 deberías hacer:

    num_qubits = backend.configuration().n_qubits

    mientras que con BackendV2 lo es:

    num_qubits = backend.num_qubits

    El otro cambio es que el número de atributos expuestos en la clase abstracta BackendV2 está diseñado para ser un conjunto agnóstico de hardware/proveedor de los campos obligatorios u opcionales que el resto de Qiskit puede utilizar hoy en día con cualquier backend. Las subclases de la clase abstracta BackendV2 pueden añadir soporte para atributos y métodos adicionales más allá de los definidos en BackendV2pero estos no serán soportados universalmente en todo Qiskit.

    El otro cambio crítico que es principalmente importante para los autores de proveedores es cómo un BackendV2 expone las propiedades de un backend concreto al transpilador. En BackendV2 esto se hace mediante un Target objeto. La dirección Targetque se expone a través del atributo target se utiliza para representar el conjunto de restricciones para la ejecución de circuitos en un backend concreto. Contiene el subconjunto de información previamente expuesto por el BackendConfiguration, BackendPropertiesy PulseDefaults que el transpilador puede utilizar activamente. Al migrar un proveedor para utilizar BackendV2 (o al crear un nuevo paquete de proveedores) la construcción de objetos backend girará principalmente en torno a la creación de un objeto Target para el backend.

  • Se ha añadido una nueva clase Target al módulo transpiler módulo. La clase Target está diseñada para representar las restricciones del backend ante el compilador. La clase Target está pensada para ser utilizada con un BackendV2 y es la forma en que los backends modelarán sus restricciones para el transpilador en el futuro. Combina los campos anteriormente distintos utilizados para controlar el transpile() dispositivo de destino (por ejemplo, basis_gates, coupling_map, instruction_durations, etc.) en una única estructura de datos. También añade funciones adicionales a las disponibles anteriormente, como la representación de conjuntos de compuertas heterogéneos, la conectividad de compuertas multiqubit y las variantes sintonizadas de las mismas compuertas. En la actualidad, el transpilador no tiene en cuenta todas estas limitaciones, pero con el tiempo irá aprovechando las funciones adicionales.

  • La clase Options tiene ahora soporte opcional para especificar validadores. Esto permite Backend a los autores especificar opcionalmente una validación básica de los valores proporcionados por el usuario para los campos del objeto Options objeto. Por ejemplo, si tuviera un objeto Options definido con:

    from qiskit.providers.Options
    options = Options(shots=1024)

    puedes establecer un validador en las tomas para que esté entre 1 y 4096 con:

    options.set_validator('shots', (1, 4096))

    Con el validador activado, cualquier llamada al método update_options() comprobará que, si se está actualizando shots , el nuevo valor propuesto se encuentra dentro del intervalo válido.

  • Añadido un nuevo pase de análisis del transpilador ContainsInstructional módulo qiskit.transpiler.passes módulo. Esta pasada se utiliza para determinar si un circuito contiene una instrucción específica. Toma un único parámetro en la inicialización, el nombre de la instrucción a comprobar y establece un booleano en el conjunto de propiedades si el circuito contiene esa instrucción o no. Por ejemplo:

    from qiskit.transpiler.passes import ContainsInstruction
    from qiskit.circuit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    
    property_set = {}
    # Contains Hadamard
    contains_h = ContainsInstruction("h")
    contains_h(circuit, property_set)
    assert property_set["contains_h"] == True
    # Not contains SX
    contains_sx = ContainsInstruction("sx")
    contains_sx(circuit, property_set)
    assert property_set["contains_sx"] == False
  • Se ha añadido una función de utilidad qiskit.utils.detach_prefix() que es una contrapartida de apply_prefix(). La nueva función devuelve una tupla de valor escalado y prefijo a partir de un valor float dado. Por ejemplo, un valor 1.3e8 se convertirá en (130, "M") que puede utilizarse para mostrar un valor en el formato fácil de usar, como 130 MHz.

  • Los valores "gate_error" y "balanced" están ahora disponibles para la opción objective en la construcción del objeto BIPMapping , y "balanced" es ahora el valor por defecto.

    El objetivo "gate_error" requiere pasar una BackendProperties instancia en el kwarg backend_prop , que contiene los errores de puerta 2q-gate utilizados en el cálculo de los objetivos. El objetivo "balanced" utilizará la instancia BackendProperties instancia si se da, pero en caso contrario asumirá una tasa de error CX como se da en el nuevo parámetro default_cx_error_rate. Los pesos relativos de los componentes de error de puerta y profundidad del objetivo equilibrado pueden controlarse con el nuevo parámetro depth_obj_weight .

  • Todos los atributos de la clase VQE que se establece en la inicialización es ahora accesible con getters y setters. Además, los valores por defecto de los atributos VQE ansatz y optimizer pueden restablecerse asignándoles None :

    vqe = VQE(my_ansatz, my_optimizer)
    vqe.ansatz = None   # reset to default: RealAmplitudes ansatz
    vqe.optimizer = None  # reset to default: SLSQP optimizer
  • Añadido un nuevo método PauliList.group_qubit_wise_commuting() que divide a PauliList en conjuntos de operadores mutuamente conmutables qubit-sabios Pauli mutuamente. Por ejemplo:

    from qiskit.quantum_info import PauliList, Pauli
    pauli_list = PauliList([Pauli("IY"), Pauli("XX"), Pauli("YY"), Pauli("YX")])
    pauli_list.group_qubit_wise_commuting()
  • Añadido un nuevo método constructor de mapa de acoplamiento CouplingMap.from_hexagonal_lattice() para construir un mapa de acoplamiento de red hexagonal. Por ejemplo, para construir un mapa de acoplamiento de la red hexagonal 2x2 :

    from qiskit.transpiler import CouplingMap
    cmap = CouplingMap.from_hexagonal_lattice(2, 2)
    cmap.draw()
  • Las nuevas clases de backend falso están disponibles en qiskit.test.mock. Se trata de versiones simuladas de ibmq_brooklyn, ibmq_manila, ibmq_jakarta y ibmq_lagos. Al igual que los demás backends falsos, éstos incluyen instantáneas de los datos de calibración (es decir, backend.defaults()) y los datos de error (es decir, backend.properties()) tomados del sistema real, y pueden utilizarse para pruebas locales, compilación y simulación.

  • Se ha añadido el método OperatorBase.is_hermitian() para comprobar si el operador es hermitiano o no. NumPyEigensolver y NumPyMinimumEigensolver utilizar eigh o eigsh para resolver el problema de valores propios cuando el operador es hermitiano.

  • Añadido un nuevo método constructor PassManagerConfig.from_backend(). Construye un PassManagerConfig objeto con las opciones del usuario y la configuración de un backend. Esta función facilita la creación de un gestor de pases predefinido. Por ejemplo:

    from qiskit.transpiler.passmanager_config import PassManagerConfig
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.test.mock import FakeMelbourne
    
    pass_manager = level_1_pass_manager(
      PassManagerConfig.from_backend(FakeMelbourne(), seed_transpiler=42)
    )
  • Se ha añadido un nuevo transpiler pass, PulseGatesque extrae automáticamente las calibraciones proporcionadas por el usuario del mapa de programación de instrucciones y adjunta la programación de puertas al circuito cuántico dado (transpilado) como una puerta de impulsos.

    El PulseGates se aplica a todos los niveles de optimización de 0 a 3. No se actualiza ninguna implementación de puerta a menos que el usuario final anule explícitamente la backend.defaults().instruction_schedule_map. Este pase ahorra a los usuarios tener que llamar individualmente QuantumCircuit.add_calibration() para cada circuito que se ejecuta en el hardware.

    Para complementar este nuevo pase, se añadió un horario a InstructionScheduleMap y se actualiza implícitamente con un campo de metadatos "publisher". Las programaciones de puertas calibradas por el backend tienen un tipo de editor especial para evitar anular circuitos con calibraciones de programaciones ya conocidas. Normalmente, los usuarios finales no necesitan ocuparse de estos metadatos, ya que se aplican automáticamente. Puede llamar a InstructionScheduleMap.has_custom_gate() para comprobar si el mapa tiene calibración de puerta personalizada.

    Vea el siguiente ejemplo de código para aprender a aplicar la implementación de compuertas personalizadas para todos los circuitos en ejecución.

    from qiskit.test.mock import FakeGuadalupe
    from qiskit import pulse, circuit, transpile
    
    backend = FakeGuadalupe()
    
    with pulse.build(backend, name="x") as x_q0:
        pulse.play(pulse.Constant(160, 0.1), pulse.drive_channel(0))
    
    backend.defaults().instruction_schedule_map.add("x", (0,), x_q0)
    
    circs = []
    for _ in range(100):
        circ = circuit.QuantumCircuit(1)
        circ.sx(0)
        circ.rz(1.57, 0)
        circ.x(0)
        circ.measure_active()
        circs.append(circ)
    
    circs = transpile(circs, backend)
    circs[0].calibrations  # This returns calibration only for x gate

    Tenga en cuenta que el mapa de programación de instrucciones es un objeto mutable. Si anula una de las entradas y utiliza ese backend para otros experimentos, puede actualizar accidentalmente la definición de la puerta.

    backend = FakeGuadalupe()
    
    instmap = backend.defaults().instruction_schedule_map
    instmap.add("x", (0, ), my_x_gate_schedule)
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0, 0)
    
    qc = transpile(qc, backend)  # This backend uses custom X gate

    Si quieres actualizar las definiciones de puerta de un experimento específico, primero tienes que hacer un deepcopy del mapa de programación de instrucciones y pasarlo directamente al transpilador.

  • Se ha introducido una nueva opción qubit_subset en el constructor de BIPMapping. La opción nos permite especificar en una línea los qubits físicos que se utilizarán (en coupling_map del dispositivo) durante el mapeo:

    mapped_circ = BIPMapping(
        coupling_map=CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]),
        qubit_subset=[1, 3, 4]
    )(circ)

    Antes, para hacer lo mismo, teníamos que suministrar un coupling_map reducido que contuviera sólo los qubits que se iban a utilizar, incrustar el circuito resultante en el coupling_map original y actualizar el QuantumCircuit._layout en consecuencia:

    reduced_coupling = coupling_map.reduce(qubit_to_use)
    mapped = BIPMapping(reduced_coupling)(circ)
    # skip the definition of fill_with_ancilla()
    # recover circuit on original coupling map
    layout = Layout({q: qubit_to_use[i] for i, q in enumerate(mapped.qubits)})
    for reg in mapped.qregs:
        layout.add_register(reg)
    property_set = {"layout": fill_with_ancilla(layout)}
    recovered = ApplyLayout()(mapped, property_set)
    # recover layout
    overall_layout = Layout({v: qubit_to_use[q] for v, q in mapped._layout.get_virtual_bits().items()})
    for reg in mapped.qregs:
        overall_layout.add_register(reg)
    recovered._layout = fill_with_ancilla(overall_layout)
  • Añadidos los argumentos ignore_pauli_phase y copy al constructor de SparsePauliOp. ignore_pauli_phase evita que se lea el atributo phase de una entrada PauliList lo que es más eficaz si se sabe que el atributo PauliList ya se sabe que tiene todas las fases como cero en la convención interna ZX. copy permite a los usuarios evitar la copia de los datos de entrada cuando establecen explícitamente copy=False.

  • Mejora del rendimiento de las siguientes SparsePauliOp operaciones:

  • Se ha añadido el método SparsePauliOp.sum() para sumar muchos SparsePauliOps. Este método tiene un rendimiento significativamente mejor que sumar las instancias en un bucle. Por ejemplo, la forma anterior de sumar varios SparsePauliOps juntos sería hacer

    from qiskit.quantum_info import SparsePauliOp, random_pauli_list
    sparse_ops = [SparsePauliOp(random_pauli_list(10, 10)) for _ in [None]*1000]
    
    total = sparse_ops[0]
    for op in sparse_ops[1:]:
        total += op

    Ahora puede hacerse de forma mucho más eficaz (tanto en velocidad como en mecanografía) como:

    SparsePauliOp.sum(sparse_ops)
  • Añadido un argumento limit_amplitude al constructor de ParametricPulse, que es la clase base de Gaussian, GaussianSquare, Drag y Constantpara permitir desactivar el límite de amplitud de 1 pulso a pulso. Con limit_amplitude=False, los impulsos individuales pueden tener una amplitud superior a la unidad sin elevar un PulseError. Véase #6544 para más detalles.

  • Utilizando QuantumCircuit.draw() o circuit_drawer() con el cajón latex generará ahora un archivo en un formato de imagen inferido de la extensión del nombre del archivo, por ejemplo:

    import qiskit
    
    circuit = qiskit.QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.draw('latex', filename='./file.jpg')

    Esto guardará el dibujo del circuito en formato JPEG. Antes, la imagen siempre estaba en formato PNG. Consulte el nº 6448 para más detalles.

    Ahora, si encuentra una extensión de nombre de archivo que no es compatible, por ejemplo:

    circuit.draw('latex', filename='./file.spooky')

    lanzará un mensaje ValueError para cambiar la extensión del nombre de archivo a un formato de imagen compatible.

  • Se ha añadido el parámetro filename a plot_gate_map() y plot_coupling_map()que permite guardar las imágenes resultantes en un archivo.

  • Se ha introducido un compilador cuántico aproximado y la correspondiente implementación de un plugin de síntesis unitaria. La clase principal de AQC es AQC para una versión independiente que compila una matriz unitaria en un circuito aproximado. El complemento puede invocarse mediante transpile() cuando el argumento unitary_synthesis_method se establece en 'aqc'. Consulte qiskit.transpiler.synthesis.aqc para más información.

  • Se ha añadido un argumento filter_function a QuantumCircuit.depth() y QuantumCircuit.size() para analizar las operaciones del circuito según algunos criterios.

    Por ejemplo, para obtener el número de puertas de dos qubits, puedes hacer:

    circuit.size(lambda x: x[0].num_qubits == 2)

    O para obtener la profundidad de las puertas T que actúan sobre el qubit zeroth:

    circuit.depth(lambda x: x[0].name == 't' and circuit.qubits[0] in x[1])
  • Añadido un nuevo pase de transpilador CollectMultiQBlocksal módulo qiskit.transpiler.passes módulo. Este paso se utiliza para recoger secuencias de puertas ininterrumpidas que actúan sobre grupos de qubits. Ofrece una función similar a la del Collect2qBlocks existente, pero mientras que ese pase está diseñado y optimizado para encontrar bloques de 2 qubits, este nuevo pase funcionará para encontrar bloques de cualquier tamaño.

  • Existe una interfaz de construcción para las nuevas operaciones de flujo de control en QuantumCircuitcomo el nuevo ForLoopOp, IfElseOpy WhileLoopOp. La interfaz utiliza los mismos métodos de circuito, es decir QuantumCircuit.for_loop(), QuantumCircuit.if_test() y QuantumCircuit.while_loop()que están sobrecargados de modo que si no se proporciona el parámetro body , devuelven un gestor de contexto. Al entrar en uno de estos gestores de contexto, se introduce un ámbito en el circuito y se capturan todas las llamadas a puertas (y otros ámbitos) y los recursos que utilizan, y se construye la operación correspondiente al final. Por ejemplo, ahora puedes hacer:

    qc = QuantumCircuit(2, 2)
    with qc.for_loop(range(5)) as i:
        qc.rx(i * math.pi / 4, 0)

    Esto producirá un ForLoopOp en qc, que sabe que el qubit 0 es el único recurso utilizado dentro del cuerpo del bucle. Estos gestores de contexto pueden anidarse y determinarán correctamente su anchura. Puede utilizar QuantumCircuit.break_loop() y QuantumCircuit.continue_loop() dentro de un contexto, y se expandirá para tener el ancho correcto para el bucle que lo contiene, incluso si está anidado en más bloques QuantumCircuit.if_test() bloques.

    El gestor de contexto if_test() gestor de contexto proporciona un gestor encadenado que, si se desea, puede utilizarse para crear un bloque else , como por:

    qreg = QuantumRegister(2)
    creg = ClassicalRegister(2)
    qc = QuantumCircuit(qreg, creg)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
    with qc.if_test((creg, 0)) as else_:
        qc.x(1)
    with else_:
        qc.z(1)

    El gestor se asegurará de que los organismos if y else se definan sobre el mismo conjunto de recursos.

  • Introducido un nuevo transpiler pass InverseCancellation que generaliza el pase CXCancellation para cancelar cualquier puerta auto-inversa o pares puerta-inversa. Se puede utilizar inicializando InverseCancellation y pasando una puerta para cancelar, por ejemplo:

    from qiskit.transpiler.passes import InverseCancellation
    from qiskit import QuantumCircuit
    from qiskit.circuit.library import HGate
    from qiskit.transpiler import PassManager
    
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.h(0)
    pass_ = InverseCancellation([HGate()])
    pm = PassManager(pass_)
    new_circ = pm.run(qc)
  • El constructor de RZXCalibrationBuilder tiene dos nuevos kwargs instruction_schedule_map y qubit_channel_mapping que toman un InstructionScheduleMap y una lista de nombres de canal para cada qubit respectivamente. Estos nuevos argumentos se utilizan para especificar directamente la información necesaria de un objetivo backend. Deben utilizarse en lugar de pasar un BaseBackend u BackendV1 directamente al pase con el argumento backend .

  • Los Statevectors de estados compuestos únicamente por qubits pueden dibujarse ahora en LaTeX en notación ket. En la notación ket, las entradas del vector de estado se procesan de forma que los factores exactos, como fracciones o raíces cuadradas de dos, se dibujan como tales. La convención concreta puede elegirse pasando el argumento de la palabra clave convention como "ket" o "vector" , según proceda:

    import math
    from qiskit.quantum_info import Statevector
    
    sv = Statevector([math.sqrt(0.5), 0, 0, -math.sqrt(0.5)])
    sv.draw("latex", convention="ket")
    sv.draw("latex", convention="vector")
  • Añadido un nuevo transpiler pass EchoRZXWeylDecomposition que permite a los usuarios descomponer una puerta arbitraria de dos qubits en términos de puertas RZX con eco aprovechando la descomposición de Cartan. En combinación con otros pases del transpilador, esto se puede utilizar para transpilar circuitos arbitrarios a circuitos basados en puertas RZX y eficientes en pulsos que implementan el mismo unitario.

  • En SPSA y QNSPSA son ahora capaces de agrupar por lotes tantas evaluaciones de circuito como sea posible, tanto para las iteraciones como para las calibraciones iniciales. Esto puede aprovecharse estableciendo el kwarg max_evals_grouped en el constructor de VQE cuando se utiliza SPSA o QNSPSA como parámetro de optimizer . Por ejemplo:

    from qiskit.circuit.library import TwoLocal
    from qiskit.algorithms import VQE
    from qiskit.algorithms.optimizers import QNSPSA
    from qiskit.test.mock import FakeMontreal
    
    backend = FakeMontreal()
    ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    qnspsa = QNSPSA(fidelity, maxiter=5)
    vqe = VQE(
        ansatz=ansatz,
        optimizer=qnspsa,
        max_evals_grouped=100,
        quantum_instance=backend,
    )
  • Esta versión introduce un método de descomposición para puertas de dos qubits que se dirige a conjuntos de puertas RZX definidos por el usuario. Los usuarios de Transpiler pueden activar la descomposición para {RZX(pi/2), RZX(pi/4), and RZX(pi/6)} específicamente incluyendo 'rzx' en su lista basis_gates al llamar a transpile(). Los usuarios del paquete de información Quantum pueden encontrar el método en la clase XXDecomposer clase.

  • Añadido un transpiler pass Optimize1qGatesSimpleCommutationque optimiza un circuito según una estrategia de conmutación de puertas de un solo qubit para descubrir oportunidades de resíntesis.

  • Se ha añadido un parámetro max_job_tries a QuantumInstancepara limitar el número de veces que un trabajo intentará ejecutarse en un backend. Anteriormente, el envío y la obtención de resultados se intentaban infinitamente, incluso si el trabajo se cancelaba o se producía un error en el backend. El valor por defecto es ahora 50, y el comportamiento anterior puede conseguirse configurando max_job_tries=-1. Correcciones #6872 y #6821.

  • El método de salida latex para la función circuit_drawer() y el método QuantumCircuit.draw() pueden ahora dibujar circuitos que contengan puertas con condición de bit único. Esto se añadió para la compatibilidad del cajón de látex con la nueva característica de soporte de condicionamiento clásico de puertas en bits clásicos individuales.

  • El método de salida "mpl" para la función circuit_drawer() y el método QuantumCircuit.draw() pueden ahora dibujar circuitos que contengan puertas con condición de bit único. Esto se añadió para la compatibilidad del cajón "mpl" con la nueva característica de soporte de condicionamiento clásico de compuertas en bits clásicos individuales.

  • El método de salida text para la función circuit_drawer() y el método QuantumCircuit.draw() pueden ahora dibujar circuitos que contengan puertas con condición de bit único. Esto se añadió para la compatibilidad del cajón de texto con la nueva característica de soporte de condicionamiento clásico de puertas en bits clásicos individuales.

  • Se ha añadido un nuevo pase de transpilador de análisis GatesInBasisse ha añadido a qiskit.transpiler.passes. Este paso se utiliza para comprobar si el DAGCircuit que se está transpilando tiene todas las puertas del conjunto de bases configurado o no. Establecerá el atributo "all_gates_in_basis" en el conjunto de propiedades a True si todas las puertas en el conjunto de propiedades DAGCircuit están en el conjunto de bases configurado o False si no lo están. Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import GatesInBasis
    
    # Instatiate Pass
    basis_gates = ["cx", "h"]
    basis_check_pass = GatesInBasis(basis_gates)
    # Build circuit
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    # Run pass on circuit
    property_set = {}
    basis_check_pass(circuit, property_set=property_set)
    assert property_set["all_gates_in_basis"]
  • Añadidos dos nuevos métodos constructores from_heavy_hex() y from_heavy_square()a la clase CouplingMap clase. Estos métodos constructores se utilizan para crear un CouplingMap que son un grafo hexagonal pesado o cuadrado pesado como se describe en Chamberland et al., 2020.

    Por ejemplo:

    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_hex(5)
    cmap.draw()
    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_square(5)
    cmap.draw()
  • El algoritmo HHL puede ahora encontrar soluciones cuando su matriz tiene valores propios negativos. Para ello, el algoritmo añade ahora un qubit adicional para representar el signo del valor, y el algoritmo de ayuda ExactReciprocal para procesar esta nueva información. Ver #6971 para más detalles.

  • Añadidas dos nuevas clases CompleteMeasFitter y TensoredMeasFitter al módulo qiskit.utils.mitigation módulo. Estas clases sólo pueden utilizarse como valores para el kwarg measurement_error_mitigation_cls de la clase QuantumInstance clase. La instanciación y el uso de estas clases (o cualquier otra cosa en qiskit.utils.mitigation) fuera del kwarg measurement_error_mitigation_cls debe tratarse como una API privada interna y no debe confiarse en ella.

  • La clase ListOp clase en qiskit.opflow tiene ahora un atributo coeffs que devuelve una lista de los coeficientes de la lista de operadores, con el coeficiente global (ListOp.coeff) distribuido multiplicativamente en la lista. Tenga en cuenta que ListOp pueden estar anidados (contenidos en oplist de un objeto ListOp objeto), y en estos casos se produce una excepción si se llama al método coeffs. El método ListOp.coeffs convenientemente contra el método de la propiedad coeffs de la clase no anidada PauliSumOp no anidada.

  • La clase Statevector es ahora subscriptible. El usuario puede ahora recuperar el enésimo coeficiente en un Statevector por índice como statevec[n].

  • Se ha añadido el Statevector.inner para calcular productos internos de Statevector instancias. Por ejemplo:

    statevec_inner_other = statevec.inner(other)

    devolverá el producto interior de statevec con other. Mientras que statevec debe ser un Statevectorother puede ser cualquier cosa que pueda construirse como una matriz Statevectorcomo una matriz Numpy.

  • Se ha añadido un nuevo parámetro, add_bits, a QuantumCircuit.measure_all(). Por defecto se establece en True para mantener el comportamiento anterior de añadir un nuevo ClassicalRegister del mismo tamaño que el número de qubits para almacenar las mediciones. Si se establece en False, las mediciones se almacenarán en los bits clásicos ya existentes. Por ejemplo, si creas un circuito con bits clásicos existentes como:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qr = QuantumRegister(2)
    cr = ClassicalRegister(2, "meas")
    circuit = QuantumCircuit(qr, cr)

    la llamada a circuit.measure_all(add_bits=False) utilizará el registro clásico existente cr como destino de salida de los objetos Measurement añadidos al circuito.

  • ParameterExpression ahora delega sus conversiones numéricas a la biblioteca simbólica subyacente, incluso si hay parámetros potencialmente no vinculados. Esto permite convertir expresiones como

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> float(x - x + 2.3)
    2.3

    donde la expresión subyacente tiene un valor fijo, pero el parámetro x aún no está acotado.

  • Se ha añadido un Optimizer.minimize() a todos los optimizadores: Optimizer y clases derivadas. Este método imita la firma de la función SciPy’s minimize() y devuelve un archivo OptimizerResult.

    Por ejemplo

    import numpy as np
    from qiskit.algorithms.optimizers import COBYLA
    
    def loss(x):
        return -(x[0] - 1) ** 2 - (x[1] + 1) ** 3
    
    initial_point = np.array([0, 0])
    optimizer = COBYLA()
    result = optimizer.minimize(loss, initial_point)
    
    optimal_parameters = result.x
    minimum_value = result.fun
    num_function_evals = result.nfev
  • Se ha añadido un PauliEvolutionGate a la biblioteca de circuitos (qiskit.circuit.library) que define una puerta que realiza la evolución temporal de (sumas o sumas-de-sumas de) Paulis. La síntesis de esta puerta la realiza EvolutionSynthesis y está desacoplada de la propia puerta. Los métodos de síntesis disponibles actualmente son:

    Por ejemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.synthesis import SuzukiTrotter
    
    operator = SparsePauliOp.from_list([
        ("XIZ", 0.5), ("ZZX", 0.5), ("IYY", -1)
    ])
    time = 0.12  # evolution time
    synth = SuzukiTrotter(order=4, reps=2)
    
    evo = PauliEvolutionGate(operator, time=time, synthesis=synth)
    
    circuit = QuantumCircuit(3)
    circuit.append(evo, range(3))
  • Se ha introducido una nueva función plot_coupling_map() que amplía la funcionalidad de la función existente plot_gate_map()aceptando tres parámetros: num_qubit, qubit_coordinates, y coupling_map (en lugar de backend), para poder trazar un mapa de acoplamiento de qubits arbitrario.

  • Qiskit Terra ahora tiene soporte inicial para serializar QuantumCircuits a OpenQASM 3 :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    
    print(qasm3.dumps(qc))

    Esta versión inicial tiene soporte limitado para registros con nombre, instrucciones básicas incorporadas (como medida, barrera y reset), puertas definidas por el usuario, instrucciones definidas por el usuario (como subrutinas), y las nuevas construcciones de flujo de control también introducidas en esta versión:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    import math
    
    composite_circ_qreg = QuantumRegister(2)
    composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ")
    composite_circ.h(0)
    composite_circ.x(1)
    composite_circ.cx(0, 1)
    composite_circ_gate = composite_circ.to_gate()
    
    qr = QuantumRegister(2, "qr")
    cr = ClassicalRegister(2, "cr")
    qc = QuantumCircuit(qr, cr)
    with qc.for_loop(range(4)) as i:
        qc.rx(i * math.pi / 4, 0)
        qc.cx(0, 1)
    qc.barrier()
    qc.append(composite_circ_gate, [0, 1])
    qc.measure([0, 1], [0, 1])
    
    print(qasm3.dumps(qc))
  • La clase QDrift clase se reformuló como un método de síntesis para PauliEvolutionGateque deriva de TrotterizationBase.

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis import QDrift
    from qiskit.opflow import X, Y, Z
    
    qdrift = QDrift(reps=2)
    operator = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
    time = 2.345  # evolution time
    
    evolution_gate = PauliEvolutionGate(operator, time, synthesis=qdrift)
    
    circuit = QuantumCircuit(3)
    circuit.append(evolution_gate, range(3))
  • La serialización QPY es ahora capaz de representar global_phase atributos de un QuantumCircuit que son un objeto int, Parameter objeto, o ParameterExpression objeto. Las versiones anteriores de QPY sólo aceptaban un global_phase que fuera un float.

    Esto requiere el formato QPY Versión 2 que se introdujo en esta versión para representar los tipos adicionales.

  • Se ha añadido un nuevo find_bit() a la clase QuantumCircuit que permite consultar el índice y los registros de un circuito dado Bit en el circuito dado. El método devuelve un namedtuple de dos elementos que contiene 0) el índice del Bit en cualquiera de los dos qubits (para un Qubit) o clbits (para a Clbit) y 1) una lista de tuplas length-2 que contiene cada circuito Register que contiene el Bit, y el índice en ese Register en el que se puede encontrar el Bit .

    Por ejemplo:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit
    
    reg1 = QuantumRegister(3, 'foo')
    qubit = Qubit()
    reg2 = QuantumRegister(2, 'bar')
    
    qc = QuantumCircuit(reg1, [qubit], reg2)
    
    print(qc.find_bit(reg1[2]))
    print(qc.find_bit(qubit))

    generaría:

    BitLocations(index=2, registers=[(QuantumRegister(3, 'foo'), 2)])
    BitLocations(index=3, registers=[])
  • Se han añadido tres nuevas Instruction para soportar operaciones de flujo de control en circuitos dinámicos: WhileLoopOp, ForLoopOpy IfElseOp. Además, dos subclases, BreakLoopOpy ContinueLoopOpque permiten salir de un contexto de bucle y continuar con la siguiente iteración, respectivamente.

    Pueden crearse como Instructiono añadirse a una instancia QuantumCircuit mediante sus respectivos métodos, QuantumCircuit.while_loop(), for_loop(), if_test(), if_else(), break_loop()y continue_loop().

  • Se ha añadido la BaseReadoutMitigator clase base abstracta para implementar mitigadores de error de medición clásicos. Estos objetos están destinados a mitigar los errores de medición en Counts objetos devueltos por la ejecución de circuitos en backends con errores de medición.

    Las clases de mitigador de lectura tienen dos métodos principales:

    Tenga en cuenta que actualmente el módulo qiskit.algorithms y la clase QuantumInstance todavía utilizan los mitigadores heredados migrados de Qiskit Ignis en qiskit.utils.mitigation. Está previsto actualizar el módulo para que utilice las nuevas clases de mitigación y dejar obsoleto el código de mitigación heredado en una futura versión.

  • Se ha añadido la clase LocalReadoutMitigator para mitigar los errores locales de medición. Los errores de medición locales son aquellos que se describen mediante un tensor-producto de errores de medición de un solo qubit.

    Esta clase se puede inicializar con una lista de NN single-qubit de matrices de asignación de error de medición o desde un backend utilizando la información de error de lectura en las propiedades del backend.

    La mitigación se implementa utilizando la inversión de la matriz de asignación local que tiene una complejidad de O(2N)O(2^N) para la mitigación de NN -qubit de QuasiDistribution y valores de expectativa.

  • Se ha añadido la clase CorrelatedReadoutMitigator para realizar la mitigación de errores de lectura de medición de errores de medición correlacionados. Esta clase puede inicializarse con una única matriz de asignación de errores de medición 2N×2N2^N \times 2^N que describa las probabilidades de error. La mitigación se implementa mediante la inversión de la matriz de asignación que tiene una complejidad de mitigación de O(4N)O(4^N) de QuasiDistribution y valores de expectativa.

  • Se ha añadido un atributo QuasiDistribution.stddev_upper_bound y un kwarg al constructor de la clase QuasiDistribution que se utiliza para almacenar errores estándar en estimaciones de cuasiprobabilidad. Se utiliza en BaseReadoutMitigator clases para almacenar el error estándar en cuasiprobabilidades atenuadas.

  • Se ha añadido un shots() a qiskit.result.Counts para devolver la suma de todos los resultados en los recuentos.

  • Cuando se ejecuta el Grover clase de algoritmo si se conoce la potencia óptima y sólo se ejecuta un único circuito, la AmplificationProblem.is_good_state y la búsqueda Grover devolverá la cadena de bits más probable. Generalmente, si no se conoce la potencia óptima del operador Grover, el algoritmo Grover algoritmo comprueba diferentes potencias (es decir, iteraciones) y aplica la función is_good_state para comprobar si se ha medido una buena cadena de bits. Por ejemplo, ahora puedes ejecutar algo como:

    from qiskit.algorithms import Grover, AmplificationProblem
    from qiskit.providers.aer import AerSimulator
    from qiskit.quantum_info import Statevector
    
    # Fixed Grover power: 2.
    grover = Grover(iterations=2, quantum_instance=AerSimulator())
    
    # The ``is_good_state`` argument not required here since Grover search
    # will be run only once, with a power of 2.
    problem = AmplificationProblem(Statevector.from_label("111"))
    
    # Run Grover search and print the best measurement
    result = grover.amplify(problem)
    print(result.top_measurement)  # should print 111
  • Añadido método remove_cregs() a la clase DAGCircuit para soportar la eliminación clásica de registros.

  • Añadido método remove_clbits() a la clase DAGCircuit para soportar la eliminación de bits clásicos ociosos. Cualquier registro clásico que haga referencia a un bit eliminado también se elimina.

  • Añadido un nuevo método, replace_block_with_op()a la clase DAGCircuit clase. Este método se utiliza para reemplazar un bloque de nodos en el DAG con una sola operación. El ejemplo canónico es el pase ConsolidateBlocks que sustituye bloques de nodos por nodos equivalentes de UnitaryGate .

  • Añadido un nuevo pase de transpilador de análisis Collect1qRunsal módulo qiskit.transpiler.passes módulo. Este paso se utiliza para encontrar secuencias de puertas ininterrumpidas que actúan sobre un único qubit. Es similar al Collect2qBlocks y CollectMultiQBlocks pero optimizado para carreras de qubits individuales en lugar de bloques de qubits múltiples.

  • Varios internos de transpilación ahora utilizan nuevas características en retworkx 0.10 cuando operan en la representación del circuito interno. Esto puede dar lugar a un aumento de la velocidad de las llamadas a transpile de alrededor del 10-40%, con mayores efectos a mayores niveles de optimización. Consulte el nº 6302 para más detalles.

  • El UnitarySynthesis transpiler pass in qiskit.transpiler.passes tiene un nuevo kwarg en el constructor, min_qubits. Cuando se especifica, puede establecerse en un valor int , que es el tamaño mínimo del objeto UnitaryGate sobre el que ejecutar la síntesis unitaria. Si un UnitaryGate en un QuantumCircuit utiliza menos qubits será omitido por esa instancia del pase.

  • Las interfaces Eigensolver y MinimumEigensolver admiten ahora el tipo Dict[str, Optional[OperatorBase]] para el parámetro aux_operators en sus respectivos métodos compute_eigenvalues() y compute_minimum_eigenvalue() . En este caso, los valores propios auxiliares también se almacenan en un diccionario bajo las mismas claves proporcionadas por el diccionario aux_operators . Las teclas que corresponden a un operador que no conmuta con el operador principal se descartan.

  • En BasisTranslator, GateDirectiony CheckGateDirection tienen un nuevo kwarg target en sus constructores, que puede utilizarse para establecer un objeto Target como destino del pase. Si se establece, se utilizará en lugar de target_basis (en el caso del BasisTranslator pass) o coupling_map (en el caso de los pass GateDirection y CheckGateDirection pass).

  • Permitir dos etapas de transpilador en el QuantumInstanceuna para circuitos parametrizados y otra sólo para circuitos limitados (es decir, sin parámetros libres). Si una instancia cuántica con pases para circuitos no ligados y ligados se pasa a un CircuitSamplerel muestreador intentará aplicar el pase no ligado una vez en el circuito parametrizado, lo almacenará en caché y sólo aplicará el pase ligado para todas las evaluaciones futuras.

    Esto permite a los algoritmos variacionales como el VQE ejecutar un gestor de pases personalizado para circuitos parametrizados una vez y, además, otro el transpilador de nuevo con un gestor de pases personalizado diferente en los circuitos ligados en cada iteración. Poder ejecutar diferentes gestores de pases es importante porque no todos los pases admiten circuitos parametrizados (por ejemplo Optimize1qGatesDecomposition sólo funciona con circuitos parametrizados).

    Por ejemplo, esta característica permite utilizar la descomposición CX de pulso eficiente en el VQE, como

    from qiskit.algorithms import VQE
    from qiskit.opflow import Z
    from qiskit.circuit.library.standard_gates.equivalence_library import StandardEquivalenceLibrary as std_eqlib
    from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.transpiler.passes import (
        Collect2qBlocks, ConsolidateBlocks, Optimize1qGatesDecomposition,
        RZXCalibrationBuilderNoEcho, UnrollCustomDefinitions, BasisTranslator
    )
    from qiskit.transpiler.passes.optimization.echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
    from qiskit.test.mock import FakeBelem
    from qiskit.utils import QuantumInstance
    
    # Replace by a real backend! If not ensure qiskit-aer is installed to simulate the backend
    backend = FakeBelem()
    
    # Build the pass manager for the parameterized circuit
    rzx_basis = ['rzx', 'rz', 'x', 'sx']
    coupling_map = CouplingMap(backend.configuration().coupling_map)
    config = PassManagerConfig(basis_gates=rzx_basis, coupling_map=coupling_map)
    pre = level_1_pass_manager(config)
    
    # Build a pass manager for the CX decomposition (works only on bound circuits)
    post = PassManager([
        # Consolidate consecutive two-qubit operations.
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=['rz', 'sx', 'x', 'rxx']),
    
        # Rewrite circuit in terms of Weyl-decomposed echoed RZX gates.
        EchoRZXWeylDecomposition(backend),
    
        # Attach scaled CR pulse schedules to the RZX gates.
        RZXCalibrationBuilderNoEcho(backend),
    
        # Simplify single-qubit gates.
        UnrollCustomDefinitions(std_eqlib, rzx_basis),
        BasisTranslator(std_eqlib, rzx_basis),
        Optimize1qGatesDecomposition(rzx_basis),
    ])
    
    quantum_instance = QuantumInstance(backend, pass_manager=pre, bound_pass_manager=post)
    
    vqe = VQE(quantum_instance=quantum_instance)
    result = vqe.compute_minimum_eigenvalue(Z ^ Z)
  • Se ha introducido una nueva interfaz de plugin de síntesis unitaria que se utiliza para permitir el uso de técnicas de síntesis alternativas incluidas en paquetes externos sin problemas con el UnitarySynthesis transpilador. Los usuarios pueden seleccionar un complemento para utilizarlo al llamar a transpile() estableciendo el kwarg unitary_synthesis_method con el nombre del complemento. Puede encontrar una lista completa de los plugins instalados utilizando la función qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names() función. Por ejemplo, si instalas un paquete que incluye un plugin de síntesis llamado special_synth podrías utilizarlo con:

    from qiskit import transpile
    
    transpile(qc, unitary_synthesis_method='special_synth', optimization_level=3)

    Esto reemplazará todos los usos del método UnitarySynthesis por el método incluido en el paquete externo que exporta el plugin special_synth .

    La interfaz del plugin está construida alrededor de puntos de entrada setuptools que permiten a los paquetes externos a Qiskit anunciar que incluyen un plugin de síntesis. Para más información sobre cómo crear un nuevo plugin, consulte la documentación del módulo qiskit.transpiler.passes.synthesis.plugin documentación del módulo.

  • Añadido un nuevo pase de transpilador, VF2Layout. Este paso modela el problema de asignación de distribución como un problema de isomorfismo de subgrafos y utiliza la implementación del algoritmo VF2 en rustworkx para encontrar una distribución perfecta (una distribución que no requiera enrutamiento adicional) si existe. La funcionalidad expuesta por este nuevo pase es muy similar a la existente CSPLayout pero VF2Layout es significativamente más rápida.

Problemas conocidos

  • La convención "ket" en el cajón "latex" de Statevector.draw() sólo es válida para estados formados exclusivamente por qubits. Si utiliza estados con algunos espacios de dimensión superior a dos, deberá pasar convention="vector", o utilizar un cajón diferente.

  • Las capacidades de exportación de OpenQASM 3 están en estado beta, y algunas características de Qiskit Terra's QuantumCircuit aún no son compatibles. En particular, es posible que se produzcan errores si intenta exportar subrutinas personalizadas con parámetros clásicos, y aún no está previsto exportar operaciones calibradas por impulsos a OpenPulse.

  • Cuando se ejecuta el programa BasisTranslator de forma aislada con el argumento target establecido en un objeto Target donde algunas puertas single-qubit sólo pueden aplicarse a conjuntos no solapados de qubits, el circuito de salida podría incluir incorrectamente operaciones sobre un qubit que no están permitidas por el argumento Target. Por ejemplo, si corres:

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit.circuit.library import UGate, RZGate, XGate, SXGate, CXGate
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    from qiskit.transpiler import PassManager, Target, InstructionProperties
    from qiskit.transpiler.passes import BasisTranslator
    
    gmap = Target()
    
    # U gate in qubit 0.
    theta = Parameter('theta')
    phi = Parameter('phi')
    lam = Parameter('lambda')
    u_props = {
        (0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
    }
    gmap.add_instruction(UGate(theta, phi, lam), u_props)
    
    # Rz gate in qubit 1.
    phi = Parameter("phi")
    rz_props = {
        (1,): InstructionProperties(duration=0.0, error=0),
    }
    gmap.add_instruction(RZGate(phi), rz_props)
    
    # X gate in qubit 1.
    x_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(XGate(), x_props)
    
    # SX gate in qubit 1.
    sx_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(SXGate(), sx_props)
    
    cx_props = {
        (0, 1): InstructionProperties(duration=5.23e-7, error=0.00098115),
        (1, 0): InstructionProperties(duration=4.52e-7, error=0.00132115),
    }
    gmap.add_instruction(CXGate(), cx_props)
    
    bt_pass = BasisTranslator(sel, target_basis=None, target=gmap)
    
    qc = QuantumCircuit(2)
    qc.iswap(0, 1)
    output = bt_pass(qc)

    output tendrá RZGate y SXGate en el qubit 0, aunque esté prohibido. Para corregirlo, normalmente puede ejecutar el traductor de bases una segunda vez (es decir output = bt_pass(output) en el ejemplo anterior) para corregirlo. Esto no debería afectar a la salida de la ejecución de la función transpile() y sólo es un problema si ejecuta el pase por sí mismo.

Notas de actualización

  • A partir de esta versión, from qiskit import * no importará submódulos, sino sólo una lista seleccionada de objetos. Esto podría romper el código existente que utiliza from qiskit import * y hace referencia a objetos que no forman parte del espacio de nombres actual. Como recordatorio, import * se considera una mala práctica y no debe utilizarse en código de producción. Qiskit establece __all__ en qiskit/__init__.py como forma de mitigar los efectos de dichas malas prácticas. Si su código muestra name '<something>' is not defined, añada from qiskit import <something> e inténtelo de nuevo.

  • Los gestores de pases preestablecidos para los niveles de optimización 0, 1, 2 y 3 que se generan mediante level_0_pass_manager(), level_1_pass_manager(), level_2_pass_manager()y level_3_pass_manager() respectivamente, ya no ejecutarán incondicionalmente la función TimeUnitConversion. Anteriormente, los gestores de pases preestablecidos siempre ejecutaban este pase independientemente de las entradas del transpilador y del circuito. Ahora este pase sólo se ejecutará si se establece un parámetro scheduling_method o el circuito contiene una Delay y el parámetro instruction_durations está activado. Este cambio se realizó en interés del rendimiento en tiempo de ejecución, ya que en algunos casos se ejecuta en circuitos con un gran número de puertas y no se utilizan retardos, temporización o programación transpile() en circuitos con un gran número de puertas y sin utilizar retardos, temporización o programación la TimeUnitConversion podría ser el mayor cuello de botella en la transpilación.

  • El método por defecto para BIPMapping es ahora balanced en lugar de depth. Este nuevo objetivo suele dar mejores resultados, ya que tiene en cuenta tanto la profundidad del circuito como el error de puerta.

  • La dirección sort_parameters_by_name de la clase VQE ha sido eliminada, tras su desaparición en Qiskit Terra 0.18. No se proporciona ninguna alternativa, ya que el nuevo orden de los parámetros es el más natural.

  • Los cajones del circuito QuantumCircuit.draw() y circuit_drawer() con la opción latex guardarán ahora sus imágenes en un formato determinado la extensión del archivo (si se proporciona un nombre de archivo). Antes, siempre se guardaban en formato PNG. Ahora aparecen en ValueError si no se conoce el formato de la imagen. Esto se hizo para facilitar el guardado de la imagen en distintos formatos.

  • El requisito de versión de la dependencia principal retworkx ha pasado de 0.9 a 0.10.1. Esto permite varias mejoras de rendimiento en diferentes pases de transpilación.

  • El anteriormente obsoleto condition kwarg, que fue obsoleto como parte de la versión 0.15.0, ha sido eliminado de DAGCircuit.apply_operation_back() y DAGCircuit.apply_operation_front(). En su lugar, establezca el atributo condition en las Instruction que se añaden a la instancia DAGCircuit utilizando Instruction.c_if().

  • Se ha eliminado el método DAGCircuit.extend_back(). Originalmente fue obsoleto en la versión 0.13.0. En su lugar, puede utilizar el método DAGCircuit.compose() que es más general y ofrece la misma funcionalidad.

  • Se ha eliminado el método DAGCircuit.compose_back(). Originalmente fue obsoleto en la versión 0.13.0. En su lugar, puede utilizar el método DAGCircuit.compose() que es más general y ofrece la misma funcionalidad.

  • El edge_map kwarg del DAGCircuit método compose() se ha eliminado. Originalmente fue obsoleto en la versión 0.14.0. El método toma un qubits y clbits kwargs para especificar el orden posicional de los bits a componer en lugar de usar un mapeo de diccionario que edge_map proporcionaba previamente.

  • Se ha eliminado el método DAGCircuit.twoQ_gates(). Originalmente fue obsoleto en la versión 0.13.0. En su lugar, DAGCircuit.two_qubit_ops() debe utilizarse

  • Se ha eliminado el método DAGCircuit.threeQ_or_more_gates(). Originalmente fue obsoleto en la versión 0.13.0. En su lugar, DAGCircuit.multi_qubit_ops() debe utilizarse el método

  • Se ha eliminado el acceso nombrado para el primer argumento posicional del constructor de la SingleQubitUnitary con u . Originalmente fue obsoleto en la versión 0.14.0. En su lugar, el primer argumento posicional se puede establecer utilizando el nombre unitary_matrix (o simplemente establecerlo posicionalmente en lugar de por su nombre).

  • Acceso con nombre para el primer argumento posicional del método QuantumCircuit método squ con u . Originalmente fue obsoleto en la versión 0.14.0. En su lugar, el primer argumento posicional se puede establecer utilizando el nombre unitary_matrix (o simplemente establecerlo posicionalmente en lugar de por su nombre).

  • Se han eliminado los kwargs no utilizados proc y nested_scope para el método qasm() de las clases de nodos QASM en el módulo qiskit.qasm.node . Originalmente estaban obsoletos en la versión 0.15.0.

  • Se han eliminado los kwargs no utilizados proc y nested_scope para el método latex() de las clases de nodos QASM en el módulo qiskit.qasm.node . Originalmente estaban obsoletos en la versión 0.15.0.

  • Se han eliminado los kwargs no utilizados proc y nested_scope para el método real() de las clases de nodos QASM en el módulo qiskit.qasm.node . Originalmente estaban obsoletos en la versión 0.15.0.

  • La salida de Statevector.draw() cuando se utiliza la salida "latex" es ahora la nueva convención "ket" si se traza un estado compuesto puramente de qubits. Esto se cambió para que la lectura de la salida fuera más clara, especialmente en contextos educativos, ya que muestra las etiquetas ket, y sólo muestra los elementos distintos de cero.

  • Cuando se ejecuta execute() con un BackendV1 los valores por defecto de los kwargs shots, max_credits, meas_level, meas_return y memory_slot_size serán ahora los valores por defecto establecidos en el atributo options del backend de destino. Anteriormente, estos valores predeterminados se establecían para que coincidieran con los valores predeterminados al llamar a execute() con un backend heredado de BaseBackend . Por ejemplo:

    from qiskit.test.mock import FakeMumbai
    from qiskit import QuantumCircuit, execute
    
    circuit = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    backend = FakeMumbai()
    backend.set_options(shots=4096)
    execute(qc, backend)

    se ejecutará ahora con 4096 disparos. Mientras que en versiones anteriores se ejecutaba con 1024.

  • La versión mínima compatible de Matplotlib ha pasado de 2.1.0 a 3.3.0. Ahora necesitará tener instalado Matplotlib 3.3.0 si utiliza funciones de visualización basadas en Matplotlib, como el backend 'mpl' para la función circuit_drawer() o la función plot_bloch_vector() función. Esto se hizo por dos razones, la primera es porque las versiones recientes de Matplotlib han dejado de utilizar las API en torno a las visualizaciones de 3D que eran compatibles con versiones anteriores y, en segundo lugar, la instalación de versiones anteriores de Matplotlib se estaba volviendo cada vez más difícil ya que las dependencias de matplotlib han causado incompatibilidades que hacían que las pruebas fueran más difíciles.

  • El uso interno del generador de números aleatorios en random_circuit() se ha ajustado, lo que cambiará la salida de las versiones anteriores, incluso con una semilla fija. Esto se hizo para mejorar enormemente el escalado del tiempo de ejecución con el número de qubits utilizados. Si usted dependía de una salida idéntica de una versión anterior, se recomienda que utilice qpy_serialization.dump() para guardar el circuito aleatorio generado con una versión anterior y en lugar de volver a generarlo con la nueva versión, y en su lugar sólo utilice qpy_serialization.load() para cargar ese circuito guardado.

  • El uso de * (__mul__) para el método dot() y @ (__matmul__) para el método compose() de BaseOperator (que es el padre de todas las clases de operadores en qiskit.quantum_info incluyendo clases como Operator y Pauli) ya no se admite. El uso de estos operadores ya estaba obsoleto en la versión 0.17.0. En su lugar, debe utilizar las etiquetas dot() y compose() directamente, o puede utilizarse el operador & (__and__) para los métodos compose(). Por ejemplo, si antes utilizabas el operador como:

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    
    new_op = op_a @ op_b

    esto debería cambiarse por:

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    new_op = op_a.compose(op_b)

    o:

    new_op = op_a & op_b
  • Se han eliminado varios métodos de asignación de parámetros a operandos de instrucciones de programa de pulsos, que han quedado obsoletos en Qiskit Terra 0.17. Esto incluye:

    • el método assign() de pulse.Instruction.
    • el método assign() de Channel, que es la base de AcquireChannel, SnapshotChannel, MemorySlot y RegisterSlot.
    • los métodos assign() y assign_parameters() de ParametricPulse, que es la base de pulse.Gaussian, pulse.GaussianSquare, pulse.Drag y pulse.Constant.

    Estos parámetros deben asignarse desde el programa de impulsos (pulse.Schedule y pulse.ScheduleBlock) en lugar de operandos de la instrucción del programa de pulsos.

  • El método flatten() de pulse.Instruction y qiskit.pulse.Schedule ha sido eliminado y ya no existe según el aviso de depreciación de Qiskit Terra 0.17. Esta transformación se define como una función independiente en qiskit.pulse.transforms.canonicalization.flatten().

  • qiskit.pulse.interfaces.ScheduleComponent ha sido eliminado y ya no existe según el aviso de obsoleto de Qiskit Terra 0.15. No se proporcionará ninguna clase alternativa.

  • Se han eliminado los argumentos heredados del cajón de pulsos de pulse.Waveform.draw(), Schedule.draw() y ScheduleBlock.draw() y ya no existen según el aviso de obsoleto de Qiskit Terra 0.16. Ahora estos métodos de dibujo sólo admiten argumentos de cajón de pulsos V2. Consulte la documentación de los métodos para más detalles.

  • El módulo qiskit.pulse.reschedule ha sido eliminado y esta ruta de importación ya no existe según el aviso de depreciación de Qiskit Terra 0.14. Utilice qiskit.pulse.transforms en su lugar.

  • Se ha eliminado un método protegido Schedule._children() y se ha sustituido por una variable de instancia protegida de acuerdo con el aviso de desaprobación de Qiskit Terra 0.17. Ahora se proporciona como atributo público Schedule.children.

  • Los métodos y propiedades relevantes para Timeslot han sido eliminados y ya no existen en ScheduleBlock de acuerdo con el aviso de desaprobación de Qiskit Terra 0.17. Dado que esta representación no tiene noción del tiempo de instrucción t0, la información sobre las franjas horarias estará disponible después de que se transforme a a Schedule. Los atributos correspondientes se han proporcionado después de esta conversión, pero ya no son compatibles. Se eliminan los siguientes atributos:

    • timeslots
    • start_time
    • stop_time
    • ch_start_time
    • ch_stop_time
    • shift
    • insert
  • Las transformaciones del programa de impulsos de alineación se han eliminado y ya no existen, según el aviso de obsoleto de Qiskit Terra 0.17. Estas transformaciones se integran y aplican en el contexto AlignmentKind del bloque de programación. Se eliminan las siguientes funciones de transformación explícitas:

    • qiskit.pulse.transforms.align_equispaced
    • qiskit.pulse.transforms.align_func
    • qiskit.pulse.transforms.align_left
    • qiskit.pulse.transforms.align_right
    • qiskit.pulse.transforms.align_sequential
  • Los comandos redundantes del generador de impulsos se han eliminado y ya no existen, de acuerdo con el aviso de desaprobación de Qiskit Terra 0.17. pulse.builder.call_schedule y pulse.builder.call_circuit se han integrado en pulse.builder.call().

  • Se ha eliminado un filtro interno que hacía que se mostraran todas las advertencias de depreciación de Qiskit. Esto significa que el comportamiento ahora volverá al comportamiento estándar de Python para las depreciaciones; sólo debería ver un DeprecationWarning si ha sido activado por código en el archivo de script principal, sesión de intérprete o cuaderno Jupyter. El usuario ya no será culpado con una advertencia si las funciones internas de Qiskit llaman a comportamientos obsoletos. Si escribes bibliotecas, de vez en cuando deberías ejecutarlas con los filtros de advertencia por defecto desactivados, o tener pruebas que siempre se ejecuten con ellos desactivados. Consulte la documentación de Python sobre advertencias y, en particular, la sección sobre pruebas de deprecación para obtener más información sobre cómo hacerlo.

  • Algunas advertencias sólo se emitían una vez, aunque se activaran desde varios lugares. Este comportamiento se ha eliminado, por lo que es posible que si llama a funciones obsoletas, vea más advertencias que antes. Deberías cambiar cualquier llamada a funciones obsoletas a las versiones sugeridas, porque las formas obsoletas serán eliminadas en futuras versiones de Qiskit.

  • El módulo obsoleto qiskit.schemas y el módulo qiskit.validation que construyen el validador jsonschema a partir de los esquemas han sido eliminados. Esta función quedó obsoleta en la versión 0.17.0 y ha sido sustituida por un repositorio específico para los esquemas de carga útil de la API Quantum IBM.

    Si confiaba en los archivos de esquema previamente empaquetados en qiskit.schemas o en los validadores creados a partir de ellos, deberá utilizar ese repositorio y crear validadores a partir de los archivos de esquema que contiene.

  • Las funciones qiskit.qobj.validate_qobj_against_schema y qiskit.qobj.common.validator junto con el kwarg validate de los métodos QasmQobj.to_dict(), PulseQobj.to_dict()y Qobj.to_dict() . Se eliminaron en la versión 0.17.0. Si utilizaba estas funciones, tendrá que crear manualmente funciones de validación jsonschema para los objetos Qobj utilizando los archivos jsonschema del repositorio dedicado a los esquemas de carga útil de la API IBM Quantum.

  • Los paquetes fastjsonschema y jsonschema ya no figuran en la lista de requisitos de qiskit-terra. Se ha eliminado el uso interno de jsonschema y ya no son necesarios para utilizar qiskit-terra.

  • La excepción lanzada por la función assemble() cuando se pasan parámetros no válidos para construir una función PulseQobj ha cambiado de SchemaValidationError a QiskitError. Esto era necesario porque la clase SchemaValidationError se eliminó junto con el resto de las clases obsoletas qiskit.schemas y qiskit.validation. Esto también lo hace más coherente con otras condiciones de error de assemble() que ya planteaban un error QiskitError.

  • El pase de enrutamiento y el pase de diseño predeterminados para el nivel de optimización 3 del transpilador han cambiado para utilizar SabreSwap y SabreLayout respectivamente. Esto se hizo para mejorar la calidad del resultado de salida, ya que el uso de los pases de sable produce mejores resultados que el uso de StochasticSwap y DenseLayoutque se utilizaban por defecto en versiones anteriores. Este cambio mejorará la calidad de los resultados al ejecutar transpile() o execute() con el kwarg optimization_level ajustado a 3. Aunque en general esto es una mejora, si por alguna razón necesita mantener el comportamiento anterior, puede hacerlo estableciendo explícitamente routing_method="stochastic" y layout_method="dense" al llamar a transpile() con optimization_level=3.

  • El tipo de retorno de pauli_basis() cambiará de PauliTable a PauliList en una futura versión de Qiskit Terra. Para cambiar inmediatamente al nuevo comportamiento, pase el argumento de palabra clave pauli_list=True.

  • El atributo name de la clase SingleQubitUnitary se ha cambiado de unitary a squ. Esto era necesario para evitar un conflicto con el nombre de la clase UnitaryGate que también era unitary ya que las 2 puertas no son lo mismo y no tienen la misma implementación (y no se pueden utilizar indistintamente).

  • La versión mínima de Symengine necesaria para la instalación se ha aumentado a 0.8.0. Esto era necesario para solucionar algunos problemas con el manejo de numpy.float16 y numpy.float32 valores cuando se ejecuta bind() para enlazar parámetros en un archivo ParameterExpression.

  • Se ha añadido un nuevo estibador dependiente a la lista de requisitos. Esto es requerido por qiskit-terra, ya que se utiliza para construir la interfaz de plugin de síntesis unitaria.

Notas sobre características en desuso

  • El atributo gate y el parámetro de inicialización de qiskit.transpiler.passes.Decompose está obsoleto y se eliminará en una futura versión. En lugar de esta única puerta, debe pasar una lista de nombres de puertas al nuevo parámetro gates_to_decompose. Esto se ha hecho porque el nuevo formulario permite seleccionar más de una compuerta como objetivo de descomposición, lo que es más flexible, y no es necesario volver a ejecutar el pase varias veces para descomponer un conjunto de compuertas.

  • Se ha producido una importante reorganización del paso del transpilador en lo que respecta a las calibraciones. Las vías de importación:

    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilder
    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilderNoEcho

    están obsoletos y se eliminarán en una futura versión. La ruta de importación:

    from qiskit.transpiler.passes.scheduling.rzx_templates import rzx_templates

    también está obsoleto y se eliminará en una futura versión. Debe utilizar las nuevas rutas de importación:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.transpiler.passes import RZXCalibrationBuilderNoEcho
    from qiskit.transpiler.passes.calibration.rzx_templates import rzx_templates
  • La clase DAGNode ha quedado obsoleta como clase independiente y en el futuro sólo se utilizará como clase padre de las clases DAGOpNode, DAGInNodey DAGOutNode. Como parte de esta eliminación, los siguientes kwargs y atributos asociados en DAGNode también quedan obsoletos: type, op, y wire.

  • Para el constructor de RZXCalibrationBuilder pasar un backend como primer argumento posicional o con el kwarg backend está obsoleto y dejará de funcionar en futuras versiones. En su lugar, debe pasarse un InstructionScheduleMap debe pasarse directamente al kwarg instruction_schedule_map y una lista de listas de nombres de canales para cada qubit debe pasarse directamente a qubit_channel_mapping. Por ejemplo, si llamaras al pase como:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.test.mock import FakeMumbai
    
    backend = FakeMumbai()
    cal_pass = RZXCalibrationBuilder(backend)

    en vez de eso deberías llamarlo como:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.test.mock import FakeMumbai
    
    backend = FakeMumbai()
    inst_map = backend.defaults().instruction_schedule_map
    channel_map = self.backend.configuration().qubit_channel_mapping
    cal_pass = RZXCalibrationBuilder(
        instruction_schedule_map=inst_map,
        qubit_channel_mapping=channel_map,
    )

    Este cambio es necesario porque como regla general los objetos backend no son serializables en pickle y se rompería cuando se usara con múltiples procesos dentro de transpile() al compilar varios circuitos a la vez.

  • La propiedad label de la clase MCMT y subclase MCMTVChain ha quedado obsoleta y se eliminará en una futura versión. En consecuencia, el kwarg label del constructor de ambas clases también queda obsoleto, junto con el kwarg label del método MCMT.control(). Actualmente, la propiedad label se utiliza para nombrar el objetivo controlado cuando se compone de más de un qubit objetivo, sin embargo, esto nunca fue pensado para ser especificable por el usuario, y puede resultar en una puerta MCMT incorrecta si se utiliza el nombre de una operación bien conocida. Una vez obsoleta, la propiedad label ya no podrá ser especificada por el usuario. Sin embargo, puede obtener el nombre generado del objetivo controlado mediante

    MCMT.data[0][0].base_gate.name
  • El método subgraph() de la clase CouplingMap está obsoleto y se eliminará en una futura versión. En su lugar debe utilizarse el método reduce() que hace lo mismo excepto que preserva el orden de la lista de nodos para la salida CouplingMap (mientras que subgraph() no conserva el orden de la lista).

  • La creación de una instancia de InstructionSet con el argumento circuit_cregs está obsoleto. En general, estas clases nunca necesitan ser construidas por los usuarios (pero se utilizan internamente), pero si lo necesita, debe pasar un callable como argumento de la palabra clave resource_requester . Por ejemplo:

    from qiskit.circuit import Clbit, ClassicalRegister, InstructionSet
    from qiskit.circuit.exceptions import CircuitError
    
    def my_requester(bits, registers):
        bits_set = set(bits)
        bits_flat = tuple(bits)
        registers_set = set(registers)
    
        def requester(specifier):
            if isinstance(specifer, Clbit) and specifier in bits_set:
                return specifier
            if isinstance(specifer, ClassicalRegster) and specifier in register_set:
                return specifier
            if isinstance(specifier, int) and 0 <= specifier < len(bits_flat):
                return bits_flat[specifier]
            raise CircuitError(f"Unknown resource: {specifier}")
    
        return requester
    
    my_bits = [Clbit() for _ in [None]*5]
    my_registers = [ClassicalRegister(n) for n in range(3)]
    
    InstructionSet(resource_requester=my_requester(my_bits, my_registers))
  • El uso de las clases de mitigación de medidas qiskit.ignis.mitigation.CompleteMeasFitter y qiskit.ignis.mitigation.TensoredMeasFitter de qiskit-ignis como valores para el kwarg measurement_error_mitigation_cls del constructor de la clase QuantumInstance está obsoleto y se eliminará en una futura versión. En su lugar, las clases equivalentes de qiskit.utils.mitigation, CompleteMeasFitter y TensoredMeasFitter . Esto era necesario, ya que el proyecto qiskit-ignis ha quedado obsoleto y dejará de recibir apoyo en un futuro próximo. Cabe señalar que, a diferencia de las clases equivalentes de qiskit-ignis , las versiones de qiskit.utils.mitigation sólo se admiten en su uso con QuantumInstance (es decir, como clase y no como instancia con el kwarg measurement_error_mitigation_cls ) y no están pensadas para un uso independiente.

  • El método Optimizer.optimize() para todos los optimizadores (Optimizer y clases derivadas) está obsoleto y se eliminará en una futura versión. En su lugar, debe utilizarse el método Optimizer.minimize() que imita la firma de la función SciPy’s minimize() .

    Para sustituir la actual llamada a optimizar por minimizar puedes sustituir

    xopt, fopt, nfev = optimizer.optimize(
        num_vars,
        objective_function,
        gradient_function,
        variable_bounds,
        initial_point,
    )

    con

    result = optimizer.minimize(
        fun=objective_function,
        x0=initial_point,
        jac=gradient_function,
        bounds=variable_bounds,
    )
    xopt, fopt, nfev = result.x, result.fun, result.nfev
  • Al importar el módulo qiskit.util ahora se emitirá un DeprecationWarning. En su lugar, los usuarios deberían importar toda la misma funcionalidad de qiskit.utils. El módulo util está obsoleto desde Terra 0.17, pero antes no emitía ninguna advertencia. Se eliminará en Terra 0.20.

  • La propiedad table está obsoleta y se eliminará en una futura versión. Esto se debe a que SparsePauliOp se ha actualizado para utilizar internamente PauliList en lugar de PauliTable. El objetivo es mejorar considerablemente el rendimiento. Ahora debería acceder a los PauliList utilizando el atributo SparsePauliOp.paulis atributo.

Corrección de errores

  • Se ha corregido un error por el que muchos métodos de diseño ignoraban las puertas de 3 o más qubits, lo que provocaba decisiones inesperadas sobre la distribución del diseño. El pase de transpilador Unroll3qOrMore se ejecuta ahora antes que el pase de maquetación en todos los gestores de pases predefinidos cuando se llama a transpile() se llama. Corregido #7156.

  • Los circuitos desmontados heredan ahora las calibraciones de los montados QasmQobj y experimentos. Correcciones #5348.

  • Se ha corregido la configuración de los atributos ansatz o optimizer de una instancia a VQE a None , lo que provocaba un error de comportamiento. Véase el nº 7093 para más detalles.

  • Corregida la adición de PauliLists con qargs. El método utilizado para lanzar un error en tiempo de ejecución si los operandos tenían diferentes números de qubits.

  • Se ha corregido un problema que provocaba un error al intentar calcular un gradiente con la clase CircuitGradient para una puerta que no era compatible. Esta corrección de errores transpila una puerta dada al conjunto de puertas admitidas para un método de gradiente solicitado. Correcciones #6918.

  • Eliminados los resultados de calibración al utilizar la mitigación de errores con el execute() método de QuantumInstance. Corrige #7129.

  • Se ha corregido una advertencia de obsoleto que se emitía al ejecutar QuantumCircuit.draw() o circuit_drawer() con Sympy 1.9 instalado, mencionando la función de Sympy expr_free_symbols(). Los dibujantes de circuitos utilizaron anteriormente este método para encontrar instancias de constantes simbólicas.

  • Se ha solucionado un problema por el que el kwarg de ax y la opción figwidth del kwarg de style para el cajón del circuito mpl no se escalaban correctamente. Los usuarios pueden ahora pasar un ax desde una subparcela Matplotlib al cajón de circuitos mpl y el circuito se dibujará dentro de los límites de esa subparcela. Alternativamente, los usuarios pueden establecer el figwidth en pulgadas en el style dict kwarg y el dibujo se escalará a la anchura en pulgadas que se estableció. Corregido #6367.

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. Al mostrar una instrucción measure dirigida a un bit clásico en lugar de a un registro, utilizando la opción de cajón latex , el cajón fallaba.

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. Con cualquiera de las 3 opciones de cajón, mpl, latex, o text, si se encontrara una puerta con una condición clásica condicionada a un bit clásico sin registro, el cajón fallaría.

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. Con cualquiera de las 3 opciones de cajón, mpl, latex, o text, si una puerta con una condición clásica estuviera condicionada al mismo bit clásico que un measure y el bit al que se dirigiera la medida no tuviera un registro, el cajón fallaría.

  • C3SXGate tiene ahora una descomposición y una representación matricial correctas. Antes equivalía a SdgXGate().control(3), en lugar de la pretendida SXGate().control(3).

  • El miembro name de qiskit.test.mock.utils.ConfigurableFakeBackend se ha cambiado a backend_name. Esto se hizo para evitar un conflicto con el método name() heredado de la clase abstracta BackendV1 padre. Esto hace que ConfigurableFakeBackend sea compatible con cualquier cosa que espere un BackendV1 objeto. Sin embargo, si antes utilizaba el atributo name directamente, ahora tendrá que llamarlo como método o acceder al atributo backend_name en su lugar.

  • Se ha corregido un problema por el que al llamar a QuantumCircuit.decompose() en un circuito que contenía un Instruction cuyo atributo definition estaba vacío dejaba la instrucción en su lugar, en lugar de descomponerla en cero operaciones. Por ejemplo, con un circuito:

    from qiskit.circuit import QuantumCircuit
    empty = QuantumCircuit(1, name="decompose me!")
    circuit = QuantumCircuit(1)
    circuit.append(empty.to_gate(), [0])

    Antes, llamar a circuit.decompose() no cambiaba el circuito. Ahora, la descomposición correcta descompondrá empty en cero instrucciones. Ver #6997 para más información.

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. Al visualizar una instrucción measure que contenía una condition clásica utilizando las opciones mpl o latex , la información condition sobrescribía a veces la visualización measure .

  • Se ha solucionado un problema con la función circuit_drawer() y el método draw() de QuantumCircuit. El cajón mpl utiliza la notación hexadecimal para mostrar el valor condition , mientras que los cajones text y latex utilizan la notación decimal. Ahora los tres cajones utilizan notación hexadecimal.

  • Se ha corregido un error en el paso de transpilación del optimizador Hoare por el que podía intentar eliminar una puerta dos veces si se podía combinar por separado tanto con su predecesora como con su sucesora para formar la identidad. Consulte el nº 7271 para más detalles.

  • Hacer que una instrucción sea condicional con el método estándar InstructionSet.c_if() con índices enteros es ahora coherente con el esquema de numeración utilizado por las instrucciones QuantumCircuit del que forman parte las instrucciones. Anteriormente, si había dos ClassicalRegisters con Clbits, la numeración sería incorrecta. Ver #7246 para más detalles.

  • Si se condiciona una instrucción con el método estándar InstructionSet.c_if() tendrá ahora éxito, incluso si no hay ClassicalRegisters en el circuito. Ver #7250 para más detalles.

  • Condicionar una instrucción con el método estándar InstructionSet.c_if() cuando se utiliza una instrucción Clbit que está contenido en un ClassicalRegister de tamaño uno creará ahora correctamente una condición sobre el bit, no sobre el registro. Ver #7255 para más detalles.

  • Si se intenta condicionar una instrucción con el método estándar InstructionSet.c_if() dará lugar a un error si el recurso clásico no está presente en el circuito. Ver #7255 para más detalles.

  • Se ha solucionado un problema de compatibilidad con Matplotlib 3.5, por el que la esfera Bloch no se renderizaba si tenía algún vector adjunto, como por ejemplo al utilizar plot_bloch_vector. Ver #7272 para más detalles.

  • Se ha corregido un problema por el que el método NLocal.add_layer() añadía capas incorrectamente si el objeto NLocal ya había sido creado.

  • Solucionado un problema con el decapado InstructionScheduleMap cuando se utiliza Python 3.6. Consulte el nº 6944 para más detalles.

  • Se ha corregido la asignación de parámetros de pulso de valor complejo con symengine. Por ejemplo:

    from qiskit import circuit, pulse
    import numpy as np
    
    amp = circuit.Parameter("amp")
    phase = circuit.Parameter("phase")
    
    with pulse.build() as sched:
        pulse.play(pulse.Gaussian(160, amp * np.exp(1j * phase), 40), pulse.DriveChannel(0))
    sched.assign_parameters({amp: 0.1, phase: 1.57}, inplace=True)

    La amplitud asignada se ha mostrado como ParameterExpression(0.1*exp(1.57*I)) después de que se introdujera el uso de symengine en la versión 0.18.0. Ahora se evalúa correctamente y se muestra como 7.96327e-05 + 0.0999999683j.

  • Se ha solucionado un problema por el que QAOA.construct_circuit() con diferentes operadores con el mismo número de qubits generaba el mismo circuito cada vez. Ver #7223 para más detalles.

  • Se ha corregido un problema por el que QAOAAnsatz tenía un número incorrecto de parámetros si se daban identidades de PauliSumOp , por ejemplo, PauliSumOp.from_list([("III", 1)]). Ver #7225 para más detalles.

  • Se ha corregido un error por el que el método QuantumCircuit.qasm() podía devolver OpenQASM 2 instrucciones con identificadores no válidos. El mismo error se ha corregido en UnitaryGate.

  • Se ha solucionado un problema por el que al intentar mostrar bits sin registro se producía un fallo en mpl y en los cajones del circuito latex . Se ha eliminado un _ inicial de la visualización de los números de bits sin registro en el cajón text . Corregido #6732.

  • Para los registros de un bit, todos los cajones de circuito muestran ahora sólo el nombre del registro y ya no muestran el subíndice 0 . Corregido #5784.

  • Corregidas las colisiones de nombres de registros implícitos en QuantumCircuit.qasm cuando se trata de qubits y clbits sin registro. Anteriormente, los qubits y clbits sin registro se colocaban en los correspondientes qreg y creg , ambos llamados regless, a pesar de la colisión. Ahora tendrán nombres separados, generados de forma determinista, que no entrarán en conflicto con ningún nombre de registro definido por el usuario en el circuito.

  • Se ha solucionado un problema en la programación de circuitos con operaciones clbits, por ejemplo, mediciones, puertas condicionales, actualización ASAPSchedule, ALAPScheduley AlignMeasures. Los planificadores actualizados asumen que todas las operaciones de E/S en clbits no llevan tiempo, measure escribe el valor medido en un clbit al final, y c_if lee el valor condicional en clbit(s) al principio. Corregido #7006.

  • La llamada a transpile en una lista vacía ahora devolverá correctamente una lista vacía sin emitir una advertencia. Corregido #7287.

  • Se ha corregido un problema en PiecewiseChebyshev cuando la función a aproximar era constante. En estos casos, ahora debe pasar la constante directamente como el argumento f_x , en lugar de utilizar una función, como:

    from qiskit.circuit.library.arithmetic import PiecewiseChebyshev
    
    PiecewiseChebyshev(1.0, degree=3)

    Ver #6707 para más detalles.

  • Si una instancia del algoritmo HHL se construyera sin una propiedad QuantumInstance (por defecto), los intentos de utilizar las propiedades getter y setter para leer o establecer una instancia más tarde fallarían. Los getters y setters ahora funcionan como se esperaba.

  • El método QuantumCircuit.qasm() edita ahora los nombres de las copias de las instrucciones presentes en el circuito, no las instrucciones originales que viven en circuit.data. Consulte el nº 6952 para más detalles.

  • Se ha corregido un error en PauliSumOp.permute() que provocaba el error:

    QiskitError: 'Pauli string label "" is not valid.'

    si la permutación tuviera el mismo número de términos de Pauli. La llamada a permute([2, 1, 0]) en X ^ Y ^ Z ya no produce un error, y ahora devuelve Z ^ Y ^ X.

  • Se ha corregido un error por el que los límites de los parámetros del mezclador en la ventana QAOAAnsatz no se establecían.

  • Determinación fija de las operaciones finales (barreras y medidas) en pass RemoveFinalMeasurements y en método remove_final_measurements() de la clase QuantumCircuit que antes sólo consideraba los nodos inmediatamente anteriores a un nodo de salida.

  • Determinación fija de las operaciones finales en pass RemoveFinalMeasurements y en el método remove_final_measurements() de la clase QuantumCircuit que podía considerar erróneamente una barrera como final, incluso si otras operaciones del circuito la seguían.

  • Corregida la eliminación de registros clásicos multibit en pass RemoveFinalMeasurements y en el método remove_final_measurements() de la clase QuantumCircuit donde los registros clásicos no se eliminaban aunque otros bits estuvieran ociosos, a menos que se hiciera una medida final en todos y cada uno de los bits. Ahora, los registros clásicos que quedan inactivos como resultado de la eliminación de las medidas finales y las barreras se eliminan siempre. Los bits clásicos se eliminan si son referenciados sólo por los registros eliminados o no son referenciados en absoluto y se vuelven ociosos debido a la eliminación. Esta corrección también añade una gestión adecuada de los registros con bits subyacentes compartidos.

  • Se ha corregido un problema con RemoveFinalMeasurements que podía provocar que el DAGCircuit resultante no fuera válida. Consulte el nº 7196 para obtener más información.

  • Solucionado un problema con el método remove_final_measurements() de la clase QuantumCircuit que provocaba que QuantumCircuit.clbits fuera incorrecto después de la invocación. Consulte el nº 7089 para más detalles.

  • Al estrechar un operador cero vacío en qiskit.opflowel código, al detectar que era cero, registraba una advertencia y devolvía el operador original. Tales operadores se encuentran comúnmente en los operadores auxiliares, cuando se utiliza Qiskit Nature, y el comportamiento anterior causó que VQE lanzara una excepción ya que los operadores cónicos distintos de cero eran un número diferente de qubits de los operadores cónicos cero (ya que el cónico ha devuelto el operador de entrada sin cambios). Ahora, el código reducirá correctamente un operador cero de forma que el número de qubits se reduzca según lo esperado y coincidirá con los operadores cónicos distintos de cero, por ejemplo, `0*"IIII"` cuando reduzcamos 3 qubits se convertirá en 0*"I".

  • Se ha corregido un problema con el método draw() y la función circuit_drawer() por el que un estilo personalizado establecido a través del archivo de configuración del usuario (es decir, settings.conf) ignoraría el valor establecido del campo circuit_mpl_style si el kwarg style de la función/método no estuviera establecido.

Otras notas

  • La cadena lanzada para qiskit.circuit.ParameterExpression ya no tiene precisión total. Esto elimina el final 0s cuando se imprimen parámetros que están vinculados a flotadores. Esto tiene consecuencias para la serialización QASM y el cajón de texto del circuito:

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> str(x.bind({x:0.5}))
    '0.5'   # instead of '0.500000000000000'
  • El sitio QAOAAnsatz se ha actualizado para utilizar el símbolo de parámetro γ para el operador de coste y β para el operador mezclador, como es la notación estándar en la literatura de QAOA.

Aer 0.9.1

No cambia

Ignis 0.7.0

Preludio

Esta versión deja obsoleto el proyecto Qiskit Ignis, que ha sido sustituido por el proyecto Qiskit Experiments y cuyo desarrollo activo ha cesado. A pesar de estar obsoleto, se seguirán realizando correcciones de errores críticos y correcciones de compatibilidad para proporcionar a los usuarios una oportunidad suficiente para migrar fuera de Ignis. Una vez transcurrido el periodo de obsoleto (que no será inferior a 3 meses a partir de esta versión), el proyecto se retirará y archivará.

Nuevas funciones

  • Actualizado el protocolo de acreditación para utilizar la rutina de adaptación de https://arxiv.org/abs/2103.06603. AccreditationFitter tiene ahora los métodos FullAccreditation (protocolo anterior) y MeanAccreditation (nuevo protocolo). Además, la introducción de datos se ha modificado para utilizar el objeto de resultado AppendResult o una lista de cadenas AppendStrings. qiskit.ignis.verification.QOTPCorrectString() también se añadió.

  • Se ha añadido la opción de generación analítica rápida de gráficos de síndrome. El RepetitionCode tiene ahora un nuevo argumento bool brute, que permite seguir utilizando el método de fuerza bruta. Clase auxiliar RepetitionCodeSyndromeGenerator añadida para facilitarlo.

  • RepetitionCode tiene ahora argumentos de palabra clave resets y delay. El primero determina si se insertan compuertas de reset tras la medición. Este último permite especificar un tiempo (en dt) para un retardo después de cada medición (y puesta a cero, si procede).

    El método syndrome_measurement() de RepetitionCode tiene ahora argumentos de palabra clave final y delay. El primero determina si hay que añadir puertas de reinicio de acuerdo con el global resets, o sobrescribirlo con un comportamiento apropiado para la ronda final de mediciones del síndrome. Este último permite especificar un tiempo (en dt) para un retardo después de cada medición (y puesta a cero, si procede).

  • La clase RepetitionCode soporta ahora la codificación con estados base x. Se puede utilizar estableciendo el argumento de la palabra clave xbasis al construir un objeto RepetitionCode .

Notas de actualización

  • Se ha eliminado la palabra clave reset del método syndrome_measurement() de RepetitionCode. Se sustituye por el argumento de palabra clave global resets para la clase, así como por el argumento de palabra clave final para syndrome_measurement. En los casos en los que anteriormente se añadía la ronda de medición final utilizando reset=False para evitar las puertas de reinicio final, ahora se debe utilizar final=True.

  • Elimine ParametrizedSchedule de update_u_gates().

    ParametrizedSchedule fue obsoleto como parte de Qiskit-terra 0.17.0 y será eliminado en la próxima versión. La función actualiza ahora las puertas u con programas Schedule que implican objetos Parameter no asignados.

Notas sobre características en desuso

  • Métodos obsoletos en AccreditationFitter a saber bound_variation_distance y single_protocol__run

  • El proyecto Qiskit Ignis en su conjunto ha quedado obsoleto y el proyecto será retirado y archivado en el futuro. Aunque está obsoleto, sólo se realizarán correcciones de compatibilidad y correcciones de errores críticos en el proyecto. En lugar de utilizar Qiskit Ignis debe migrar a utilizar Qiskit Experimentos en su lugar. Puede consultar la guía de migración:

    https://github.com/qiskit-community/qiskit-ignis#migration-guide

¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.