Esempio n. 1
0
    def test_fusion_default(self, method, device):
        """Test fusion threshsold"""
        shots = 100
        num_qubits = 5
        backend = self.backend(method=method, device=device)
        circuit = transpile(QFT(num_qubits), backend, optimization_level=0)
        if method == "unitary":
            circuit.save_unitary()
        elif method == "superop":
            circuit.save_superop()
        else:
            circuit.measure_all()

        backend.set_options(**self.fusion_options(enabled=True))
        result = backend.run(circuit, shots=shots).result()

        expected_max_qubits = 5
        expected_threshold = 14
        if method == "density_matrix":
            expected_max_qubits = 2
            expected_threshold = 7
        elif method == "unitary":
            expected_max_qubits = 5
            expected_threshold = 7
        elif method == "superop":
            expected_max_qubits = 2
            expected_threshold = 7

        meta = result.results[0].metadata.get('fusion', None)
        self.assertEqual(meta.get('max_fused_qubits', None),
                         expected_max_qubits)
        self.assertEqual(meta.get('threshold', None), expected_threshold)
Esempio n. 2
0
    def test_fusion_qft(self):
        """Test Fusion with qft"""
        shots = 100
        num_qubits = 8
        backend = self.backend(method="statevector")
        circuit = transpile(QFT(num_qubits), backend, optimization_level=0)
        circuit.measure_all()

        options_disabled = self.fusion_options(enabled=False, threshold=1)
        result_disabled = backend.run(circuit, shots=shots,
                                      **options_disabled).result()
        meta_disabled = self.fusion_metadata(result_disabled)

        options_enabled = self.fusion_options(enabled=True, threshold=1)
        result_enabled = backend.run(circuit, shots=shots,
                                     **options_enabled).result()
        meta_enabled = self.fusion_metadata(result_enabled)

        self.assertTrue(getattr(result_disabled, 'success', 'False'))
        self.assertTrue(getattr(result_enabled, 'success', 'False'))
        self.assertFalse(meta_disabled.get('enabled'))
        self.assertTrue(meta_enabled.get('enabled'))
        self.assertTrue(meta_enabled.get('applied'))
        self.assertDictAlmostEqual(result_enabled.get_counts(circuit),
                                   result_disabled.get_counts(circuit),
                                   delta=0.0,
                                   msg="fusion for qft was failed")
Esempio n. 3
0
    def __init__(
        self,
        num_eval_qubits: int,
        a_factory: Optional[CircuitFactory] = None,
        q_factory: Optional[CircuitFactory] = None,
        i_objective: Optional[int] = None,
        iqft: Optional[QuantumCircuit] = None,
        quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None
    ) -> None:
        r"""
        Args:
            num_eval_qubits: Number of evaluation qubits, has a min. value of 1.
            a_factory: The CircuitFactory subclass object representing the problem unitary.
            q_factory: The CircuitFactory subclass object representing an amplitude estimation
                sample (based on a_factory).
            i_objective: The index of the objective qubit, i.e. the qubit marking 'good' solutions
                with the state \|1> and 'bad' solutions with the state \|0>.
            iqft: The Inverse Quantum Fourier Transform component, defaults to using a standard IQFT
                when None
            quantum_instance: Quantum Instance or Backend
        """
        validate_min('num_eval_qubits', num_eval_qubits, 1)
        super().__init__(a_factory, q_factory, i_objective, quantum_instance)

        # get parameters
        self._m = num_eval_qubits
        self._M = 2**num_eval_qubits
        self._iqft = iqft or QFT(self._m).inverse()
        self._circuit = None
        self._ret = {}  # type: Dict[str, Any]
Esempio n. 4
0
    def test_fusion_threshold(self, method, device):
        """Test fusion threshsold"""
        shots = 100
        num_qubits = 5
        backend = self.backend(method=method, device=device)
        circuit = transpile(QFT(num_qubits), backend, optimization_level=0)
        circuit.measure_all()

        with self.subTest(msg='at threshold'):
            backend.set_options(
                **self.fusion_options(enabled=True, threshold=num_qubits))
            result = backend.run(circuit, shots=shots).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertFalse(meta.get('applied'))

        with self.subTest(msg='below threshold'):
            backend.set_options(
                **self.fusion_options(enabled=True, threshold=num_qubits + 1))
            result = backend.run(circuit, shots=shots).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertFalse(meta.get('applied'))

        with self.subTest(msg='above threshold'):
            backend.set_options(
                **self.fusion_options(enabled=True, threshold=num_qubits - 1))
            result = backend.run(circuit, shots=shots).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertTrue(meta.get('applied'))
Esempio n. 5
0
def aqft(n_qubits, n_circuits):
    approximation_degree = int(math.log(n_qubits, 2) + 2)
    return [
        QFT(num_qubits=n_qubits,
            approximation_degree=n_qubits - approximation_degree,
            do_swaps=False) for i in range(n_circuits)
    ], n_circuits
Esempio n. 6
0
def create_eigs(matrix, num_ancillae, num_time_slices, negative_evals):
    ne_qfts = [None, None]
    if negative_evals:
        num_ancillae += 1
        ne_qfts = [QFT(num_ancillae - 1), QFT(num_ancillae - 1).inverse()]
    ret = EigsQPE(MatrixOperator(matrix=matrix),
                   QFT(num_ancillae).inverse(),
                   num_time_slices=num_time_slices,
                   num_ancillae=num_ancillae,
                   expansion_mode='suzuki',
                   expansion_order=2,
                   evo_time=None,  # This is t, can set to: np.pi*3/4
                   negative_evals=negative_evals,
                   ne_qfts=ne_qfts)
    #print(ret.construct_circuit(mode='circuit'))
    return ret
Esempio n. 7
0
    def test_chunk_QFTWithFusion(self):
        """Test multi-chunk with fused QFT (testing multi-chunk diagonal matrix)"""
        shots = 100
        num_qubits = 8
        backend_options = self.BACKEND_OPTS.copy()
        backend_options['fusion_enable'] = True
        backend_options['fusion_threshold'] = 5
        backend_options["blocking_qubits"] = 4
        backend_options_no_chunk = self.BACKEND_OPTS.copy()
        backend_options_no_chunk.pop("blocking_enable")
        backend_options_no_chunk.pop("blocking_qubits")
        backend_options_no_chunk['fusion_enable'] = True
        backend_options_no_chunk['fusion_threshold'] = 5

        circuit = transpile(QFT(num_qubits),
                            backend=self.SIMULATOR,
                            optimization_level=0)
        circuit.measure_all()
        qobj = assemble(circuit, shots=shots, memory=True)
        result = self.SIMULATOR.run(qobj, **backend_options_no_chunk).result()
        counts_no_chunk = result.get_counts(circuit)
        result = self.SIMULATOR.run(qobj, **backend_options).result()
        counts = result.get_counts(circuit)

        self.assertEqual(counts_no_chunk,counts)
Esempio n. 8
0
    def _construct_circuit(self, a: int, N: int, n: int,
                           measurement: bool) -> QuantumCircuit:
        x_qreg = QuantumRegister(2 * n, 'x')
        y_qreg = QuantumRegister(n, 'y')
        aux_qreg = AncillaRegister(self._get_aux_register_size(n), 'aux')

        circuit = QuantumCircuit(x_qreg,
                                 y_qreg,
                                 aux_qreg,
                                 name=self._get_name(a, N))

        circuit.h(x_qreg)
        circuit.x(y_qreg[0])

        modular_exponentiation_gate = self._modular_exponentiation_gate(
            a, N, n)
        circuit.append(modular_exponentiation_gate, circuit.qubits)

        iqft = QFT(len(x_qreg)).inverse().to_gate()
        circuit.append(iqft, x_qreg)

        if measurement:
            x_creg = ClassicalRegister(2 * n, name='xValue')
            circuit.add_register(x_creg)
            circuit.measure(x_qreg, x_creg)

        return circuit
Esempio n. 9
0
    def test_fusion_qft(self):
        """Test Fusion with qft"""
        shots = 100
        num_qubits = 8
        circuit = transpile(QFT(num_qubits),
                            backend=self.SIMULATOR,
                            basis_gates=['u1', 'u2', 'u3', 'cx', 'cz'],
                            optimization_level=0)
        circuit.measure_all()
        qobj = assemble([circuit],
                        self.SIMULATOR,
                        shots=shots,
                        seed_simulator=1)

        backend_options = self.fusion_options(enabled=False, threshold=1)
        result_disabled = self.SIMULATOR.run(qobj, **backend_options).result()
        meta_disabled = self.fusion_metadata(result_disabled)

        backend_options = self.fusion_options(enabled=True, threshold=1)
        result_enabled = self.SIMULATOR.run(qobj, **backend_options).result()
        meta_enabled = self.fusion_metadata(result_enabled)

        self.assertTrue(getattr(result_disabled, 'success', 'False'))
        self.assertTrue(getattr(result_enabled, 'success', 'False'))
        self.assertFalse(meta_disabled.get('enabled'))
        self.assertTrue(meta_enabled.get('enabled'))
        self.assertTrue(meta_enabled.get('applied'))
        self.assertDictAlmostEqual(result_enabled.get_counts(circuit),
                                   result_disabled.get_counts(circuit),
                                   delta=0.0,
                                   msg="fusion for qft was failed")
Esempio n. 10
0
class BeauregardShor(Shor):
    def _construct_circuit_with_semiclassical_QFT(self, a: int, N: int,
                                                  n: int) -> QuantumCircuit:
        self._qft = QFT(n + 1, do_swaps=False).to_gate()
        self._iqft = self._qft.inverse()

        phi_add_N = phi_constant_adder(get_angles(N, n + 1))
        self._iphi_add_N = phi_add_N.inverse()
        self._c_phi_add_N = phi_add_N.control(1)

        return super()._construct_circuit_with_semiclassical_QFT(a, N, n)

    def _get_aux_register_size(self, n: int) -> int:
        return n + 2

    @property
    def _prefix(self) -> str:
        return 'Beauregard'

    def _modular_exponentiation_gate(self, constant: int, N: int,
                                     n: int) -> Instruction:
        return modular_exponentiation_gate(constant, N, n)

    def _modular_multiplication_gate(self, constant: int, N: int,
                                     n: int) -> Instruction:
        return controlled_modular_multiplication_gate(constant, N, n,
                                                      self._c_phi_add_N,
                                                      self._iphi_add_N,
                                                      self._qft, self._iqft)
Esempio n. 11
0
def create_eigs(matrix, num_auxiliary, num_time_slices, negative_evals):
    ne_qfts = [None, None]
    if negative_evals:
        num_auxiliary += 1
        ne_qfts = [QFT(num_auxiliary - 1), QFT(num_auxiliary - 1).inverse()]

    return EigsQPE(
        MatrixOperator(matrix=matrix),
        QFT(num_auxiliary).inverse(),
        num_time_slices=num_time_slices,
        num_ancillae=num_auxiliary,
        expansion_mode='suzuki',
        expansion_order=2,
        evo_time=None,  # This is t, can set to: np.pi*3/4
        negative_evals=negative_evals,
        ne_qfts=ne_qfts)
Esempio n. 12
0
    def test_initialize_qft(self):
        """Test that initialize with a complex statevector and qft work."""
        k = 5
        state = (1 / np.sqrt(8)) * np.array([
            np.exp(-1j * 2 * np.pi * k * (0) / 8),
            np.exp(-1j * 2 * np.pi * k * (1) / 8),
            np.exp(-1j * 2 * np.pi * k * (2) / 8),
            np.exp(-1j * 2 * np.pi * k * 3 / 8),
            np.exp(-1j * 2 * np.pi * k * 4 / 8),
            np.exp(-1j * 2 * np.pi * k * 5 / 8),
            np.exp(-1j * 2 * np.pi * k * 6 / 8),
            np.exp(-1j * 2 * np.pi * k * 7 / 8),
        ])

        qubits = 3
        qc = QuantumCircuit(qubits, qubits)
        qc.initialize(state)
        qc.append(QFT(qubits), range(qubits))
        qc.measure(range(qubits), range(qubits))
        qpy_file = io.BytesIO()
        dump(qc, qpy_file)
        qpy_file.seek(0)
        new_circ = load(qpy_file)[0]
        self.assertEqual(qc, new_circ)
        self.assertEqual([x[0].label for x in qc.data],
                         [x[0].label for x in new_circ.data])
Esempio n. 13
0
    def test_qft_num_gates(self, num_qubits, approximation_degree,
                           insert_barriers):
        """Test the number of gates in the QFT and the approximated QFT."""
        basis_gates = ['h', 'swap', 'cu1']

        qft = QFT(num_qubits,
                  approximation_degree=approximation_degree,
                  insert_barriers=insert_barriers)
        ops = transpile(qft, basis_gates=basis_gates).count_ops()

        with self.subTest(msg='assert H count'):
            self.assertEqual(ops['h'], num_qubits)

        with self.subTest(msg='assert swap count'):
            self.assertEqual(ops['swap'], num_qubits // 2)

        with self.subTest(msg='assert CU1 count'):
            expected = sum(
                max(
                    0,
                    min(num_qubits - 1 - k, num_qubits - 1 -
                        approximation_degree)) for k in range(num_qubits))
            self.assertEqual(ops.get('cu1', 0), expected)

        with self.subTest(msg='assert barrier count'):
            expected = qft.num_qubits if insert_barriers else 0
            self.assertEqual(ops.get('barrier', 0), expected)
Esempio n. 14
0
    def test_qae_circuit(self, efficient_circuit):
        """Test circuits resulting from canonical amplitude estimation.

        Build the circuit manually and from the algorithm and compare the resulting unitaries.
        """
        prob = 0.5

        for m in [2, 5]:
            qae = AmplitudeEstimation(m, BernoulliStateIn(prob))
            angle = 2 * np.arcsin(np.sqrt(prob))

            # manually set up the inefficient AE circuit
            qr_eval = QuantumRegister(m, 'a')
            qr_objective = QuantumRegister(1, 'q')
            circuit = QuantumCircuit(qr_eval, qr_objective)

            # initial Hadamard gates
            for i in range(m):
                circuit.h(qr_eval[i])

            # A operator
            circuit.ry(angle, qr_objective)

            if efficient_circuit:
                qae.grover_operator = BernoulliGrover(prob)
                for power in range(m):
                    circuit.cry(2 * 2**power * angle, qr_eval[power],
                                qr_objective[0])
            else:
                oracle = QuantumCircuit(1)
                oracle.z(0)

                state_preparation = QuantumCircuit(1)
                state_preparation.ry(angle, 0)
                grover_op = GroverOperator(oracle, state_preparation)
                for power in range(m):
                    circuit.compose(grover_op.power(2**power).control(),
                                    qubits=[qr_eval[power], qr_objective[0]],
                                    inplace=True)

            # fourier transform
            iqft = QFT(m, do_swaps=False).inverse().reverse_bits()
            circuit.append(iqft.to_instruction(), qr_eval)

            actual_circuit = qae.construct_circuit(measurement=False)

            self.assertEqual(Operator(circuit), Operator(actual_circuit))
Esempio n. 15
0
    def __init__(self,
                 N: int = 15,
                 a: int = 2,
                 quantum_instance: Optional[Union[QuantumInstance,
                                                  BaseBackend]] = None,
                 job_id=None) -> None:
        """
        Args:
            N: The integer to be factored, has a min. value of 3.
            a: A random integer that satisfies a < N and gcd(a, N) = 1, has a min. value of 2.
            quantum_instance: Quantum Instance or Backend

         Raises:
            ValueError: Invalid input
        """
        validate_min('N', N, 3)
        validate_min('a', a, 2)
        super().__init__(quantum_instance)
        self.job_id = job_id
        self._n = None
        self._up_qreg = None
        self._down_qreg = None
        self._aux_qreg = None

        # check the input integer
        if N < 1 or N % 2 == 0:
            raise ValueError(
                'The input needs to be an odd integer greater than 1.')

        self._N = N

        if a >= N or math.gcd(a, self._N) != 1:
            raise ValueError(
                'The integer a needs to satisfy a < N and gcd(a, N) = 1.')

        self._a = a

        self._ret = {'factors': []}

        # check if the input integer is a power
        tf, b, p = is_power(N, return_decomposition=True)
        if tf:
            logger.info('The input integer is a power: %s=%s^%s.', N, b, p)
            self._ret['factors'].append(b)

        self._qft = QFT(do_swaps=False)
        self._iqft = self._qft.inverse()
Esempio n. 16
0
    def construct_circuit(self, measurement: bool = False) -> QuantumCircuit:
        """Construct circuit.

        Args:
            measurement: Boolean flag to indicate if measurement should be included in the circuit.

        Returns:
            Quantum circuit.
        """

        # Get n value used in Shor's algorithm, to know how many qubits are used
        self._n = math.ceil(math.log(self._N, 2))
        self._qft.num_qubits = self._n + 1
        self._iqft.num_qubits = self._n + 1
        self._qft_dag = circuit_to_dag(self._qft)
        self._iqft_dag = circuit_to_dag(self._iqft)

        # quantum register where the sequential QFT is performed
        self._up_qreg = QuantumRegister(2 * self._n, name='up')
        # quantum register where the multiplications are made
        self._down_qreg = QuantumRegister(self._n, name='down')
        # auxiliary quantum register used in addition and multiplication
        self._aux_qreg = QuantumRegister(self._n + 2, name='aux')

        # Create Quantum Circuit
        circuit = QuantumCircuit(self._up_qreg, self._down_qreg,
                                 self._aux_qreg)

        # Initialize down register to 1 and create maximal superposition in top register
        circuit.u2(0, np.pi, self._up_qreg)
        circuit.u3(np.pi, 0, np.pi, self._down_qreg[0])

        tdags = []
        dag_self = circuit_to_dag(circuit)

        # Apply the multiplication gates as showed in
        # the report in order to create the exponentiation
        for i in range(0, 2 * self._n):
            tdags += self._controlled_multiple_mod_N_tdags(
                self._up_qreg[i], self._down_qreg, self._aux_qreg,
                int(pow(self._a, pow(2, i))))

        for tdag in tdags:
            dag_compose_with_tagged(dag_self, tdag)
        composed_circuit = dag_to_circuit(dag_self)
        circuit.__dict__.update(composed_circuit.__dict__)

        # Apply inverse QFT
        iqft = QFT(len(self._up_qreg), inverse=True)
        circuit.compose(iqft, qubits=self._up_qreg)

        if measurement:
            up_cqreg = ClassicalRegister(2 * self._n, name='m')
            circuit.add_register(up_cqreg)
            circuit.measure(self._up_qreg, up_cqreg)

        logger.info(summarize_circuits(circuit))

        return circuit
Esempio n. 17
0
    def test_qae_circuit(self, efficient_circuit):
        """Test circuits resulting from canonical amplitude estimation.

        Build the circuit manually and from the algorithm and compare the resulting unitaries.
        """

        prob = 0.5

        for m in range(2, 7):
            qae = AmplitudeEstimation(m, a_factory=BernoulliAFactory(prob))
            angle = 2 * np.arcsin(np.sqrt(prob))

            # manually set up the inefficient AE circuit
            q_ancilla = QuantumRegister(m, 'a')
            q_objective = QuantumRegister(1, 'q')
            circuit = QuantumCircuit(q_ancilla, q_objective)

            # initial Hadamard gates
            for i in range(m):
                circuit.h(q_ancilla[i])

            # A operator
            circuit.ry(angle, q_objective)

            if efficient_circuit:
                qae.q_factory = BernoulliQFactory(qae.a_factory)
                for power in range(m):
                    circuit.cry(2 * 2 ** power * angle, q_ancilla[power], q_objective[0])

            else:
                q_factory = QFactory(qae.a_factory, i_objective=0)
                for power in range(m):
                    for _ in range(2**power):
                        q_factory.build_controlled(circuit, q_objective, q_ancilla[power])

            # fourier transform
            iqft = QFT(m, do_swaps=False).inverse()
            circuit.append(iqft.to_instruction(), q_ancilla)

            expected_unitary = self._unitary.execute(circuit).get_unitary()

            actual_circuit = qae.construct_circuit(measurement=False)
            actual_unitary = self._unitary.execute(actual_circuit).get_unitary()

            diff = np.sum(np.abs(actual_unitary - expected_unitary))
            self.assertAlmostEqual(diff, 0)
    def test_fusion_theshold(self):
        """Test fusion threhsold"""
        shots = 100
        threshold = 6
        backend_options = self.fusion_options(enabled=True,
                                              threshold=threshold)

        with self.subTest(msg='below fusion threshold'):
            circuit = transpile(QFT(threshold - 1),
                                self.SIMULATOR,
                                basis_gates=['u1', 'u2', 'u3', 'cx', 'cz'],
                                optimization_level=0)
            circuit.measure_all()
            qobj = assemble(circuit, self.SIMULATOR, shots=shots)
            result = self.SIMULATOR.run(qobj, **backend_options).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertFalse(meta.get('applied'))

        with self.subTest(msg='at fusion threshold'):
            circuit = transpile(QFT(threshold),
                                self.SIMULATOR,
                                basis_gates=['u1', 'u2', 'u3', 'cx', 'cz'],
                                optimization_level=0)
            circuit.measure_all()
            qobj = assemble(circuit, self.SIMULATOR, shots=shots)
            result = self.SIMULATOR.run(qobj, **backend_options).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertFalse(meta.get('applied'))

        with self.subTest(msg='above fusion threshold'):
            circuit = transpile(QFT(threshold + 1),
                                self.SIMULATOR,
                                basis_gates=['u1', 'u2', 'u3', 'cx', 'cz'],
                                optimization_level=0)
            circuit.measure_all()
            qobj = assemble(circuit, self.SIMULATOR, shots=shots)
            result = self.SIMULATOR.run(qobj, **backend_options).result()
            self.assertSuccess(result)
            meta = self.fusion_metadata(result)
            self.assertTrue(meta.get('enabled'))
            self.assertTrue(meta.get('applied'))
Esempio n. 19
0
 def test_drawings(self):
     """Test draw method"""
     qc1 = QFT(5)
     sv = Statevector.from_instruction(qc1)
     with self.subTest(msg="str(statevector)"):
         str(sv)
     for drawtype in ["repr", "text", "latex", "latex_source", "qsphere", "hinton", "bloch"]:
         with self.subTest(msg=f"draw('{drawtype}')"):
             sv.draw(drawtype)
Esempio n. 20
0
 def test_drawings(self):
     """Test draw method"""
     qc1 = QFT(5)
     dm = DensityMatrix.from_instruction(qc1)
     with self.subTest(msg="str(density_matrix)"):
         str(dm)
     for drawtype in ["repr", "text", "latex", "latex_source", "qsphere", "hinton", "bloch"]:
         with self.subTest(msg=f"draw('{drawtype}')"):
             dm.draw(drawtype)
Esempio n. 21
0
 def test_save_amplitudes_cache_blocking(self, method, device, params):
     """Test save_amplitudes instruction"""
     self._test_save_amplitudes(QFT(3),
                                params,
                                False,
                                method=method,
                                device=device,
                                blocking_qubits=2,
                                max_parallel_threads=1)
    def construct_circuit(circuit=None,
                          qubits=None,
                          inverse=False,
                          approximation_degree=0,
                          do_swaps=True):
        """Construct the circuit representing the desired state vector.

        Args:
            circuit (QuantumCircuit): The optional circuit to extend from.
            qubits (Union(QuantumRegister, list[Qubit])): The optional qubits to construct
                the circuit with.
            approximation_degree (int): degree of approximation for the desired circuit
            inverse (bool): Boolean flag to indicate Inverse Quantum Fourier Transform
            do_swaps (bool): Boolean flag to specify if swaps should be included to align
                the qubit order of
                input and output. The output qubits would be in reversed order without the swaps.

        Returns:
            QuantumCircuit: quantum circuit
        Raises:
            AquaError: invalid input
        """
        warnings.warn(
            'The class FourierTransformCircuits is deprecated and will be removed '
            'no earlier than 3 months after the release 0.7.0. You should use the '
            'qiskit.circuit.library.QFT class instead.',
            DeprecationWarning,
            stacklevel=2)

        if circuit is None:
            raise AquaError('Missing input QuantumCircuit.')

        if qubits is None:
            raise AquaError('Missing input qubits.')

        qft = QFT(len(qubits),
                  approximation_degree=approximation_degree,
                  do_swaps=do_swaps)
        if inverse:
            qft = qft.inverse()

        circuit.append(qft.to_instruction(), qubits)

        return circuit
Esempio n. 23
0
    def _build_operator(
            self, func_dict: Dict[Union[int, Tuple[int, int]],
                                  int]) -> QuantumCircuit:
        """Creates a circuit for the state preparation operator.

        Args:
            func_dict: Representation of the QUBO problem. The keys should be subscripts of the
                coefficients (e.g. x_1 -> 1), with the constant (if present) being represented with
                a key of -1 (i.e. d[-1] = constant). Quadratic coefficients should use a tuple for
                the key, with the corresponding subscripts inside (e.g. 2*x_1*x_2 -> d[(1,2)]=2).

        Returns:
            Circuit object describing the state preparation operator.
        """

        # Build initial circuit.
        key_val = QuantumRegister(self._num_key + self._num_value, "key_value")
        circuit = QuantumCircuit(key_val)
        if self._measurement:
            measure = ClassicalRegister(self._num_key + self._num_value)
            circuit.add_register(measure)
        circuit.h(key_val)

        # Linear Coefficients.
        for i in range(self._num_value):
            if func_dict.get(-1, 0) != 0:
                circuit.u1(
                    1 / 2**self._num_value * 2 * np.pi * 2**i * func_dict[-1],
                    key_val[self._num_key + i])
            for j in range(self._num_key):
                if func_dict.get(j, 0) != 0:
                    circuit.cu1(
                        1 / 2**self._num_value * 2 * np.pi * 2**i *
                        func_dict[j], key_val[j], key_val[self._num_key + i])

        # Quadratic Coefficients.
        for i in range(self._num_value):
            for k, v in func_dict.items():
                if isinstance(k, tuple):
                    a_v = [key_val[int(k[0])], key_val[int(k[1])]]
                    b_v = key_val[self._num_key + i]
                    circuit.mcu1(1 / 2**self._num_value * 2 * np.pi * 2**i * v,
                                 a_v, b_v)

        # Add IQFT. Adding swaps at the end of the IQFT, not the beginning.
        iqft = QFT(self._num_value, do_swaps=False).inverse()
        value = [
            key_val[v]
            for v in range(self._num_key, self._num_key + self._num_value)
        ]
        circuit.compose(iqft, qubits=value, inplace=True)

        for i in range(len(value) // 2):
            circuit.swap(value[i], value[-(i + 1)])

        return circuit
Esempio n. 24
0
 def test_drawings(self):
     """Test draw method"""
     qc1 = QFT(5)
     dm = DensityMatrix.from_instruction(qc1)
     with self.subTest(msg='str(density_matrix)'):
         str(dm)
     for drawtype in ['repr', 'text', 'latex', 'latex_source',
                      'qsphere', 'hinton', 'bloch']:
         with self.subTest(msg=f"draw('{drawtype}')"):
             dm.draw(drawtype)
Esempio n. 25
0
    def construct_circuit(self,
                          N: int,
                          a: int = 2,
                          measurement: bool = False) -> QuantumCircuit:
        """Construct quantum part of the algorithm.

        Args:
            N: The odd integer to be factored, has a min. value of 3.
            a: Any integer that satisfies 1 < a < N and gcd(a, N) = 1.
            measurement: Boolean flag to indicate if measurement should be included in the circuit.

        Returns:
            Quantum circuit.

        """
        self._validate_input(N, a)

        # Get n value used in Shor's algorithm, to know how many qubits are used
        n = N.bit_length()

        # quantum register where the sequential QFT is performed
        up_qreg = QuantumRegister(2 * n, name="up")
        # quantum register where the multiplications are made
        down_qreg = QuantumRegister(n, name="down")
        # auxiliary quantum register used in addition and multiplication
        aux_qreg = QuantumRegister(n + 2, name="aux")

        # Create Quantum Circuit
        circuit = QuantumCircuit(up_qreg,
                                 down_qreg,
                                 aux_qreg,
                                 name=f"Shor(N={N}, a={a})")

        # Create maximal superposition in top register
        circuit.h(up_qreg)

        # Initialize down register to 1
        circuit.x(down_qreg[0])

        # Apply modulo exponentiation
        modulo_power = self._power_mod_N(n, N, a)
        circuit.append(modulo_power, circuit.qubits)

        # Apply inverse QFT
        iqft = QFT(len(up_qreg)).inverse().to_gate()
        circuit.append(iqft, up_qreg)

        if measurement:
            up_cqreg = ClassicalRegister(2 * n, name="m")
            circuit.add_register(up_cqreg)
            circuit.measure(up_qreg, up_cqreg)

        logger.info(summarize_circuits(circuit))

        return circuit
Esempio n. 26
0
    def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae):
        """Test the QPE algorithm."""
        self.log.debug('Testing QPE')
        qubit_op = self._dict[qubit_op]
        exact_eigensolver = NumPyMinimumEigensolver(qubit_op)
        results = exact_eigensolver.run()

        ref_eigenval = results.eigenvalue
        ref_eigenvec = results.eigenstate
        self.log.debug('The exact eigenvalue is:       %s', ref_eigenval)
        self.log.debug('The corresponding eigenvector: %s', ref_eigenvec)

        state_in = Custom(qubit_op.num_qubits, state_vector=ref_eigenvec)
        iqft = QFT(n_ancillae).inverse()

        qpe = QPE(qubit_op,
                  state_in,
                  iqft,
                  num_time_slices,
                  n_ancillae,
                  expansion_mode='suzuki',
                  expansion_order=2,
                  shallow_circuit_concat=True)

        backend = BasicAer.get_backend(simulator)
        quantum_instance = QuantumInstance(backend,
                                           shots=100,
                                           seed_transpiler=1,
                                           seed_simulator=1)

        # run qpe
        result = qpe.run(quantum_instance)

        # report result
        self.log.debug('top result str label:         %s',
                       result.top_measurement_label)
        self.log.debug('top result in decimal:        %s',
                       result.top_measurement_decimal)
        self.log.debug('stretch:                      %s', result.stretch)
        self.log.debug('translation:                  %s', result.translation)
        self.log.debug('final eigenvalue from QPE:    %s', result.eigenvalue)
        self.log.debug('reference eigenvalue:         %s', ref_eigenval)
        self.log.debug('ref eigenvalue (transformed): %s',
                       (ref_eigenval + result.translation) * result.stretch)
        self.log.debug(
            'reference binary str label:   %s',
            decimal_to_binary(
                (ref_eigenval.real + result.translation) * result.stretch,
                max_num_digits=n_ancillae + 3,
                fractional_part_only=True))

        self.assertAlmostEqual(result.eigenvalue.real,
                               ref_eigenval.real,
                               delta=2e-2)
Esempio n. 27
0
 def test_drawings(self):
     """Test draw method"""
     qc1 = QFT(5)
     sv = Statevector.from_instruction(qc1)
     with self.subTest(msg='str(statevector)'):
         str(sv)
     for drawtype in [
             'text', 'latex', 'latex_source', 'qsphere', 'hinton', 'bloch'
     ]:
         with self.subTest(msg=f"draw('{drawtype}')"):
             sv.draw(drawtype)
Esempio n. 28
0
    def _create_eigs(matrix, num_ancillae, negative_evals):
        # Adding an additional flag qubit for negative eigenvalues
        ne_qfts = [None, None]
        if negative_evals:
            num_ancillae += 1
            ne_qfts = [QFT(num_ancillae - 1), QFT(num_ancillae - 1).inverse()]

        iqft = QFT(num_ancillae).inverse()

        eigs_qpe = EigsQPE(MatrixOperator(matrix=matrix),
                           iqft,
                           num_time_slices=1,
                           num_ancillae=num_ancillae,
                           expansion_mode='suzuki',
                           expansion_order=2,
                           evo_time=None,
                           negative_evals=negative_evals,
                           ne_qfts=ne_qfts)

        return eigs_qpe
Esempio n. 29
0
    def _create_eigs(matrix,
                     num_ancillae,
                     negative_evals,
                     use_circuit_library=True):
        # Adding an additional flag qubit for negative eigenvalues
        ne_qfts = [None, None]
        if not use_circuit_library:
            warnings.filterwarnings('ignore', category=DeprecationWarning)

        if negative_evals:
            num_ancillae += 1
            if use_circuit_library:
                ne_qfts = [
                    QFT(num_ancillae - 1),
                    QFT(num_ancillae - 1).inverse()
                ]
            else:
                ne_qfts = [
                    StandardQFTS(num_ancillae - 1),
                    StandardIQFTS(num_ancillae - 1)
                ]

        if use_circuit_library:
            iqft = QFT(num_ancillae).inverse()
        else:
            iqft = StandardIQFTS(num_ancillae)

        eigs_qpe = EigsQPE(MatrixOperator(matrix=matrix),
                           iqft,
                           num_time_slices=1,
                           num_ancillae=num_ancillae,
                           expansion_mode='suzuki',
                           expansion_order=2,
                           evo_time=None,
                           negative_evals=negative_evals,
                           ne_qfts=ne_qfts)

        if not use_circuit_library:
            warnings.filterwarnings('always', category=DeprecationWarning)

        return eigs_qpe
def modular_exponentiation_gate(constant: int, N: int, n: int) -> Gate:
    x_qreg = QuantumRegister(2 * n, name='x')
    y_qreg = QuantumRegister(n, name='y')
    aux_qreg = QuantumRegister(n + 1, name='aux')

    circuit = QuantumCircuit(x_qreg,
                             y_qreg,
                             aux_qreg,
                             name=f'Exp({constant})_Mod_{N}')

    qft = QFT(n, do_swaps=False).to_gate()
    iqft = qft.inverse()

    for i in range(2 * n):
        partial_constant = pow(constant, pow(2, i), mod=N)
        circuit.append(
            controlled_modular_multiplication_gate(partial_constant, N, n, qft, iqft),
            list(chain([x_qreg[i]], y_qreg, aux_qreg))
        )

    return circuit.to_gate()