Пример #1
0
    def test_N_level_system(self):
        """
        Test for circuit with N-level system.
        """
        mat3 = qp.rand_unitary_haar(3)

        def controlled_mat3(arg_value):
            """
            A qubit control an operator acting on a 3 level system
            """
            control_value = arg_value
            dim = mat3.dims[0][0]
            return (tensor(fock_dm(2, control_value), mat3) +
                    tensor(fock_dm(2, 1 - control_value), identity(dim)))

        qc = QubitCircuit(2, dims=[3, 2])
        qc.user_gates = {"CTRLMAT3": controlled_mat3}
        qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1)
        props = qc.propagators()
        final_fid = qp.average_gate_fidelity(mat3, ptrace(props[0], 0) - 1)
        assert pytest.approx(final_fid, 1.0e-6) == 1

        init_state = basis([3, 2], [0, 1])
        result = qc.run(init_state)
        final_fid = qp.fidelity(result, props[0] * init_state)
        assert pytest.approx(final_fid, 1.0e-6) == 1.
def pro_avfid_superoperator_phasecorrected(U,phases):
    """
    Average process (gate) fidelity in the whole space for a qubit and qutrit
    Qubit Z rotation and qutrit "Z" rotations are applied, taking into account the anharmonicity as well
    """
    Ucorrection = qtp.Qobj([[np.exp(-1j*np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
                     [0, np.exp(-1j*np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
                     [0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1])), 0, 0, 0, 0, 0, 0],
                     [0, 0, 0, np.exp(-1j*np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
                     [0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[3]-phases[-1])), 0, 0, 0, 0],
                     [0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1]+phases[2]-phases[0])), 0, 0, 0],
                     [0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[5])), 0, 0],
                     [0, 0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[5]+phases[1]-phases[0])), 0],
                     [0, 0, 0, 0, 0, 0, 0, 0, np.exp(-1j*np.deg2rad(phases[4]-phases[-1]+phases[5]-phases[0]))]],
                    type='oper',
                    dims=[[3, 3], [3, 3]])

    if U.type=='oper':
        U=Ucorrection*U
        ptrace = np.abs((U.dag()*U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace+dim)/(dim*(dim+1)))

    elif U.type=='super':
        U=qtp.to_super(Ucorrection)*U
        return np.real(qtp.average_gate_fidelity(U,target=U_target_diffdims))
Пример #3
0
 def test_all_elements_different(self):
     clifford = [gate for gate in self.clifford]
     for i, gate in enumerate(clifford):
         for other in clifford[i + 1:]:
             # Big tolerance because we actually want to test the inverse.
             fid = qutip.average_gate_fidelity(gate, other)
             assert not np.allclose(fid, 1., atol=1e-3)
Пример #4
0
	def get_fidelity(self, target, U = None):
		if U is None:
			U = self.get_unitary()
		U = qt.Qobj(list(U))

		target = qt.Qobj(list(target))

		return (qt.average_gate_fidelity(U,target=target))
def unitary_channel(dimension,desired_fidelity,error):
    noise_operator = qt.to_super(qt.rand_unitary(dimension))
    count=0
    while np.abs(qt.average_gate_fidelity(noise_operator)-desired_fidelity)>error and count<400:
        noise_operator = qt.to_super(qt.rand_unitary(dimension))
        count=count+1
    if count>=400: 
        print("Could not achieve desired fidelity within margin of error")
    return noise_operator 
Пример #6
0
def test_scqubits_single_qubit_gate():
    # Check the accuracy of the single-qubit gate for SCQubits.
    circuit = QubitCircuit(1)
    circuit.add_gate("X", targets=[0])
    processor = SCQubits(1, omega_single=0.04)
    processor.load_circuit(circuit)
    U = _compute_propagator(processor, circuit)
    fid = qutip.average_gate_fidelity(qutip.Qobj(U.full()[:2, :2]),
                                      qutip.sigmax())
    assert pytest.approx(fid, rel=1.0e-6) == 1
Пример #7
0
def test_check_single_qubit_to_decompose_to_rotations(gate, method):
    """Initial matrix and product of final decompositions are same within some
    phase."""
    gate_list = decompose_one_qubit_gate(gate, method)
    circuit = QubitCircuit(num_qubits)
    circuit.add_gates(gate_list)
    decomposed_gates_final_matrix = circuit.compute_unitary()
    fidelity_of_input_output = average_gate_fidelity(
        gate, decomposed_gates_final_matrix)
    assert np.isclose(fidelity_of_input_output, 1.0)
Пример #8
0
def pro_avfid_superoperator(U):
    """
    Average process (gate) fidelity in the whole space for two qutrits
    """
    if U.type == 'oper':
        ptrace = np.abs((U.dag() * U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace + dim) / (dim * (dim + 1)))

    elif U.type == 'super':
        return np.real(qtp.average_gate_fidelity(U, target=U_target_diffdims))
Пример #9
0
    def get_fidelity(self, target, U=None):
        if U is None:
            U = self.get_unitary()
        U = qt.Qobj(list(U))

        # Correct for phase of singlet. We do not give a damn about it.
        # target[4,4] = cmath.rect(1, cmath.phase(U[4,4]))
        # target[5,5] = cmath.rect(1, cmath.phase(U[5,5]))
        target = qt.Qobj(list(target))

        return (qt.average_gate_fidelity(U, target=target))
def pro_avfid_superoperator(U):
    """
    Average process (gate) fidelity in the whole space for two qutrits
    The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
    """
    if U.type == 'oper':
        ptrace = np.abs((U.dag() * U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace + dim) / (dim * (dim + 1)))

    elif U.type == 'super':
        return np.real(qtp.average_gate_fidelity(U, target=U_target_diffdims))
def pro_avfid_superoperator_phasecorrected(U, phases):
    """
    Average process (gate) fidelity in the whole space for two qutrits
    Qubit Z rotation and qutrit "Z" rotations are applied, taking into account the anharmonicity as well.
    The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
    This function is quite useless because we are always interested in the computational subspace only.
    """
    Ucorrection = qtp.Qobj(
        [[np.exp(-1j * np.deg2rad(phases[0])), 0, 0, 0, 0, 0, 0, 0, 0],
         [0, np.exp(-1j * np.deg2rad(phases[1])), 0, 0, 0, 0, 0, 0, 0],
         [
             0, 0,
             np.exp(-1j * np.deg2rad(phases[4] - phases[-1])), 0, 0, 0, 0, 0, 0
         ], [0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[2])), 0, 0, 0, 0, 0],
         [
             0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[3] - phases[-1])), 0, 0, 0, 0
         ],
         [
             0, 0, 0, 0, 0,
             np.exp(
                 -1j *
                 np.deg2rad(phases[4] - phases[-1] + phases[2] - phases[0])),
             0, 0, 0
         ], [0, 0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[5])), 0, 0],
         [
             0, 0, 0, 0, 0, 0, 0,
             np.exp(-1j * np.deg2rad(phases[5] + phases[1] - phases[0])), 0
         ],
         [
             0, 0, 0, 0, 0, 0, 0, 0,
             np.exp(-1j *
                    np.deg2rad(phases[4] - phases[-1] + phases[5] - phases[0]))
         ]],
        type='oper',
        dims=[[3, 3], [3, 3]])

    if U.type == 'oper':
        U = Ucorrection * U
        ptrace = np.abs((U.dag() * U_target).tr())**2
        dim = 9  # dimension of the whole space
        return np.real((ptrace + dim) / (dim * (dim + 1)))

    elif U.type == 'super':
        U = qtp.to_super(Ucorrection) * U
        return np.real(qtp.average_gate_fidelity(U, target=U_target_diffdims))
Пример #12
0
def test_idling_accuracy():
    """
    Check if the switch-on and off of the pulse is implemented correctly.
    More sampling points may be needed to suppress the interpolated pulse
    during the idling period.
    """
    processor = SCQubits(2, omega_single=0.04)
    circuit = QubitCircuit(1)
    circuit.add_gate("X", targets=[0])
    processor.load_circuit(circuit)
    U = _compute_propagator(processor, circuit)
    error_1_gate = 1 - qutip.average_gate_fidelity(
        qutip.Qobj(U.full()[:2, :2]), qutip.sigmax())

    circuit = QubitCircuit(2)
    circuit.add_gate("X", targets=[0])
    circuit.add_gate("X", targets=[1])
    # Turning off scheduling to keep the idling.
    processor.load_circuit(circuit, schedule_mode=False)
    U = _compute_propagator(processor, circuit)
    error_2_gate = 1 - qutip.average_gate_fidelity(
        qutip.Qobj(U.full()[:2, :2]), qutip.sigmax())

    assert error_2_gate < 2 * error_1_gate
Пример #13
0
 def test_gate_normalises_pauli_group(self, gate):
     """
     Test the fundamental definition of the Clifford group, i.e. that it
     normalises the Pauli group.
     """
     # Assert that each Clifford gate maps the set of Pauli gates back onto
     # itself (though not necessarily in order).  This condition is no
     # stronger than simply considering each (gate, Pauli) pair separately.
     pauli_gates = deepcopy(self.pauli)
     normalised = [gate * pauli * gate.dag() for pauli in self.pauli]
     for gate in normalised:
         for i, pauli in enumerate(pauli_gates):
             # if np.allclose(gate.full(), pauli.full(), atol=1e-10):
             if np.allclose(qutip.average_gate_fidelity(gate, pauli), 1):
                 del pauli_gates[i]
                 break
     assert len(pauli_gates) == 0
Пример #14
0
        def get_unitary_gate_fidelity(self, U=None):
            """
            returns unitary gate fidelity
            Args
                runs (str/tuple) : number of runs to compute the average gate fidelity
            """
            self.solver_obj.calculate_evolution(self.init, self.total_time,
                                                50000, 1)
            U = qt.Qobj(self.solver_obj.get_unitary()[0])

            target = qt.Qobj(
                sp.linalg.expm(-np.pi / 4. * 1j *
                               sp.sparse.diags([0., -1., -1., 0.]).todense()))
            temp_phase = self.delta_z * (self.total_time * 1e-9)
            SQphase = qt.Qobj(
                sp.linalg.expm(-2 * np.pi * 1j * temp_phase * self.H_zeeman))
            fidelity = qt.average_gate_fidelity(U, target * SQphase)

            return fidelity
Пример #15
0
        def get_average_gate_fidelity(self, runs=500, target=None):
            """
            returns average gate fidelity
            Args
                runs (int) : number of runs to compute the average gate fidelity
                target (4x4 numpy array) : target unitary to compute fidelity
            """

            self.solver_obj.calculate_evolution(self.init, self.total_time,
                                                10000, 1)
            U_ideal = self.solver_obj.get_unitary()[0]
            self.solver_obj.add_noise_static(2 * np.pi * self.H_zeeman,
                                             18 * 1e-6)
            self.solver_obj.add_noise_generic(2 * np.pi * self.H_heisenberg,
                                              oneoverfnoise,
                                              self.exchange_dc / 100)
            self.solver_obj.calculate_evolution(self.init, self.total_time,
                                                10000, int(runs))

            U_list = self.solver_obj.get_unitary()

            # Calculate the averaged super operator in the Lioville superoperator form using column convention
            basis = [qt.basis(4, it) for it in range(4)]
            superoperator_basis = [
                basis_it1 * basis_it2.dag() for basis_it2 in basis
                for basis_it1 in basis
            ]
            averaged_map = np.zeros([16, 16], dtype=np.complex)
            for u in U_list:
                temp_U = qt.Qobj(u)
                output_density = list()
                for it in range(len(superoperator_basis)):
                    temp_vec = np.array(
                        qt.operator_to_vector(
                            temp_U * superoperator_basis[it] * temp_U.dag() /
                            float(runs)).full()).flatten()
                    output_density.append(np.array(temp_vec))
                averaged_map = np.add(averaged_map, np.array(output_density))

            # Define the target unitary operation
            if target is None:
                target = sp.linalg.expm(
                    -np.pi / 2. * 1j *
                    sp.sparse.diags([0., -1., -1., 0.]).todense())

            # get phase from optimizing noiseless unitary evolution
            def to_minimize_fidelity(theta):
                temp_z_gate = np.matmul(
                    sp.linalg.expm(-2 * np.pi * 1j * theta * self.H_zeeman),
                    U_ideal)
                temp_m = np.matmul(sp.conjugate(sp.transpose(target)),
                                   temp_z_gate)
                return np.real(1. - (sp.trace(
                    np.matmul(temp_m, sp.conjugate(sp.transpose(temp_m)))) +
                                     np.abs(sp.trace(temp_m))**2.) / 20.)

            ideal_phase = sp.optimize.minimize(
                to_minimize_fidelity,
                [self.delta_z * (self.total_time * 1e-9)],
                method='Nelder-Mead',
                tol=1e-6).x[0]

            target = np.matmul(
                sp.linalg.expm(2 * np.pi * 1j * ideal_phase * self.H_zeeman),
                target)

            # Change the shape of the averaged super operator to match the definitions used in QuTip (row convention)
            target = qt.Qobj(target)
            averaged_map = qt.Qobj(averaged_map).trans()
            averaged_map._type = 'super'
            averaged_map.dims = [[[4], [4]], [[4], [4]]]
            averaged_map.superrep = qt.to_super(target).superrep

            # Calculate the average gate fidelity of the superoperator with the target unitary gate

            fidelity = qt.average_gate_fidelity(averaged_map, target)
            return fidelity
Пример #16
0
 def test_unitaries_equal_1(self, dimension):
     """Tests that for random unitaries U, AGF(U, U) = 1."""
     tol = 1e-7
     U = rand_unitary_haar(dimension)
     SU = to_super(U)
     assert average_gate_fidelity(SU, target=U) == pytest.approx(1, abs=tol)
Пример #17
0
 def test_bounded(self, dimension):
     tol = 1e-7
     channel = rand_super_bcsz(dimension)
     assert -tol <= average_gate_fidelity(channel) <= 1 + tol
Пример #18
0
 def test_identity(self, dimension):
     id = qeye(dimension)
     assert average_gate_fidelity(id) == pytest.approx(1, abs=1e-12)