Source code for qiskit_quantum_knn.qknn.quantumgates

from typing import Optional

import numpy as np
import qiskit as qk
import qiskit.extensions.quantum_initializer as qi
from qiskit.circuit.controlledgate import ControlledGate
from qiskit.circuit.gate import Gate

"""
Extra file containing some decomposed quantum gates to get familiar with them 
and Qiskit.
"""


[docs]def swap(): """A self-written decomposition of the SWAP-gate. Example: .. jupyter-execute:: from qiskit_quantum_knn.qknn.quantumgates import swap swap_circ = swap() print(swap_circ.definition.draw()) Returns: Instruction: the SWAP-gate. """ swap_circuit = qk.QuantumCircuit(2, name='swap_gate') swap_circuit.cx(0, 1) swap_circuit.cx(1, 0) swap_circuit.cx(0, 1) return swap_circuit.to_instruction()
[docs]def fidelity_instruction(): r"""A decomposition of the SWAP-measurement. The fidelity between the state on ``q_1`` and the state on ``q_2`` is defined as: .. math:: \mathbb{P}(q_0 = 0) - \mathbb{P}(q_0 = 1) Example: .. jupyter-execute:: from qiskit_quantum_knn.qknn.quantumgates import fidelity_instruction fid_inst = fidelity_instruction() print(fid_inst.definition.draw()) Returns: Instruction: The Fidelity gate (swap measurement). """ fidelity_circ = qk.QuantumCircuit(3, 1) fidelity_circ.h(0) fidelity_circ.cswap(0, 1, 2) fidelity_circ.h(0) fidelity_circ.measure(0, 0) fidelity_instr = fidelity_circ.to_instruction() return fidelity_instr
[docs]def init_to_state(reg_to_init: qk.QuantumRegister, init_state: np.ndarray, name: Optional[str] = None) -> Gate: """Initialize a :class:`QuantumRegister` to the provided state. Args: reg_to_init (QuantumRegister): register which needs to be initialized. init_state (np.ndarray): state to which the :py:attr:`reg_to_init` must be initialized to. name (str): optional, name for the ``init_gate``. Raises: ValueError: if the register and state do not have the same dimension. Returns: Gate: The initialiser. A gate of size ``reg_to_init.size`` which performs the initialization. """ # check if provided values are correct if len(init_state) != 2 ** len(reg_to_init): raise ValueError( "Dimensionality of the init_state does not coincide with the " "length of the register to initialise to: is {0} and {1}".format( len(init_state), len(reg_to_init) ) ) init_circ = qk.QuantumCircuit(reg_to_init, name=name) # create temp circuit init = qi.Isometry(init_state, 0, 0) # create Isometry for init init_circ.append(init, reg_to_init) # apply init to temp circuit basis_gates = ['u1', 'u2', 'u3', 'cx'] # list basis gates # transpile circuit so that it is decomposed to the basis gates above, # making it unitary and possible to convert from Instruction to Gate transpiled = qk.transpile(init_circ, basis_gates=basis_gates) init_gate = transpiled.to_gate() # convert to Gate return init_gate
[docs]def controlled_initialize(reg_to_init: qk.QuantumRegister, init_state: np.ndarray, num_ctrl_qubits: Optional[int] = 1, name: Optional[str] = None) -> ControlledGate: """Initialize a register to provided state with control. This method uses :py:func:`init_to_state` to create the initialiser. Args: reg_to_init (QuantumRegister): register which needs to be initialized. init_state (np.ndarray): state to which the ``reg_to_init`` must be initialized to. num_ctrl_qubits (int): optional, number of desired controls. name (str): optional, name for the ``init_gate``. Returns: ControlledGate: The produced controlled initialise. A Gate of size ``reg_to_init.size + num_ctrl_qubits`` which performs the initialize with control. """ # create the init state init_gate = init_to_state(reg_to_init, init_state, name) # make it controlled controlled_init = init_gate.control(num_ctrl_qubits=num_ctrl_qubits) return controlled_init