예제 #1
0
 def test_two_qubit_synthesis_not_pulse_optimal(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     backend = FakeVigo()
     conf = backend.configuration()
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         coupling_map=coupling_map,
         backend_props=backend.properties(),
         pulse_optimize=False,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()  # pylint: disable=no-member
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertGreaterEqual(num_ops["sx"], 16)
    def test_hidden_identity_block(self):
        """Test that extracting linear functions and synthesizing them back
        results in an equivalent circuit when a linear block represents
        the identity matrix."""

        # Create a circuit with multiple non-linear blocks
        circuit1 = QuantumCircuit(3)
        circuit1.h(0)
        circuit1.h(1)
        circuit1.h(2)
        circuit1.swap(0, 2)
        circuit1.swap(0, 2)
        circuit1.h(0)
        circuit1.h(1)
        circuit1.h(2)

        # collect linear functions
        circuit2 = PassManager(CollectLinearFunctions()).run(circuit1)

        # synthesize linear functions
        circuit3 = PassManager(LinearFunctionsSynthesis()).run(circuit2)

        # check that we have an equivalent circuit
        self.assertEqual(Operator(circuit1), Operator(circuit3))
 def test_all_gates_in_basis_after_translation_with_target(self):
     """Test circuit with gates in basis after conditional translation."""
     target = FakeBackend5QV2().target
     basis_gates = ["cx", "u"]
     property_set = {}
     analysis_pass = GatesInBasis(basis_gates, target)
     circuit = QuantumCircuit(2)
     circuit.h(0)
     circuit.cx(0, 1)
     circuit.measure_all()
     analysis_pass(circuit, property_set=property_set)
     self.assertFalse(property_set["all_gates_in_basis"])
     pm = PassManager()
     pm.append(analysis_pass)
     pm.append(
         BasisTranslator(SessionEquivalenceLibrary,
                         basis_gates,
                         target=target),
         condition=lambda property_set: not property_set[
             "all_gates_in_basis"],
     )
     pm.append(analysis_pass)
     pm.run(circuit)
     self.assertTrue(pm.property_set["all_gates_in_basis"])
예제 #4
0
 def test_expand_method(self, num_qubits_1, num_qubits_2):
     """Test expand method"""
     samples = 5
     num_gates = 10
     seed = 800
     gates = 'all'
     for i in range(samples):
         circ1 = random_clifford_circuit(num_qubits_1,
                                         num_gates,
                                         gates=gates,
                                         seed=seed + i)
         circ2 = random_clifford_circuit(num_qubits_2,
                                         num_gates,
                                         gates=gates,
                                         seed=seed + samples + i)
         cliff1 = Clifford(circ1)
         cliff2 = Clifford(circ2)
         value = cliff1.expand(cliff2)
         circ = QuantumCircuit(num_qubits_1 + num_qubits_2)
         circ.append(circ1, range(num_qubits_1))
         circ.append(circ2, range(num_qubits_1,
                                  num_qubits_1 + num_qubits_2))
         target = Clifford(circ)
         self.assertEqual(target, value)
예제 #5
0
    def test_repetetive_parameter_setting(self):
        """Test alternate setting of parameters and circuit construction."""
        x = Parameter("x")
        circuit = QuantumCircuit(1)
        circuit.rx(x, 0)

        nlocal = NLocal(1,
                        entanglement_blocks=circuit,
                        reps=3,
                        insert_barriers=True)
        with self.subTest(msg="immediately after initialization"):
            self.assertEqual(len(nlocal.parameters), 3)

        with self.subTest(msg="after circuit construction"):
            self.assertEqual(len(nlocal.parameters), 3)

        q = Parameter("q")
        nlocal.assign_parameters([x, q, q], inplace=True)
        with self.subTest(msg="setting parameter to Parameter objects"):
            self.assertEqual(nlocal.parameters, set({x, q}))

        nlocal.assign_parameters([0, -1], inplace=True)
        with self.subTest(msg="setting parameter to numbers"):
            self.assertEqual(nlocal.parameters, set())
    def test_name_collision(self):
        """Name collision during ancilla allocation."""
        qr_ancilla = QuantumRegister(3, 'ancilla')
        circuit = QuantumCircuit(qr_ancilla)
        circuit.h(qr_ancilla)
        dag = circuit_to_dag(circuit)

        initial_layout = Layout()
        initial_layout[0] = qr_ancilla[0]
        initial_layout[1] = qr_ancilla[1]
        initial_layout[2] = qr_ancilla[2]

        pass_ = FullAncillaAllocation(self.cmap5)
        pass_.property_set['layout'] = initial_layout
        pass_.run(dag)
        after_layout = pass_.property_set['layout']

        qregs = {v.register for v in after_layout.get_virtual_bits().keys()}
        self.assertEqual(2, len(qregs))
        self.assertIn(qr_ancilla, qregs)
        qregs.remove(qr_ancilla)
        other_reg = qregs.pop()
        self.assertEqual(len(other_reg), 2)
        self.assertRegex(other_reg.name, r'^ancilla\d+$')
예제 #7
0
    def test_non_commutative_circuit_2(self):
        """A simple circuit where no gates commute

        qr0:----.-------------
                |
        qr1:---(+)------.-----
                        |
        qr2:---[H]-----(+)----
        """
        qr = QuantumRegister(3, "qr")
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[1])
        circuit.h(qr[2])
        circuit.cx(qr[1], qr[2])
        dag = circuit_to_dag(circuit)

        self.pass_.run(dag)

        expected = {
            qr[0]: [[0], [6], [1]],
            qr[1]: [[2], [6], [8], [3]],
            qr[2]: [[4], [7], [8], [5]],
        }
        self.assertCommutationSet(self.pset["commutation_set"], expected)
예제 #8
0
 def test_run_path_with_expressions_multiple_params_per_instruction(self):
     """Test parameterized circuit path via backed.run()"""
     shots = 1000
     backend = AerSimulator()
     circuit = QuantumCircuit(2)
     theta = Parameter('theta')
     theta_squared = theta * theta
     circuit.rx(theta, 0)
     circuit.cx(0, 1)
     circuit.rz(theta_squared, 1)
     circuit.u(theta, theta_squared, theta, 1)
     circuit.measure_all()
     parameter_binds = [{theta: [0, pi, 2 * pi]}] * 3
     res = backend.run([circuit] * 3,
                       shots=shots,
                       parameter_binds=parameter_binds).result()
     counts = res.get_counts()
     self.assertEqual(counts, [{
         '00': shots
     }, {
         '01': shots
     }, {
         '00': shots
     }] * 3)
예제 #9
0
 def test_amplitude_damping_error(self):
     """Test amplitude damping error damps to correct state"""
     qr = QuantumRegister(1, 'qr')
     cr = ClassicalRegister(1, 'cr')
     circuit = QuantumCircuit(qr, cr)
     circuit.x(qr)  # prepare + state
     for _ in range(30):
         # Add noisy identities
         circuit.barrier(qr)
         circuit.i(qr)
     circuit.barrier(qr)
     circuit.measure(qr, cr)
     shots = 4000
     backend = AerSimulator()
     # test noise model
     error = amplitude_damping_error(0.75, 0.25)
     noise_model = NoiseModel()
     noise_model.add_all_qubit_quantum_error(error, 'id')
     # Execute
     target = {'0x0': 3 * shots / 4, '0x1': shots / 4}
     circuit = transpile(circuit, basis_gates=noise_model.basis_gates, optimization_level=0)
     result = backend.run(circuit, shots=shots, noise_model=noise_model).result()
     self.assertSuccess(result)
     self.compare_counts(result, [circuit], [target], delta=0.05 * shots)
예제 #10
0
    def _define(self):
        """Calculate a subcircuit that implements this initialization

        Implements a recursive initialization algorithm, including optimizations,
        from "Synthesis of Quantum Logic Circuits" Shende, Bullock, Markov
        https://arxiv.org/abs/quant-ph/0406176v5

        Additionally implements some extra optimizations: remove zero rotations and
        double cnots.
        """
        # call to generate the circuit that takes the desired vector to zero
        disentangling_circuit = self.gates_to_uncompute()

        # invert the circuit to create the desired vector from zero (assuming
        # the qubits are in the zero state)
        initialize_gate = disentangling_circuit.to_instruction().inverse()

        q = QuantumRegister(self.num_qubits)
        initialize_circuit = QuantumCircuit(q)
        # TODO: make initialize an Instruction, and insert reset
        # TODO: avoid explicit reset if compiler determines a |0> state
        initialize_circuit.append(initialize_gate, q[:])

        self.definition = initialize_circuit.data
예제 #11
0
    def test_statevector(self, expression, good_states):
        """Circuit generation"""
        oracle = PhaseOracle(expression)
        num_qubits = oracle.num_qubits
        circuit = QuantumCircuit(num_qubits)
        circuit.h(range(num_qubits))
        circuit.compose(oracle, inplace=True)
        statevector = Statevector.from_instruction(circuit)

        valid_state = -1 / sqrt(2**num_qubits)
        invalid_state = 1 / sqrt(2**num_qubits)

        states = list(range(2**num_qubits))
        expected_valid = [state in good_states for state in states]
        result_valid = [
            isclose(statevector.data[state], valid_state) for state in states
        ]

        expected_invalid = [state not in good_states for state in states]
        result_invalid = [
            isclose(statevector.data[state], invalid_state) for state in states
        ]
        self.assertListEqual(expected_valid, result_valid)
        self.assertListEqual(expected_invalid, result_invalid)
예제 #12
0
def replace_q_indices(circuit, q_nums, qr):
    """
    Take a circuit that is ordered from 0,1,2 qubits and replace 0 with the
    qubit label in the first index of q_nums, 1 with the second index...

    Args:
        circuit (QuantumCircuit): circuit to operate on
        q_nums (list): list of qubit indices
        qr (QuantumRegister): A quantum register to use for the output circuit

    Returns:
        QuantumCircuit: updated circuit
    """

    new_circuit = QuantumCircuit(qr)
    bit_indices = {bit: index for index, bit in enumerate(circuit.qubits)}
    for instr, qargs, cargs in circuit.data:
        new_qargs = [
            qr[q_nums[x]] for x in [bit_indices[arg] for arg in qargs]
        ]
        new_op = copy.deepcopy((instr, new_qargs, cargs))
        new_circuit.data.append(new_op)

    return new_circuit
예제 #13
0
    def get_ghz_po(self, n, delta):
        """
        Get Parity Oscillation circuit
        """

        circ, initial_layout = self.get_ghz_layout(n)
        q = QuantumRegister(n, 'q')
        rotate = QuantumCircuit(q)

        rotate.barrier()
        rotate.u2(delta, -delta, q)
        rotate.barrier()
        rotate = transpile(rotate,
                           backend=self.backend,
                           initial_layout=initial_layout)

        meas = self.get_measurement_circ(n, 'q', 'c', True)
        meas = transpile(meas,
                         backend=self.backend,
                         initial_layout=initial_layout)

        new_circ = circ + rotate + meas

        return new_circ, initial_layout
예제 #14
0
def dagdependency_to_circuit(dagdependency):
    """Build a ``QuantumCircuit`` object from a ``DAGDependency``.

    Args:
        dagdependency (DAGDependency): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag dependency.
    """

    name = dagdependency.name or None
    circuit = QuantumCircuit(*dagdependency.qregs.values(),
                             *dagdependency.cregs.values(),
                             name=name)

    circuit.calibrations = dagdependency.calibrations

    for node in dagdependency.get_nodes():
        # Get arguments for classical control (if any)
        inst = node.op.copy()
        inst.condition = node.condition
        circuit._append(inst, node.qargs, node.cargs)

    return circuit
    def setUp(self):
        super().setUp()

        # specify "run configuration"
        self.quantum_instance_sv = QuantumInstance(
            Aer.get_backend('statevector_simulator'))
        self.quantum_instance_qasm = QuantumInstance(
            Aer.get_backend('qasm_simulator'), shots=100)

        # define feature map and variational form
        num_qubits = 2
        feature_map = ZZFeatureMap(num_qubits, reps=1)
        var_form = RealAmplitudes(num_qubits, reps=1)

        # construct circuit
        self.qc = QuantumCircuit(num_qubits)
        self.qc.append(feature_map, range(2))
        self.qc.append(var_form, range(2))

        # store params
        self.input_params = list(feature_map.parameters)
        self.weight_params = list(var_form.parameters)

        # define interpret functions
        def interpret_1d(x):
            return sum([s == '1' for s in '{0:0b}'.format(x)]) % 2

        self.interpret_1d = interpret_1d
        self.output_shape_1d = 2  # takes values in {0, 1}

        def interpret_2d(x):
            return np.array([self.interpret_1d(x), 2 * self.interpret_1d(x)])

        self.interpret_2d = interpret_2d
        self.output_shape_2d = (
            2, 3)  # 1st dim. takes values in {0, 1} 2nd dim in {0, 1, 2}
예제 #16
0
 def to_instruction(self):
     """Convert to Pauli circuit instruction."""
     from math import pi
     pauli, phase = self._to_label(self.z,
                                   self.x,
                                   self._phase[0],
                                   full_group=False,
                                   return_phase=True)
     if len(pauli) == 1:
         gate = {
             'I': IGate(),
             'X': XGate(),
             'Y': YGate(),
             'Z': ZGate()
         }[pauli]
     else:
         gate = PauliGate(pauli)
     if not phase:
         return gate
     # Add global phase
     circuit = QuantumCircuit(self.num_qubits, name=str(self))
     circuit.global_phase = -phase * pi / 2
     circuit.append(gate, range(self.num_qubits))
     return circuit.to_instruction()
    def test_node_middle_of_blocks(self):
        """Test that a node surrounded by blocks stays in the same place

        This is a larger test to ensure multiple blocks can all be collected
        and added back in the correct order.

        blocks = [['cx', 'id'], ['cx', 'id'], ['id', 'cx'], ['id', 'cx']]

        q_0: |0>──■───────────────────■──
                ┌─┴─┐┌────┐   ┌────┐┌─┴─┐
        q_1: |0>┤ X ├┤ Id ├─X─┤ Id ├┤ X ├
                ├───┤├────┤ │ ├────┤├───┤
        q_2: |0>┤ X ├┤ Id ├─X─┤ Id ├┤ X ├
                └─┬─┘└────┘   └────┘└─┬─┘
        q_3: |0>──■───────────────────■──

        """
        qc = QuantumCircuit(4)
        qc.cx(0, 1)
        qc.cx(3, 2)
        qc.i(1)
        qc.i(2)

        qc.swap(1, 2)

        qc.i(1)
        qc.i(2)
        qc.cx(0, 1)
        qc.cx(3, 2)

        pass_manager = PassManager()
        pass_manager.append(Collect2qBlocks())
        pass_manager.append(ConsolidateBlocks())
        qc1 = transpile(qc, pass_manager=pass_manager)

        self.assertEqual(qc, qc1)
예제 #18
0
    def test_list_op_parameters(self):
        """Test that Parameters are stored correctly in a List Operator"""
        lam = Parameter('λ')
        phi = Parameter('φ')
        omega = Parameter('ω')

        mat_op = PrimitiveOp([[0, 1], [1, 0]], coeff=omega)

        qc = QuantumCircuit(1)
        qc.rx(phi, 0)
        qc_op = PrimitiveOp(qc)

        op1 = SummedOp([mat_op, qc_op])

        params = [phi, omega]
        self.assertEqual(op1.parameters, set(params))

        # check list nesting case
        op2 = PrimitiveOp([[1, 0], [0, -1]], coeff=lam)

        list_op = ListOp([op1, op2])

        params.append(lam)
        self.assertEqual(list_op.parameters, set(params))
예제 #19
0
    def test_measure_to_registers_when_conditionals(self):
        """Verify assemble_circuits maps all measure ops on to a register slot
        for a circuit containing conditionals."""
        qr = QuantumRegister(2)
        cr1 = ClassicalRegister(1)
        cr2 = ClassicalRegister(2)
        qc = QuantumCircuit(qr, cr1, cr2)

        qc.measure(qr[0], cr1)  # Measure not required for a later conditional
        qc.measure(qr[1], cr2[1])  # Measure required for a later conditional
        qc.h(qr[1]).c_if(cr2, 3)

        qobj = assemble(qc)
        validate_qobj_against_schema(qobj)

        first_measure, second_measure = [
            op for op in qobj.experiments[0].instructions
            if op.name == 'measure'
        ]

        self.assertTrue(hasattr(first_measure, 'register'))
        self.assertEqual(first_measure.register, first_measure.memory)
        self.assertTrue(hasattr(second_measure, 'register'))
        self.assertEqual(second_measure.register, second_measure.memory)
    def pauli_evolution(self, pauli_string, time):
        """Get the evolution block for the given pauli string."""
        # for some reason this is in reversed order
        pauli_string = pauli_string[::-1]

        # trim the pauli string if identities are included
        trimmed = []
        indices = []
        for i, pauli in enumerate(pauli_string):
            if pauli != "I":
                trimmed += [pauli]
                indices += [i]

        evo = QuantumCircuit(len(pauli_string))

        if len(trimmed) == 0:
            return evo

        def basis_change(circuit, inverse=False):
            for i, pauli in enumerate(pauli_string):
                if pauli == "X":
                    circuit.h(i)
                elif pauli == "Y":
                    circuit.rx(-np.pi / 2 if inverse else np.pi / 2, i)

        def cx_chain(circuit, inverse=False):
            num_cx = len(indices) - 1
            for i in reversed(range(num_cx)) if inverse else range(num_cx):
                circuit.cx(indices[i], indices[i + 1])

        basis_change(evo)
        cx_chain(evo)
        evo.p(self.alpha * time, indices[-1])
        cx_chain(evo, inverse=True)
        basis_change(evo, inverse=True)
        return evo
예제 #21
0
    def _define(self):
        """Calculate a subcircuit that implements this initialization

        Implements a recursive initialization algorithm, including optimizations,
        from "Synthesis of Quantum Logic Circuits" Shende, Bullock, Markov
        https://arxiv.org/abs/quant-ph/0406176v5

        Additionally implements some extra optimizations: remove zero rotations and
        double cnots.
        """
        # call to generate the circuit that takes the desired vector to zero
        disentangling_circuit = self.gates_to_uncompute()

        # invert the circuit to create the desired vector from zero (assuming
        # the qubits are in the zero state)
        initialize_instr = disentangling_circuit.to_instruction().inverse()

        q = QuantumRegister(self.num_qubits, 'q')
        initialize_circuit = QuantumCircuit(q, name='init_def')
        for qubit in q:
            initialize_circuit.append(Reset(), [qubit])
        initialize_circuit.append(initialize_instr, q[:])

        self.definition = initialize_circuit.data
예제 #22
0
    def get_ghz_mqc_para(
        self,
        n: int,
        full_measurement: bool = True
    ) -> Tuple[QuantumCircuit, Parameter, Dict]:
        """
        Get a parametrized MQC circuit.
        Remember that get_counts() method accepts
        an index now, not a circuit

        Args:
            n: number of qubits
            full_measurement: Whether to append full measurement, or
                only on the first qubit
        Returns:
            The MQC circuit, its delta parameter, and the initial GHZ layout
        """

        circ, initial_layout = self.get_ghz_layout(n)
        q = QuantumRegister(n, 'q')
        rotate = QuantumCircuit(q)
        delta = Parameter('t')
        rotate.barrier()
        rotate.u1(delta, q)
        rotate.barrier()
        rotate.x(q)
        rotate.barrier()
        rotate = transpile(rotate,
                           backend=self.backend,
                           initial_layout=initial_layout)
        meas = self.get_measurement_circ(n, 'q', 'c', full_measurement)
        meas = transpile(meas,
                         backend=self.backend,
                         initial_layout=initial_layout)
        new_circ = circ + rotate + circ.inverse() + meas
        return new_circ, delta, initial_layout
예제 #23
0
    def repeat(self, n):
        """Creates an instruction with `gate` repeated `n` amount of times.

        Args:
            n (int): Number of times to repeat the instruction

        Returns:
            qiskit.circuit.Instruction: Containing the definition.

        Raises:
            CircuitError: If n < 1.
        """
        if int(n) != n or n < 1:
            raise CircuitError(
                "Repeat can only be called with strictly positive integer.")

        n = int(n)

        instruction = self._return_repeat(n)
        qargs = [] if self.num_qubits == 0 else QuantumRegister(
            self.num_qubits, "q")
        cargs = [] if self.num_clbits == 0 else ClassicalRegister(
            self.num_clbits, "c")

        if instruction.definition is None:
            # pylint: disable=cyclic-import
            from qiskit import QuantumCircuit

            qc = QuantumCircuit()
            if qargs:
                qc.add_register(qargs)
            if cargs:
                qc.add_register(cargs)
            qc.data = [(self, qargs[:], cargs[:])] * n
        instruction.definition = qc
        return instruction
    def test_successors_predecessors(self):
        """Test the method direct_successors."""

        circuit = QuantumCircuit(self.qreg, self.creg)
        circuit.h(self.qreg[0])
        circuit.x(self.qreg[0])
        circuit.h(self.qreg[0])
        circuit.x(self.qreg[1])
        circuit.h(self.qreg[0])
        circuit.measure(self.qreg[0], self.creg[0])

        self.dag = circuit_to_dagdependency(circuit)

        dir_successors_second = self.dag.direct_successors(1)
        self.assertEqual(dir_successors_second, [2, 4])

        dir_successors_fourth = self.dag.direct_successors(3)
        self.assertEqual(dir_successors_fourth, [])

        successors_second = self.dag.successors(1)
        self.assertEqual(successors_second, [2, 4, 5])

        successors_fourth = self.dag.successors(3)
        self.assertEqual(successors_fourth, [])

        dir_predecessors_sixth = self.dag.direct_predecessors(5)
        self.assertEqual(dir_predecessors_sixth, [2, 4])

        dir_predecessors_fourth = self.dag.direct_predecessors(3)
        self.assertEqual(dir_predecessors_fourth, [])

        predecessors_sixth = self.dag.predecessors(5)
        self.assertEqual(predecessors_sixth, [0, 1, 2, 4])

        predecessors_fourth = self.dag.predecessors(3)
        self.assertEqual(predecessors_fourth, [])
    def test_blocks_in_topological_order(self):
        """the pass returns blocks in correct topological order
                                                     ______
         q0:--[u1]-------.----      q0:-------------|      |--
                         |                 ______   |  U2  |
         q1:--[u2]--(+)-(+)---   =  q1:---|      |--|______|--
                     |                    |  U1  |
         q2:---------.--------      q2:---|______|------------
        """
        qr = QuantumRegister(3, "qr")
        qc = QuantumCircuit(qr)
        qc.u1(0.5, qr[0])
        qc.u2(0.2, 0.6, qr[1])
        qc.cx(qr[2], qr[1])
        qc.cx(qr[0], qr[1])
        dag = circuit_to_dag(qc)

        topo_ops = list(dag.topological_op_nodes())
        block_1 = [topo_ops[1], topo_ops[2]]
        block_2 = [topo_ops[0], topo_ops[3]]

        pass_ = Collect2qBlocks()
        pass_.run(dag)
        self.assertTrue(pass_.property_set['block_list'], [block_1, block_2])
    def _gate_rules_to_qiskit_circuit(self, node, params):
        """From a gate definition in qasm, to a QuantumCircuit format."""
        rules = []
        qreg = QuantumRegister(node['n_bits'])
        bit_args = {node['bits'][i]: q for i, q in enumerate(qreg)}
        exp_args = {node['args'][i]: Real(q) for i, q in enumerate(params)}

        for child_op in node['body'].children:
            qparams = []
            eparams = []
            for param_list in child_op.children[1:]:
                if param_list.type == 'id_list':
                    qparams = [
                        bit_args[param.name] for param in param_list.children
                    ]
                elif param_list.type == 'expression_list':
                    for param in param_list.children:
                        eparams.append(param.sym(nested_scope=[exp_args]))
            op = self._create_op(child_op.name, params=eparams)
            rules.append((op, qparams, []))
        circ = QuantumCircuit(qreg)
        for instr, qargs, cargs in rules:
            circ._append(instr, qargs, cargs)
        return circ
예제 #27
0
    def test_pauli_op_to_circuit(self):
        """Test PauliOp.to_circuit()"""
        with self.subTest("single Pauli"):
            pauli = PauliOp(Pauli("Y"))
            expected = QuantumCircuit(1)
            expected.y(0)
            self.assertEqual(pauli.to_circuit(), expected)

        with self.subTest("single Pauli with phase"):
            pauli = PauliOp(Pauli("-iX"))
            expected = QuantumCircuit(1)
            expected.x(0)
            expected.global_phase = -pi / 2
            self.assertEqual(Operator(pauli.to_circuit()), Operator(expected))

        with self.subTest("two qubit"):
            pauli = PauliOp(Pauli("IX"))
            expected = QuantumCircuit(2)
            expected.pauli("IX", range(2))
            self.assertEqual(pauli.to_circuit(), expected)
            expected = QuantumCircuit(2)
            expected.x(0)
            expected.id(1)
            self.assertEqual(pauli.to_circuit().decompose(), expected)

        with self.subTest("two qubit with phase"):
            pauli = PauliOp(Pauli("iXZ"))
            expected = QuantumCircuit(2)
            expected.pauli("XZ", range(2))
            expected.global_phase = pi / 2
            self.assertEqual(pauli.to_circuit(), expected)
            expected = QuantumCircuit(2)
            expected.z(0)
            expected.x(1)
            expected.global_phase = pi / 2
            self.assertEqual(pauli.to_circuit().decompose(), expected)
예제 #28
0
    RYYGate,
    ECRGate,
    ZGate,
    CZGate,
)


_sel = StandardEquivalenceLibrary = EquivalenceLibrary()


# Import existing gate definitions

# HGate

q = QuantumRegister(1, "q")
def_h = QuantumCircuit(q)
def_h.append(U2Gate(0, pi), [q[0]], [])
_sel.add_equivalence(HGate(), def_h)

# CHGate

q = QuantumRegister(2, "q")
def_ch = QuantumCircuit(q)
for inst, qargs, cargs in [
    (SGate(), [q[1]], []),
    (HGate(), [q[1]], []),
    (TGate(), [q[1]], []),
    (CXGate(), [q[0], q[1]], []),
    (TdgGate(), [q[1]], []),
    (HGate(), [q[1]], []),
    (SdgGate(), [q[1]], []),
예제 #29
0
    def test_asian_barrier_spread(self):
        """Test the asian barrier spread model."""
        try:
            from qiskit.aqua.circuits import WeightedSumOperator, FixedValueComparator as Comparator
            from qiskit.aqua.components.uncertainty_problems import (
                UnivariatePiecewiseLinearObjective as PwlObjective,
                MultivariateProblem)
            from qiskit.aqua.components.uncertainty_models import MultivariateLogNormalDistribution
        except ImportError:
            import warnings
            warnings.warn(
                'Qiskit Aqua is not installed, skipping the application test.')
            return

        # number of qubits per dimension to represent the uncertainty
        num_uncertainty_qubits = 2

        # parameters for considered random distribution
        spot_price = 2.0  # initial spot price
        volatility = 0.4  # volatility of 40%
        interest_rate = 0.05  # annual interest rate of 5%
        time_to_maturity = 40 / 365  # 40 days to maturity

        # resulting parameters for log-normal distribution
        # pylint: disable=invalid-name
        mu = ((interest_rate - 0.5 * volatility**2) * time_to_maturity +
              np.log(spot_price))
        sigma = volatility * np.sqrt(time_to_maturity)
        mean = np.exp(mu + sigma**2 / 2)
        variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
        stddev = np.sqrt(variance)

        # lowest and highest value considered for the spot price; in between,
        # an equidistant discretization is considered.
        low = np.maximum(0, mean - 3 * stddev)
        high = mean + 3 * stddev

        # map to higher dimensional distribution
        # for simplicity assuming dimensions are independent and identically distributed)
        dimension = 2
        num_qubits = [num_uncertainty_qubits] * dimension
        low = low * np.ones(dimension)
        high = high * np.ones(dimension)
        mu = mu * np.ones(dimension)
        cov = sigma**2 * np.eye(dimension)

        # construct circuit factory
        distribution = MultivariateLogNormalDistribution(num_qubits=num_qubits,
                                                         low=low,
                                                         high=high,
                                                         mu=mu,
                                                         cov=cov)

        # determine number of qubits required to represent total loss
        weights = []
        for n in num_qubits:
            for i in range(n):
                weights += [2**i]

        num_sum_qubits = WeightedSumOperator.get_required_sum_qubits(weights)

        # create circuit factoy
        agg = WeightedSumOperator(sum(num_qubits), weights)

        # set the strike price (should be within the low and the high value of the uncertainty)
        strike_price_1 = 3
        strike_price_2 = 4

        # set the barrier threshold
        barrier = 2.5

        # map strike prices and barrier threshold from [low, high] to {0, ..., 2^n-1}
        max_value = 2**num_sum_qubits - 1
        low_ = low[0]
        high_ = high[0]

        mapped_strike_price_1 = (strike_price_1 - dimension*low_) / \
            (high_ - low_) * (2**num_uncertainty_qubits - 1)
        mapped_strike_price_2 = (strike_price_2 - dimension*low_) / \
            (high_ - low_) * (2**num_uncertainty_qubits - 1)
        mapped_barrier = (barrier -
                          low) / (high - low) * (2**num_uncertainty_qubits - 1)

        conditions = []
        for i in range(dimension):
            # target dimension of random distribution and corresponding condition
            conditions += [(i,
                            Comparator(num_qubits[i],
                                       mapped_barrier[i] + 1,
                                       geq=False))]

        # set the approximation scaling for the payoff function
        c_approx = 0.25

        # setup piecewise linear objective fcuntion
        breakpoints = [0, mapped_strike_price_1, mapped_strike_price_2]
        slopes = [0, 1, 0]
        offsets = [0, 0, mapped_strike_price_2 - mapped_strike_price_1]
        f_min = 0
        f_max = mapped_strike_price_2 - mapped_strike_price_1
        bull_spread_objective = PwlObjective(num_sum_qubits, 0, max_value,
                                             breakpoints, slopes, offsets,
                                             f_min, f_max, c_approx)

        # define overall multivariate problem
        asian_barrier_spread = MultivariateProblem(distribution,
                                                   agg,
                                                   bull_spread_objective,
                                                   conditions=conditions)

        num_req_qubits = asian_barrier_spread.num_target_qubits
        num_req_ancillas = asian_barrier_spread.required_ancillas()

        qr = QuantumRegister(num_req_qubits, name='q')
        qr_ancilla = QuantumRegister(num_req_ancillas, name='q_a')
        qc = QuantumCircuit(qr, qr_ancilla)

        asian_barrier_spread.build(qc, qr, qr_ancilla)
        job = execute(qc,
                      backend=BasicAer.get_backend('statevector_simulator'))

        # evaluate resulting statevector
        value = 0
        for i, amplitude in enumerate(job.result().get_statevector()):
            b = ('{0:0%sb}' % asian_barrier_spread.num_target_qubits
                 ).format(i)[-asian_barrier_spread.num_target_qubits:]
            prob = np.abs(amplitude)**2
            if prob > 1e-4 and b[0] == '1':
                value += prob
                # all other states should have zero probability due to ancilla qubits
                if i > 2**num_req_qubits:
                    break

        # map value to original range
        mapped_value = asian_barrier_spread.value_to_estimation(value) / (
            2**num_uncertainty_qubits - 1) * (high_ - low_)
        expected = 0.83188
        self.assertAlmostEqual(mapped_value, expected, places=5)
예제 #30
0
    def test_compose_classical(self):
        """Composing on classical bits.

                       ┌───┐                       ┌─────┐┌─┐
        lqr_1_0: |0>───┤ H ├───     rqr_0: |0>──■──┤ Tdg ├┤M├
                       ├───┤                  ┌─┴─┐└─┬─┬─┘└╥┘
        lqr_1_1: |0>───┤ X ├───     rqr_1: |0>┤ X ├──┤M├───╫─
                    ┌──┴───┴──┐               └───┘  └╥┘   ║
        lqr_1_2: |0>┤ U1(0.1) ├  +   rcr_0: 0 ════════╬════╩═  =
                    └─────────┘                       ║
        lqr_2_0: |0>─────■─────      rcr_1: 0 ════════╩══════
                       ┌─┴─┐
        lqr_2_1: |0>───┤ X ├───
                       └───┘
        lcr_0: 0 ══════════════

        lcr_1: 0 ══════════════

                       ┌───┐
        lqr_1_0: |0>───┤ H ├──────────────────
                       ├───┤        ┌─────┐┌─┐
        lqr_1_1: |0>───┤ X ├─────■──┤ Tdg ├┤M├
                    ┌──┴───┴──┐  │  └─────┘└╥┘
        lqr_1_2: |0>┤ U1(0.1) ├──┼──────────╫─
                    └─────────┘  │          ║
        lqr_2_0: |0>─────■───────┼──────────╫─
                       ┌─┴─┐   ┌─┴─┐  ┌─┐   ║
        lqr_2_1: |0>───┤ X ├───┤ X ├──┤M├───╫─
                       └───┘   └───┘  └╥┘   ║
           lcr_0: 0 ═══════════════════╩════╬═
                                            ║
           lcr_1: 0 ════════════════════════╩═
        """
        qreg = QuantumRegister(2, 'rqr')
        creg = ClassicalRegister(2, 'rcr')
        right_qubit0 = qreg[0]
        right_qubit1 = qreg[1]
        right_clbit0 = creg[0]
        right_clbit1 = creg[1]

        circuit_right = QuantumCircuit(qreg, creg)
        circuit_right.cx(qreg[0], qreg[1])
        circuit_right.tdg(qreg[0])
        circuit_right.measure(qreg, creg)

        dag_left = circuit_to_dag(self.circuit_left)
        dag_right = circuit_to_dag(circuit_right)

        # permuted subset of qubits and clbits
        dag_left.compose(dag_right, edge_map={right_qubit0: self.left_qubit1,
                                              right_qubit1: self.left_qubit4,
                                              right_clbit0: self.left_clbit1,
                                              right_clbit1: self.left_clbit0})
        circuit_composed = dag_to_circuit(dag_left)

        circuit_expected = self.circuit_left.copy()
        circuit_expected.cx(self.left_qubit1, self.left_qubit4)
        circuit_expected.tdg(self.left_qubit1)
        circuit_expected.measure(self.left_qubit4, self.left_clbit0)
        circuit_expected.measure(self.left_qubit1, self.left_clbit1)

        self.assertEqual(circuit_composed, circuit_expected)