Esempio n. 1
0
    def __init__(self,
                 num_qubits,
                 depth=3,
                 entangler_map=None,
                 entanglement='full',
                 initial_state=None,
                 entanglement_gate='cz',
                 skip_unentangled_qubits=False,
                 skip_final_ry=False):
        """Constructor.

        Args:
            num_qubits (int) : number of qubits
            depth (int) : number of rotation layers
            entangler_map (list[list]): describe the connectivity of qubits, each list describes
                                        [source, target], or None for full entanglement.
                                        Note that the order is the list is the order of
                                        applying the two-qubit gate.
            entanglement (str): 'full', 'linear' or 'sca'
            initial_state (InitialState): an initial state object
            entanglement_gate (str): cz or cx
            skip_unentangled_qubits (bool): skip the qubits not in the entangler_map
            skip_final_ry (bool): skip the final layer of Y rotations
        """
        self.validate(locals())
        super().__init__()
        self._num_qubits = num_qubits
        self._depth = depth
        self._entanglement = entanglement

        if entangler_map is None:
            self._entangler_map = VariationalForm.get_entangler_map(
                entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(
                entangler_map, num_qubits)

        # determine the entangled qubits
        all_qubits = []
        for src, targ in self._entangler_map:
            all_qubits.extend([src, targ])
        self._entangled_qubits = sorted(list(set(all_qubits)))
        self._initial_state = initial_state
        self._entanglement_gate = entanglement_gate
        self._skip_unentangled_qubits = skip_unentangled_qubits
        self._skip_final_ry = skip_final_ry

        # for the first layer
        self._num_parameters = len(self._entangled_qubits) if self._skip_unentangled_qubits \
            else self._num_qubits

        # for repeated block (minus one ry layer if we skip the last)
        self._num_parameters += len(self._entangled_qubits) * (depth - 1) if skip_final_ry \
            else len(self._entangled_qubits) * depth

        # CRx gates have an additional parameter per entanglement
        if entanglement_gate == 'crx':
            self._num_parameters += len(self._entangler_map) * depth

        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
Esempio n. 2
0
    def __init__(self,
                 num_qubits,
                 depth=3,
                 entangler_map=None,
                 entanglement='full',
                 initial_state=None):
        """Constructor.

        Args:
            num_qubits (int) : number of qubits
            depth (int) : number of rotation layers
            entangler_map (list[list]): describe the connectivity of qubits, each list describes
                                        [source, target], or None for full entanglement.
                                        Note that the order is the list is the order of
                                        applying the two-qubit gate.
            entanglement (str): 'full' or 'linear'
            initial_state (InitialState): an initial state object
        """
        self.validate(locals())
        super().__init__()
        self._num_qubits = num_qubits
        self._depth = depth
        if entangler_map is None:
            self._entangler_map = VariationalForm.get_entangler_map(
                entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(
                entangler_map, num_qubits)
        self._initial_state = initial_state
        self._num_parameters = num_qubits + depth * \
            (num_qubits + len(self._entangler_map))
        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
Esempio n. 3
0
    def __init__(self, num_qubits: Optional[int] = None, reps: int = 1, ladder: bool = False,
                 excitations: Optional[List[List[int]]] = None,
                 entanglement: Union[str, List[int]] = 'full',
                 initial_state: Optional[InitialState] = None) -> None:
        """

        Args:
            num_qubits: number of qubits
            reps: number of replica of basic module
            ladder: use ladder of CNOTs between to indices in the entangling block
            excitations: indices corresponding to the excitations to include in the circuit
            entanglement: physical connections between the qubits
            initial_state: an initial state object
        """

        super().__init__()
        self._num_qubits = num_qubits
        self._reps = reps
        self._excitations = None
        self._entangler_map = None
        self._initial_state = None
        self._ladder = ladder
        self._num_parameters = len(excitations) * reps
        self._excitations = excitations
        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
        self._num_qubits = num_qubits
        if isinstance(entanglement, str):
            self._entangler_map = VariationalForm.get_entangler_map(entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(entanglement, num_qubits)
        self._initial_state = initial_state
        self._support_parameterized_circuit = True
Esempio n. 4
0
    def __init__(self,
                 num_qubits,
                 depth=3,
                 entangler_map=None,
                 entanglement='full',
                 initial_state=None):
        """Constructor.

        Args:
            num_qubits (int) : number of qubits
            depth (int) : number of rotation layers
            entangler_map (dict) : dictionary of entangling gates, in the format
                                    { source : [list of targets] },
                                    or None for full entanglement.
            entanglement (str): 'full' or 'linear'
            initial_state (InitialState): an initial state object
        """
        self.validate(locals())
        super().__init__()
        self._num_parameters = num_qubits * (depth + 1) * 2
        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
        self._num_qubits = num_qubits
        self._depth = depth
        if entangler_map is None:
            self._entangler_map = VariationalForm.get_entangler_map(
                entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(
                entangler_map, num_qubits)
        self._initial_state = initial_state
Esempio n. 5
0
    def __init__(self,
                 num_qubits,
                 depth=3,
                 entangler_map=None,
                 entanglement='full',
                 initial_state=None,
                 skip_unentangled_qubits=False):
        """Constructor.

        Args:
            num_qubits (int) : number of qubits
            depth (int) : number of rotation layers
            entangler_map (list[list]): describe the connectivity of qubits, each list describes
                                        [source, target], or None for full entanglement.
                                        Note that the order is the list is the order of
                                        applying the two-qubit gate.
            entanglement (str): 'full' or 'linear'
            initial_state (InitialState): an initial state object
            skip_unentangled_qubits (bool): skip the qubits not in the entangler_map
        """
        validate(locals(), self._INPUT_SCHEMA)
        super().__init__()
        self._num_qubits = num_qubits
        self._depth = depth
        if entangler_map is None:
            self._entangler_map = VariationalForm.get_entangler_map(
                entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(
                entangler_map, num_qubits)
        # determine the entangled qubits
        all_qubits = []
        for src, targ in self._entangler_map:
            all_qubits.extend([src, targ])

        self._entangled_qubits = sorted(list(set(all_qubits)))
        self._initial_state = initial_state
        self._skip_unentangled_qubits = skip_unentangled_qubits

        # for the first layer
        self._num_parameters = len(self._entangled_qubits) if self._skip_unentangled_qubits \
            else self._num_qubits
        # for repeated block
        self._num_parameters += (len(self._entangled_qubits) +
                                 len(self._entangler_map)) * depth
        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
        self._support_parameterized_circuit = True
Esempio n. 6
0
    def __init__(self,
                 num_dis: int = 4,
                 num_con: int = 2,
                 depth: int = 4,
                 entangler_map: Optional[List[List[int]]] = None,
                 entanglement: str = 'full',
                 initial_state: Optional[InitialState] = None,
                 entanglement_gate: str = 'cz',
                 skip_unentangled_qubits: bool = False) -> None:
        """
        Args:
            num_qubits: Number of qubits, has a minimum value of 1.
            depth: Number of rotation layers, has a minimum value of 1.
            entangler_map: Describe the connectivity of qubits, each list pair describes
                [source, target], or None for as defined by `entanglement`.
                Note that the order is the list is the order of applying the two-qubit gate.
            entanglement: ('full' | 'linear') overridden by 'entangler_map` if its
                provided. 'full' is all-to-all entanglement, 'linear' is nearest-neighbor.
            initial_state: An initial state object
            entanglement_gate: ('cz' | 'cx')
            skip_unentangled_qubits: Skip the qubits not in the entangler_map
        """
        warnings.warn(
            'The qiskit.aqua.components.variational_forms.RYRZ object is deprecated as '
            'of 0.7.0 and will be removed no sooner than 3 months after the release. You '
            'should use qiskit.circuit.library.EfficientSU2 (uses CX entangling) or '
            'qiskit.circuit.library.TwoLocal instead.',
            DeprecationWarning,
            stacklevel=2)

        num_qubits = num_con + num_dis
        validate_min('num_qubits', num_qubits, 1)
        validate_min('depth', depth, 1)
        validate_in_set('entanglement', entanglement, {'full', 'linear'})
        validate_in_set('entanglement_gate', entanglement_gate, {'cz', 'cx'})
        super().__init__()
        self._num_qubits = num_qubits
        self._num_con = num_con
        self._num_dis = num_dis
        self._depth = depth
        if entangler_map is None:
            self._entangler_map = VariationalForm.get_entangler_map(
                entanglement, num_qubits)
        else:
            self._entangler_map = VariationalForm.validate_entangler_map(
                entangler_map, num_qubits)
        # determine the entangled qubits
        all_qubits = []
        for src, targ in self._entangler_map:
            all_qubits.extend([src, targ])
        self._entangled_qubits = sorted(list(set(all_qubits)))
        self._initial_state = initial_state
        self._entanglement_gate = entanglement_gate
        self._skip_unentangled_qubits = skip_unentangled_qubits

        # for the first layer
        self._num_parameters = len(self._entangled_qubits) * 2 if self._skip_unentangled_qubits \
            else self._num_qubits * 2
        # for repeated block
        self._num_parameters += len(self._entangled_qubits) * depth * 2
        self._support_parameterized_circuit = True

        # Feature Encoder params
        # U3(theta1, theta2, 0)
        self._num_parameters += 16 * self._num_dis

        self._pre_params = 16 * self._num_dis

        self._bounds = [(-np.pi, np.pi)] * self._num_parameters
Esempio n. 7
0
    def construct_circuit(self, parameters, q=None):
        """
        Construct the variational form, given its parameters.

        Args:
            parameters (numpy.ndarray): circuit parameters.
            q (QuantumRegister): Quantum Register for the circuit.

        Returns:
            QuantumCircuit: a quantum circuit with given `parameters`

        Raises:
            ValueError: the number of parameters is incorrect.
        """
        if len(parameters) != self._num_parameters:
            raise ValueError('The number of parameters has to be {}'.format(
                self._num_parameters))

        if q is None:
            q = QuantumRegister(self._num_qubits, name='q')
        if self._initial_state is not None:
            circuit = self._initial_state.construct_circuit('circuit', q)
        else:
            circuit = QuantumCircuit(q)

        param_idx = 0
        for qubit in range(self._num_qubits):
            if not self._skip_unentangled_qubits or qubit in self._entangled_qubits:
                circuit.u3(parameters[param_idx], 0.0, 0.0, q[qubit])  # ry
                param_idx += 1

        for block in range(self._depth):
            circuit.barrier(q)
            if self._entanglement == 'sca':
                self._entangler_map = VariationalForm.get_entangler_map(
                    self._entanglement, self._num_qubits, offset=block)

            for src, targ in self._entangler_map:
                if self._entanglement_gate == 'cz':
                    circuit.u2(0.0, np.pi, q[targ])  # h
                    circuit.cx(q[src], q[targ])
                    circuit.u2(0.0, np.pi, q[targ])  # h

                elif self._entanglement_gate == 'crx':
                    circuit.cu3(parameters[param_idx], -np.pi / 2, np.pi / 2,
                                q[src], q[targ])  # crx
                    param_idx += 1

                else:
                    circuit.cx(q[src], q[targ])

            # Skip the final RY layer if it is specified and we reached the
            # last block
            if not self._skip_final_ry or block != self._depth - 1:
                circuit.barrier(q)
                for qubit in self._entangled_qubits:
                    circuit.u3(parameters[param_idx], 0.0, 0.0, q[qubit])  # ry
                    param_idx += 1
        circuit.barrier(q)

        return circuit