def test_invariant_under_unitary_transformation(self, dimension): rho1 = rand_dm(dimension, 0.25) rho2 = rand_dm(dimension, 0.25) U = rand_unitary(dimension, 0.25) D = tracedist(rho1, rho2) DU = tracedist(U * rho1 * U.dag(), U * rho2 * U.dag()) assert D == pytest.approx(DU, rel=1e-5)
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)
def verify_CPTP(U): # args: U(Qobj): superoperator or unitary # returns: trace dist of the partial trace that should be the identity, i.e. trace dist should be zero for TP maps choi = qtp.to_choi(U) candidate_identity = choi.ptrace([0, 1]) # 3 since we have a qutrit ptrace = qtp.tracedist(candidate_identity, qtp.tensor(qtp.qeye(3), qtp.qeye(3))) return ptrace
def test_orthogonal(self, left_dm, right_dm, dimension): left = basis(dimension, 0) right = basis(dimension, dimension // 2) if left_dm: left = left.proj() if right_dm: right = right.proj() assert tracedist(left, right) == pytest.approx(1, abs=1e-6)
def _verify_scheduled_circuit(circuit, gate_cycle_indices): """ Compare results between the original and the scheduled circuit. The input gate_cycle_indices is the scheduling result, i.e., a list of integers denoting the execution cycle of each gate in the circuit. """ result0 = gate_sequence_product(circuit.propagators()) scheduled_gate = [[] for i in range(max(gate_cycle_indices) + 1)] 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()) return tracedist(result0 * result1.dag(), qeye(result0.dims[0])) < 1.0e-7
def tracedist(self, target_state=None, sparse=False, tol=0): """Returns the trace distance from the state resulting from the sequence to the target state. Args: target_state (optional, qutip.Qobj): State to which to compare the final state. Defaults to``target_unitary * init_state``. sparse, tol: See ``qutip.tracedist``. Returns: float or None """ if self.mesolve_state is None: return target_state = target_state or self.target_state state = self.mesolve_state return qutip.tracedist(state, target_state, sparse=sparse, tol=tol)
def trace_norm(self): """ Calculates trace norms of density state of matrix - to use this as a metric, take the difference (p_0 - p_1) and return the value of the trace distance Return: dist (float): trace distance of difference between density matrices """ current = Qobj(self.current_state) goal = Qobj(self.goal_state) density_1 = current * current.dag() density_2 = goal * goal.dag() dist = tracedist(density_1, density_2) return dist
def metastable_calc_optimization_duffing(rho_ss, rho_adr, mode_idx=0, min_dist=10, ranges=None): kwargs = {'min_dist': min_dist, 'ranges': ranges} rho_ss /= rho_ss.tr() rho_adr /= (rho_adr.dag() * rho_adr).tr() rho_c_ss = rho_ss.ptrace(mode_idx) rho_c_adr = rho_adr.ptrace(mode_idx) res = scipy.optimize.minimize(objective_calc, 0.0, method='Nelder-Mead', args=(rho_c_adr, rho_c_ss, kwargs)) rho_d = rho_adr + res.x[0] * rho_ss rho_d /= rho_d.tr() rho_2 = rho_d rho_c_2 = rho_2.ptrace(mode_idx) rho_1 = rho_adr rho_1 -= rho_2 * (rho_1 * rho_2).tr() / (rho_2 * rho_2).tr() rho_c_1 = rho_1.ptrace(mode_idx) res = scipy.optimize.minimize(objective_calc, 0.0, method='Nelder-Mead', args=(rho_c_1, rho_c_2, kwargs)) rho_b_adr = rho_1 + res.x[0] * rho_2 rho_b_adr /= rho_b_adr.tr() rho_1 = rho_ss rho_1 -= rho_2 * (rho_1 * rho_2).tr() / (rho_2 * rho_2).tr() rho_c_1 = rho_1.ptrace(mode_idx) res = scipy.optimize.minimize(objective_calc, 0.0, method='Nelder-Mead', args=(rho_c_1, rho_c_2, kwargs)) rho_b_ss = rho_1 + res.x[0] * rho_2 rho_b_ss /= rho_b_ss.tr() states_b = [rho_b_ss, rho_b_adr] distances = [tracedist(rho_b, rho_d) for rho_b in states_b] rho_b = states_b[np.argmax(distances)] dims = rho_b.dims components = [qeye(levels) for levels in dims[0][:mode_idx]] + [destroy(dims[0][mode_idx])] + [qeye(levels) for levels in dims[0][ mode_idx + 1:]] a_op = tensor(components) a_exp = [np.abs(expect(a_op, rho_d)), np.abs(expect(a_op, rho_b))] states = np.array([rho_d, rho_b], dtype=object) states = states[np.argsort(a_exp)] return states[0], states[1]
import qutip as qt import gates as gate import numpy as np from solovay_kitaev import solovay_kitaev from utils import load_tree U = gate.R([0.21, 0.14, 0.7], 7 * np.pi / 6) tree = load_tree('trees/HT_15.pkl') U_approx = solovay_kitaev(U, tree, 2) print(U.full()) print(U_approx.full()) print(qt.tracedist(U, U_approx))
def tpcheck(self): tmp = self._choi.ptrace([0]) ide = qt.identity(tmp.shape[0]) print(qt.tracedist(tmp, ide)) return tmp
def test_inequality_tracedist_to_fidelity(self, left, right): tol = 1e-7 assert 1 - fidelity(left, right) <= tracedist(left, right) + tol
def test_state_with_itself(self, state): assert tracedist(state, state) == pytest.approx(0, abs=1e-6)
def overlap_objective(p_b, rho_ss, rho_b, rho_d): rho = p_b*rho_b + (1-p_b)*rho_d objective = tracedist(rho_ss, rho) return objective
inputfilenameA = str(sys.argv[1]) indexA = int(sys.argv[2]) inputfilenameB = str(sys.argv[3]) indexB = int(sys.argv[4]) if inputfilenameA[-3:]==".qu": inputfilenameA = inputfilenameA[:-3] if inputfilenameB[-3:]==".qu": inputfilenameB = inputfilenameB[:-3] listA=qutip.qload(inputfilenameA) A=listA[indexA] listB=qutip.qload(inputfilenameB) B=listB[indexB] elif len(sys.argv) ==4: inputfilename = str(sys.argv[1]) indexA = int(sys.argv[2]) indexB = int(sys.argv[3]) if inputfilename[-3:]==".qu": inputfilename = inputfilename[:-3] mylist=qutip.qload(inputfilename) A=mylist[indexA] B=mylist[indexB] print("Loaded two objects") print(A) print(B) result = qutip.tracedist(A, B) print("The trace distance between them is") print(result)