Example #1
0
def test_scheduling_pulse(instructions, method, expected_length,
                          random_shuffle, gates_schedule):
    circuit = QubitCircuit(4)
    for instruction in instructions:
        circuit.add_gate(
            Gate(instruction.name, instruction.targets, instruction.controls))

    if random_shuffle:
        repeat_num = 5
    else:
        repeat_num = 0
    result0 = gate_sequence_product(circuit.propagators())

    # run the scheduler
    scheduler = Scheduler(method)
    gate_cycle_indices = scheduler.schedule(instructions,
                                            gates_schedule=gates_schedule,
                                            repeat_num=repeat_num)

    # check if the scheduled length is expected
    assert (max(gate_cycle_indices) == expected_length)
    scheduled_gate = [[] for i in range(max(gate_cycle_indices) + 1)]

    # check if the scheduled circuit is correct
    for i, cycles in enumerate(gate_cycle_indices):
        scheduled_gate[cycles].append(circuit.gates[i])
    circuit.gates = sum(scheduled_gate, [])
    result1 = gate_sequence_product(circuit.propagators())
    assert (tracedist(result0 * result1.dag(), qeye(result0.dims[0])) < 1.0e-7)
Example #2
0
 def testresolve(self, gate_from, gate_to, targets, controls):
     qc1 = QubitCircuit(2)
     qc1.add_gate(gate_from, targets=targets, controls=controls)
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates(basis=gate_to)
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Example #3
0
    def test_gate_product(self):

        filename = "qft.qasm"
        filepath = Path(__file__).parent / 'qasm_files' / filename
        qc = read_qasm(filepath)

        U_list_expanded = qc.propagators()
        U_list = qc.propagators(expand=False)

        inds_list = []

        for gate in qc.gates:
            if isinstance(gate, Measurement):
                continue
            else:
                inds_list.append(gate.get_inds(qc.N))

        U_1, _ = gate_sequence_product(U_list,
                                       inds_list=inds_list,
                                       expand=True)
        U_2 = gate_sequence_product(U_list_expanded,
                                    left_to_right=True,
                                    expand=False)

        np.testing.assert_allclose(U_1, U_2)
Example #4
0
def test_device_against_gate_sequence(num_qubits, gates, device_class, kwargs):
    circuit = QubitCircuit(num_qubits)
    for gate in gates:
        circuit.add_gate(gate)
    U_ideal = gate_sequence_product(circuit.propagators())

    device = device_class(num_qubits)
    U_physical = gate_sequence_product(device.run(circuit))
    assert (U_ideal - U_physical).norm() < _tol
Example #5
0
def test_analytical_evolution(num_qubits, gates, device_class, kwargs):
    circuit = QubitCircuit(num_qubits)
    for gate in gates:
        circuit.add_gate(gate)
    state = qutip.rand_ket(2**num_qubits)
    state.dims = [[2] * num_qubits, [1] * num_qubits]
    ideal = gate_sequence_product([state] + circuit.propagators())
    device = device_class(num_qubits)
    operators = device.run_state(init_state=state, qc=circuit, analytical=True)
    result = gate_sequence_product(operators)
    assert abs(qutip.metrics.fidelity(result, ideal) - 1) < _tol
Example #6
0
 def testFREDKINdecompose(self):
     """
     FREDKIN to rotation and CNOT: compare unitary matrix for FREDKIN and product of
     resolved matrices in terms of rotation gates and CNOT.
     """
     qc1 = QubitCircuit(3)
     qc1.add_gate("FREDKIN", targets=[0, 1], controls=[2])
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates()
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Example #7
0
 def testSNOTdecompose(self):
     """
     SNOT to rotation: compare unitary matrix for SNOT and product of
     resolved matrices in terms of rotation gates.
     """
     qc1 = QubitCircuit(1)
     qc1.add_gate("SNOT", targets=0)
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc2 = qc1.resolve_gates()
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Example #8
0
 def testadjacentgates(self):
     """
     Adjacent Gates: compare unitary matrix for ISWAP and product of
     resolved matrices in terms of adjacent gates interaction.
     """
     qc1 = QubitCircuit(3)
     qc1.add_gate("ISWAP", targets=[0, 2])
     U1 = gates.gate_sequence_product(qc1.propagators())
     qc0 = qc1.adjacent_gates()
     qc2 = qc0.resolve_gates(basis="ISWAP")
     U2 = gates.gate_sequence_product(qc2.propagators())
     assert _op_dist(U1, U2) < 1e-12
Example #9
0
def test_numerical_circuit(circuit, device_class, kwargs, schedule_mode):
    num_qubits = circuit.N
    with warnings.catch_warnings(record=True):
        device = device_class(circuit.N, **kwargs)
    device.load_circuit(circuit, schedule_mode=schedule_mode)

    state = qutip.rand_ket(2**num_qubits)
    state.dims = [[2] * num_qubits, [1] * num_qubits]
    target = gate_sequence_product([state] + circuit.propagators())
    if isinstance(device, DispersiveCavityQED):
        num_ancilla = len(device.dims) - num_qubits
        ancilla_indices = slice(0, num_ancilla)
        extra = qutip.basis(device.dims[ancilla_indices], [0] * num_ancilla)
        init_state = qutip.tensor(extra, state)
    elif isinstance(device, SCQubits):
        # expand to 3-level represetnation
        init_state = _ket_expaned_dims(state, device.dims)
    else:
        init_state = state
    options = qutip.Options(store_final_state=True, nsteps=50_000)
    result = device.run_state(init_state=init_state,
                              analytical=False,
                              options=options)
    if isinstance(device, DispersiveCavityQED):
        target = qutip.tensor(extra, target)
    elif isinstance(device, SCQubits):
        target = _ket_expaned_dims(target, device.dims)
    assert _tol > abs(1 - qutip.metrics.fidelity(result.final_state, target))
Example #10
0
def test_numerical_evolution(num_qubits, gates, device_class, kwargs):
    num_qubits = 2
    circuit = QubitCircuit(num_qubits)
    for gate in gates:
        circuit.add_gate(gate)
    device = device_class(num_qubits, **kwargs)
    device.load_circuit(circuit)

    state = qutip.rand_ket(2**num_qubits)
    state.dims = [[2] * num_qubits, [1] * num_qubits]
    target = gate_sequence_product([state] + circuit.propagators())
    if isinstance(device, DispersiveCavityQED):
        num_ancilla = len(device.dims) - num_qubits
        ancilla_indices = slice(0, num_ancilla)
        extra = qutip.basis(device.dims[ancilla_indices], [0] * num_ancilla)
        init_state = qutip.tensor(extra, state)
    elif isinstance(device, SCQubits):
        # expand to 3-level represetnation
        init_state = _ket_expaned_dims(state, device.dims)
    else:
        init_state = state
    options = qutip.Options(store_final_state=True, nsteps=50_000)
    result = device.run_state(init_state=init_state,
                              analytical=False,
                              options=options)
    numerical_result = result.final_state
    if isinstance(device, DispersiveCavityQED):
        target = qutip.tensor(extra, target)
    elif isinstance(device, SCQubits):
        target = _ket_expaned_dims(target, device.dims)
    assert _tol > abs(1 - qutip.metrics.fidelity(numerical_result, target))
Example #11
0
def test_numerical_evolution(num_qubits, gates, device_class, kwargs):
    num_qubits = 3
    circuit = QubitCircuit(num_qubits)
    for gate in gates:
        circuit.add_gate(gate)
    device = device_class(num_qubits, **kwargs)
    device.load_circuit(circuit)

    state = qutip.rand_ket(2**num_qubits)
    state.dims = [[2] * num_qubits, [1] * num_qubits]
    target = gate_sequence_product([state] + circuit.propagators())
    if len(device.dims) > num_qubits:
        num_ancilla = len(device.dims) - num_qubits
        ancilla_indices = slice(0, num_ancilla)
        extra = qutip.basis(device.dims[ancilla_indices], [0] * num_ancilla)
        init_state = qutip.tensor(extra, state)
    else:
        init_state = state
    options = qutip.Options(store_final_state=True, nsteps=50_000)
    result = device.run_state(init_state=init_state,
                              analytical=False,
                              options=options)
    if len(device.dims) > num_qubits:
        target = qutip.tensor(extra, target)
    assert _tol > abs(1 - qutip.metrics.fidelity(result.final_state, target))
Example #12
0
 def testQFTComparison(self):
     """
     qft: compare qft and product of qft steps
     """
     for N in range(1, 5):
         U1 = qft(N)
         U2 = gate_sequence_product(qft_steps(N))
         assert_((U1 - U2).norm() < 1e-12)
Example #13
0
    def compute_jac(self, angles, indices_to_compute=None):
        """
        Compute the jacobian for the circuit's cost function,
        assuming the cost function is in observable mode.

        Parameters
        ----------
        angles: list of float
            Circuit free parameters
        indicies_to_compute: list of int, optional
            Block indices for which to use in computing the jacobian.
            By default, this is every index (every block).

        Returns
        -------
        jac: (n,) numpy array of floats
        """
        if indices_to_compute is None:
            indices_to_compute = list(range(len(angles)))

        circ = self.construct_circuit(angles)
        propagators = circ.propagators()
        U = gate_sequence_product(propagators)
        U_prods, U_prods_back = self.get_unitary_products(propagators)
        # subtract one for the identity matrix
        n = len(U_prods) - 1

        def modify_unitary(k, U):
            return U_prods_back[n - 1 - k] * U * U_prods[k]

        jacobian = []
        i = 0
        for k, block in enumerate(self.get_block_series()):
            n_params = block.get_free_parameters_num()
            if n_params > 0:
                if i in indices_to_compute:
                    dBlock = block.get_unitary_derivative(angles[i:i +
                                                                 n_params])
                    dU = modify_unitary(k, dBlock)
                    jacobian.append(self.cost_derivative(U, dU))
                i += n_params
        return np.array(jacobian)
Example #14
0
    def test_multi_gates(self):
        N = 2
        H_d = tensor([sigmaz()] * 2)
        H_c = []

        test = OptPulseProcessor(N)
        test.add_drift(H_d, [0, 1])
        test.add_control(sigmax(), cyclic_permutation=True)
        test.add_control(sigmay(), cyclic_permutation=True)
        test.add_control(tensor([sigmay(), sigmay()]))

        # qubits circuit with 3 gates
        setting_args = {
            "SNOT": {
                "num_tslots": 10,
                "evo_time": 1
            },
            "SWAP": {
                "num_tslots": 30,
                "evo_time": 3
            },
            "CNOT": {
                "num_tslots": 30,
                "evo_time": 3
            }
        }
        qc = QubitCircuit(N)
        qc.add_gate("SNOT", 0)
        qc.add_gate("SWAP", targets=[0, 1])
        qc.add_gate('CNOT', controls=1, targets=[0])
        test.load_circuit(qc, setting_args=setting_args, merge_gates=False)

        rho0 = rand_ket(4)  # use random generated ket state
        rho0.dims = [[2, 2], [1, 1]]
        U = gate_sequence_product(qc.propagators())
        rho1 = U * rho0
        result = test.run_state(rho0)
        assert_(fidelity(result.states[-1], rho1) > 1 - 1.0e-6)