def set_up_ops(self, N): """ Generate the Hamiltonians for the spinchain model and save them in the attribute `ctrls`. Parameters ---------- N: int The number of qubits in the system. """ self.pulse_dict = {} index = 0 # sx_ops for m in range(N): self.pulses.append( Pulse(sigmax(), m, spline_kind=self.spline_kind)) self.pulse_dict["sx" + str(m)] = index index += 1 # sz_ops for m in range(N): self.pulses.append( Pulse(sigmaz(), m, spline_kind=self.spline_kind)) self.pulse_dict["sz" + str(m)] = index index += 1 # sxsy_ops operator = tensor([sigmax(), sigmax()]) + tensor([sigmay(), sigmay()]) for n in range(N - 1): self.pulses.append( Pulse(operator, [n, n+1], spline_kind=self.spline_kind)) self.pulse_dict["g" + str(n)] = index index += 1
def add_states(self, state, kind='vector'): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : qobj Input state vector. kind : str {'vector','point'} Type of object to plot. """ if isinstance(state, Qobj): state = [state] for st in state: if kind == 'vector': vec = [ expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st) ] self.add_vectors(vec) elif kind == 'point': pnt = [ expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st) ] self.add_points(pnt)
def TestBasicPulse(): """ Test for basic pulse generation and attributes. """ coeff = np.array([0.1, 0.2, 0.3, 0.4]) tlist = np.array([0., 1., 2., 3.]) ham = sigmaz() # Basic tests pulse1 = Pulse(ham, 1, tlist, coeff) assert_allclose( pulse1.get_ideal_qobjevo(2).ops[0].qobj, tensor(identity(2), sigmaz())) pulse1.tlist = 2 * tlist assert_allclose(pulse1.tlist, 2 * tlist) pulse1.tlist = tlist pulse1.coeff = 2 * coeff assert_allclose(pulse1.coeff, 2 * coeff) pulse1.coeff = coeff pulse1.qobj = 2 * sigmay() assert_allclose(pulse1.qobj, 2 * sigmay()) pulse1.qobj = ham pulse1.targets = 3 assert_allclose(pulse1.targets, 3) pulse1.targets = 1 assert_allclose(pulse1.get_ideal_qobj(2), tensor(identity(2), sigmaz()))
def test_simple_hadamard(self): """ Test for optimizing a simple hadamard gate """ N = 1 H_d = sigmaz() H_c = sigmax() qc = QubitCircuit(N) qc.add_gate("SNOT", 0) # test load_circuit, with verbose info num_tslots = 10 evo_time = 10 test = OptPulseProcessor(N, drift=H_d) test.add_control(H_c, targets=0) tlist, coeffs = test.load_circuit(qc, num_tslots=num_tslots, evo_time=evo_time, verbose=True) # test run_state rho0 = qubit_states(1, [0]) plus = (qubit_states(1, [0]) + qubit_states(1, [1])).unit() result = test.run_state(rho0) assert_allclose(fidelity(result.states[-1], plus), 1, rtol=1.0e-6) # test add/remove ctrl test.add_control(sigmay()) test.remove_pulse(0) assert_(len(test.pulses) == 1, msg="Method of remove_pulse could be wrong.") assert_allclose(test.drift.drift_hamiltonians[0].qobj, H_d) assert_(sigmay() in test.ctrls, msg="Method of remove_pulse could be wrong.")
def test_simple_hadamard(self): N = 1 H_d = sigmaz() H_c = [sigmax()] qc = QubitCircuit(N) qc.add_gate("SNOT", 0) # test load_circuit, with verbose info num_tslots = 10 evo_time = 10 test = OptPulseProcessor(N, H_d, H_c) tlist, coeffs = test.load_circuit( qc, num_tslots=num_tslots, evo_time=evo_time, verbose=True) # test run_state rho0 = qubit_states(1, [0]) plus = (qubit_states(1, [0]) + qubit_states(1, [1])).unit() result = test.run_state(rho0) assert_allclose(fidelity(result.states[-1], plus), 1, rtol=1.0e-6) # test add/remove ctrl test.add_ctrl(sigmay()) test.remove_ctrl(0) assert_( len(test.ctrls) == 1, msg="Method of remove_ctrl could be wrong.") assert_allclose(test.drift, H_d) assert_( sigmay() in test.ctrls, msg="Method of remove_ctrl could be wrong.")
def concurrence(rho): """ Calculate the concurrence entanglement measure for a two-qubit state. Parameters ---------- rho : qobj Density matrix for two-qubits. Returns ------- concur : float Concurrence """ if rho.dims != [[2, 2], [2, 2]]: raise Exception("Density matrix must be tensor product of two qubits.") sysy = tensor(sigmay(), sigmay()) rho_tilde = (rho * sysy) * (rho.conj() * sysy) evals = rho_tilde.eigenenergies() # abs to avoid problems with sqrt for very small negative numbers evals = abs(sort(real(evals))) lsum = sqrt(evals[3]) - sqrt(evals[2]) - sqrt(evals[1]) - sqrt(evals[0]) return max(0, lsum)
def test_multi_gates(self): N = 2 H_d = tensor([sigmaz()]*2) H_c = [] test = OptPulseProcessor(N, H_d, H_c) test.add_ctrl(sigmax(), cyclic_permutation=True) test.add_ctrl(sigmay(), cyclic_permutation=True) test.add_ctrl(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)
def TestPulseConstructor(): """ Test for creating empty Pulse, Pulse with constant coefficients etc. """ coeff = np.array([0.1, 0.2, 0.3, 0.4]) tlist = np.array([0., 1., 2., 3.]) ham = sigmaz() # Special ways of initializing pulse pulse2 = Pulse(sigmax(), 0, tlist, True) assert_allclose(pulse2.get_ideal_qobjevo(2).ops[0].qobj, tensor(sigmax(), identity(2))) pulse3 = Pulse(sigmay(), 0) assert_allclose(pulse3.get_ideal_qobjevo(2).cte.norm(), 0.) pulse4 = Pulse(None, None) # Dummy empty ham assert_allclose(pulse4.get_ideal_qobjevo(2).cte.norm(), 0.) tlist_noise = np.array([1., 2.5, 3.]) coeff_noise = np.array([0.5, 0.1, 0.5]) tlist_noise2 = np.array([0.5, 2, 3.]) coeff_noise2 = np.array([0.1, 0.2, 0.3]) # Pulse with different dims random_qobj = Qobj(np.random.random((3, 3))) pulse5 = Pulse(sigmaz(), 1, tlist, True) pulse5.add_coherent_noise(sigmay(), 1, tlist_noise, coeff_noise) pulse5.add_lindblad_noise( random_qobj, 0, tlist=tlist_noise2, coeff=coeff_noise2) qu, c_ops = pulse5.get_noisy_qobjevo(dims=[3, 2]) assert_allclose(qu.ops[0].qobj, tensor([identity(3), sigmaz()])) assert_allclose(qu.ops[1].qobj, tensor([identity(3), sigmay()])) assert_allclose(c_ops[0].ops[0].qobj, tensor([random_qobj, identity(2)]))
def add_states(self, state, kind='vector', alpha=1.0): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : qobj Input state vector. kind : str {'vector','point'} Type of object to plot. alpha : float, default=1. Transparency value for the vectors. Values between 0 and 1. """ if isinstance(state, Qobj): state = [state] for st in state: if kind == 'vector': vec = [ expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st) ] self.add_vectors(vec, alpha=alpha) elif kind == 'point': pnt = [ expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st) ] self.add_points(pnt, alpha=alpha)
def concurrence(rho): """ Calculate the concurrence entanglement measure for a two-qubit state. Parameters ---------- rho : qobj Density matrix for two-qubits. Returns ------- concur : float Concurrence """ if rho.dims != [[2, 2], [2, 2]]: raise Exception("Density matrix must be tensor product of two qubits.") sysy = tensor(sigmay(), sigmay()) rho_tilde = (rho * sysy) * (rho.conj() * sysy) evals = rho_tilde.eigenenergies() evals = abs( sort(real(evals)) ) # abs to avoid problems with sqrt for very small negative numbers lsum = sqrt(evals[3]) - sqrt(evals[2]) - sqrt(evals[1]) - sqrt(evals[0]) return max(0, lsum)
def test_multiplication(self): # Test multiplication of two Hermitian operators. This results in a # skew-Hermitian operator, so we're checking here that __mul__ doesn't # set wrong metadata. q = sigmax() * sigmay() assert_hermicity(q, False) # Similarly, we need to check that -Z = X * iY is correctly identified # as Hermitian. q = sigmax() * (1j * sigmay()) assert_hermicity(q, True)
def testOperatorListState(self): """ expect: operator list and state """ res = expect([sigmax(), sigmay(), sigmaz()], fock(2, 0)) assert_(len(res) == 3) assert_(all(abs(res - [0, 0, 1]) < 1e-12)) res = expect([sigmax(), sigmay(), sigmaz()], fock_dm(2, 1)) assert_(len(res) == 3) assert_(all(abs(res - [0, 0, -1]) < 1e-12))
def TestPlot(self): try: import matplotlib.pyplot as plt except: return True # step_func tlist = np.linspace(0., 2 * np.pi, 20) processor = Processor(N=1, spline_kind="step_func") processor.add_ctrl(sigmaz()) processor.tlist = tlist processor.coeffs = np.array([[np.sin(t) for t in tlist]]) processor.plot_pulses(noisy=False) plt.clf() # cubic spline tlist = np.linspace(0., 2 * np.pi, 20) processor = Processor(N=1, spline_kind="cubic") processor.add_ctrl(sigmaz()) processor.tlist = tlist processor.coeffs = np.array([[np.sin(t) for t in tlist]]) processor.plot_pulses(noisy=False) plt.clf() # noisy processor = Processor(N=1) processor.add_ctrl(sigmaz(), targets=0) processor.add_ctrl(sigmay(), targets=0) processor.coeffs = np.array([[0.5, 0., 0.5], [0., 0.5, 0.]]) processor.tlist = np.array( [0., np.pi / 2., 2 * np.pi / 2, 3 * np.pi / 2]) processor.plot_pulses(noisy=False) plt.clf() processor.plot_pulses(noisy=True) plt.clf()
def TestRandomNoise(self): """ Test for the white noise """ tlist = np.array([1, 2, 3, 4, 5, 6]) coeff = np.array([1, 1, 1, 1, 1, 1]) dummy_qobjevo = QobjEvo(sigmaz(), tlist=tlist) mean = 0. std = 0.5 ops = [sigmaz(), sigmax()] proc_qobjevo = QobjEvo( [[sigmaz(), coeff], [sigmax(), coeff], [sigmay(), coeff]], tlist=tlist) # random noise with external operators gaussnoise = RandomNoise(ops=ops, loc=mean, scale=std) noise = gaussnoise.get_noise(N=1, proc_qobjevo=dummy_qobjevo) assert_allclose(noise.ops[1].qobj, sigmax()) assert_allclose(len(noise.ops[1].coeff), len(tlist)) assert_allclose(len(noise.ops), len(ops)) # random noise with operators from proc_qobjevo gaussnoise = RandomNoise(loc=mean, scale=std) noise = gaussnoise.get_noise(N=1, proc_qobjevo=proc_qobjevo) assert_allclose(noise.ops[1].qobj, sigmax()) assert_(len(noise.ops[0].coeff) == len(tlist)) assert_(len(noise.ops) == len(proc_qobjevo.ops)) # random noise with dt and other random number generator gaussnoise = RandomNoise(lam=0.1, dt=0.2, rand_gen=np.random.poisson) assert_(gaussnoise.rand_gen is np.random.poisson) noise = gaussnoise.get_noise(N=1, proc_qobjevo=proc_qobjevo) assert_allclose(noise.tlist, np.linspace(1, 6, int(5 / 0.2) + 1))
def add_annotation(self, state_or_vector, text, **kwargs): """Add a text or LaTeX annotation to Bloch sphere, parametrized by a qubit state or a vector. Parameters ---------- state_or_vector : Qobj/array/list/tuple Position for the annotaion. Qobj of a qubit or a vector of 3 elements. text : str/unicode Annotation text. You can use LaTeX, but remember to use raw string e.g. r"$\\langle x \\rangle$" or escape backslashes e.g. "$\\\\langle x \\\\rangle$". **kwargs : Options as for mplot3d.axes3d.text, including: fontsize, color, horizontalalignment, verticalalignment. """ if isinstance(state_or_vector, Qobj): vec = [expect(sigmax(), state_or_vector), expect(sigmay(), state_or_vector), expect(sigmaz(), state_or_vector)] elif isinstance(state_or_vector, (list, ndarray, tuple)) \ and len(state_or_vector) == 3: vec = state_or_vector else: raise Exception("Position needs to be specified by a qubit " + "state or a 3D vector.") self.annotations.append({'position': vec, 'text': text, 'opts': kwargs})
def set_up_ops(self, N): super(CircularSpinChain, self).set_up_ops(N) x = [identity(2)] * N x[0] = x[N - 1] = sigmax() y = [identity(2)] * N y[0] = y[N - 1] = sigmay() self.ctrls.append(tensor(x) + tensor(y))
def set_up_ops(self, N): """ Generate the Hamiltonians for the spinchain model and save them in the attribute `ctrls`. Parameters ---------- N: int The number of qubits in the system. """ # sx_ops self.ctrls += [ tensor([sigmax() if m == n else identity(2) for n in range(N)]) for m in range(N) ] # sz_ops self.ctrls += [ tensor([sigmaz() if m == n else identity(2) for n in range(N)]) for m in range(N) ] # sxsy_ops for n in range(N - 1): x = [identity(2)] * N x[n] = x[n + 1] = sigmax() y = [identity(2)] * N y[n] = y[n + 1] = sigmay() self.ctrls.append(tensor(x) + tensor(y))
def test_multi_qubits(self): """ Test for multi-qubits system. """ N = 3 H_d = tensor([sigmaz()] * 3) H_c = [] # test empty ctrls num_tslots = 30 evo_time = 10 test = OptPulseProcessor(N) test.add_drift(H_d, [0, 1, 2]) test.add_control(tensor([sigmax(), sigmax()]), cyclic_permutation=True) # test periodically adding ctrls sx = sigmax() iden = identity(2) # print(test.ctrls) # print(Qobj(tensor([sx, iden, sx]))) assert_(Qobj(tensor([sx, iden, sx])) in test.ctrls) assert_(Qobj(tensor([iden, sx, sx])) in test.ctrls) assert_(Qobj(tensor([sx, sx, iden])) in test.ctrls) test.add_control(sigmax(), cyclic_permutation=True) test.add_control(sigmay(), cyclic_permutation=True) # test pulse genration for cnot gate, with kwargs qc = [tensor([identity(2), cnot()])] test.load_circuit(qc, num_tslots=num_tslots, evo_time=evo_time, min_fid_err=1.0e-6) rho0 = qubit_states(3, [1, 1, 1]) rho1 = qubit_states(3, [1, 1, 0]) result = test.run_state(rho0, options=Options(store_states=True)) assert_(fidelity(result.states[-1], rho1) > 1 - 1.0e-6)
def add_line(self, start, end, fmt="k", **kwargs): """Adds a line segment connecting two points on the bloch sphere. The line segment is set to be a black solid line by default. Parameters ---------- start : Qobj or array-like Array with cartesian coordinates of the first point, or a state vector or density matrix that can be mapped to a point on or within the Bloch sphere. end : Qobj or array-like Array with cartesian coordinates of the second point, or a state vector or density matrix that can be mapped to a point on or within the Bloch sphere. fmt : str, default: "k" A matplotlib format string for rendering the line. **kwargs : dict Additional parameters to pass to the matplotlib .plot function when rendering this line. """ if isinstance(start, Qobj): pt1 = [ expect(sigmax(), start), expect(sigmay(), start), expect(sigmaz(), start), ] else: pt1 = start if isinstance(end, Qobj): pt2 = [ expect(sigmax(), end), expect(sigmay(), end), expect(sigmaz(), end), ] else: pt2 = end pt1 = np.asarray(pt1) pt2 = np.asarray(pt2) x = [pt1[1], pt2[1]] y = [-pt1[0], -pt2[0]] z = [pt1[2], pt2[2]] v = [x, y, z] self._lines.append([v, fmt, kwargs])
def test_random_noise(self): """ Test for the white noise """ tlist = np.array([1, 2, 3, 4, 5, 6]) coeff = np.array([1, 1, 1, 1, 1, 1]) dummy_qobjevo = QobjEvo(sigmaz(), tlist=tlist) mean = 0. std = 0.5 pulses = [ Pulse(sigmaz(), 0, tlist, coeff), Pulse(sigmax(), 0, tlist, coeff * 2), Pulse(sigmay(), 0, tlist, coeff * 3) ] # random noise with operators from proc_qobjevo gaussnoise = RandomNoise(dt=0.1, rand_gen=np.random.normal, loc=mean, scale=std) noisy_pulses, systematic_noise = \ gaussnoise.get_noisy_dynamics(pulses=pulses) assert_allclose(noisy_pulses[2].qobj, sigmay()) assert_allclose(noisy_pulses[1].coherent_noise[0].qobj, sigmax()) assert_allclose(len(noisy_pulses[0].coherent_noise[0].tlist), len(noisy_pulses[0].coherent_noise[0].coeff)) # random noise with dt and other random number generator pulses = [ Pulse(sigmaz(), 0, tlist, coeff), Pulse(sigmax(), 0, tlist, coeff * 2), Pulse(sigmay(), 0, tlist, coeff * 3) ] gaussnoise = RandomNoise(lam=0.1, dt=0.2, rand_gen=np.random.poisson) assert_(gaussnoise.rand_gen is np.random.poisson) noisy_pulses, systematic_noise = \ gaussnoise.get_noisy_dynamics(pulses=pulses) assert_allclose(noisy_pulses[0].coherent_noise[0].tlist, np.linspace(1, 6, int(5 / 0.2) + 1)) assert_allclose(noisy_pulses[1].coherent_noise[0].tlist, np.linspace(1, 6, int(5 / 0.2) + 1)) assert_allclose(noisy_pulses[2].coherent_noise[0].tlist, np.linspace(1, 6, int(5 / 0.2) + 1))
def __init__(self, N, correct_global_phase=True, sx=None, sz=None, sxsy=None): """ Parameters ---------- sx: Integer/List The delta for each of the qubits in the system. sz: Integer/List The epsilon for each of the qubits in the system. sxsy: Integer/List The interaction strength for each of the qubit pair in the system. """ super(SpinChain, self).__init__(N, correct_global_phase) self.sx_ops = [ tensor([sigmax() if m == n else identity(2) for n in range(N)]) for m in range(N) ] self.sz_ops = [ tensor([sigmaz() if m == n else identity(2) for n in range(N)]) for m in range(N) ] self.sxsy_ops = [] for n in range(N - 1): x = [identity(2)] * N x[n] = x[n + 1] = sigmax() y = [identity(2)] * N y[n] = y[n + 1] = sigmay() self.sxsy_ops.append(tensor(x) + tensor(y)) if sx is None: self.sx_coeff = [0.25 * 2 * np.pi] * N elif not isinstance(sx, list): self.sx_coeff = [sx * 2 * np.pi] * N else: self.sx_coeff = sx if sz is None: self.sz_coeff = [1.0 * 2 * np.pi] * N elif not isinstance(sz, list): self.sz_coeff = [sz * 2 * np.pi] * N else: self.sz_coeff = sz if sxsy is None: self.sxsy_coeff = [0.1 * 2 * np.pi] * (N - 1) elif not isinstance(sxsy, list): self.sxsy_coeff = [sxsy * 2 * np.pi] * (N - 1) else: self.sxsy_coeff = sxsy
def case_is_clifford(self, U): paulis = (identity(2), sigmax(), sigmay(), sigmaz()) for P in paulis: U_P = U * P * U.dag() out = (np.any( np.array([self._prop_identity(U_P * Q) for Q in paulis]))) return out
def concurrence(rho): """ Calculate the concurrence entanglement measure for a two-qubit state. Parameters ---------- state : qobj Ket, bra, or density matrix for a two-qubit state. Returns ------- concur : float Concurrence References ---------- .. [1] http://en.wikipedia.org/wiki/Concurrence_(quantum_computing) """ if rho.isket and rho.dims != [[2, 2], [1, 1]]: raise Exception("Ket must be tensor product of two qubits.") elif rho.isbra and rho.dims != [[1, 1], [2, 2]]: raise Exception("Bra must be tensor product of two qubits.") elif rho.isoper and rho.dims != [[2, 2], [2, 2]]: raise Exception("Density matrix must be tensor product of two qubits.") if rho.isket or rho.isbra: rho = ket2dm(rho) sysy = tensor(sigmay(), sigmay()) rho_tilde = (rho * sysy) * (rho.conj() * sysy) evals = rho_tilde.eigenenergies() # abs to avoid problems with sqrt for very small negative numbers evals = abs(sort(real(evals))) lsum = sqrt(evals[3]) - sqrt(evals[2]) - sqrt(evals[1]) - sqrt(evals[0]) return max(0, lsum)
def testNoisyPulse(self): """ Test for lindblad noise and different tlist """ coeff = np.array([0.1, 0.2, 0.3, 0.4]) tlist = np.array([0., 1., 2., 3.]) ham = sigmaz() pulse1 = Pulse(ham, 1, tlist, coeff) # Add coherent noise and lindblad noise with different tlist pulse1.spline_kind = "step_func" tlist_noise = np.array([1., 2.5, 3.]) coeff_noise = np.array([0.5, 0.1, 0.5]) pulse1.add_coherent_noise(sigmay(), 0, tlist_noise, coeff_noise) tlist_noise2 = np.array([0.5, 2, 3.]) coeff_noise2 = np.array([0.1, 0.2, 0.3]) pulse1.add_lindblad_noise(sigmax(), 1, coeff=True) pulse1.add_lindblad_noise(sigmax(), 0, tlist=tlist_noise2, coeff=coeff_noise2) assert_allclose( pulse1.get_ideal_qobjevo(2).ops[0].qobj, tensor(identity(2), sigmaz())) noise_qu, c_ops = pulse1.get_noisy_qobjevo(2) assert_allclose(noise_qu.tlist, np.array([0., 0.5, 1., 2., 2.5, 3.])) for ele in noise_qu.ops: if ele.qobj == tensor(identity(2), sigmaz()): assert_allclose(ele.coeff, np.array([0.1, 0.1, 0.2, 0.3, 0.3, 0.4])) elif ele.qobj == tensor(sigmay(), identity(2)): assert_allclose(ele.coeff, np.array([0., 0., 0.5, 0.5, 0.1, 0.5])) for c_op in c_ops: if len(c_op.ops) == 0: assert_allclose(c_ops[0].cte, tensor(identity(2), sigmax())) else: assert_allclose(c_ops[1].ops[0].qobj, tensor(sigmax(), identity(2))) assert_allclose(c_ops[1].tlist, np.array([0., 0.5, 1., 2., 2.5, 3.])) assert_allclose(c_ops[1].ops[0].coeff, np.array([0., 0.1, 0.1, 0.2, 0.2, 0.3]))
def case_is_clifford(self, U): paulis = (identity(2), sigmax(), sigmay(), sigmaz()) for P in paulis: U_P = U * P * U.dag() out = (np.any( np.array([self._prop_identity(U_P * Q) for Q in paulis]) )) return out
def case_is_clifford(self, U): paulis = (identity(2), sigmax(), sigmay(), sigmaz()) for P in paulis: U_P = U * P * U.dag() assert_(any( self._prop_identity(U_P * Q) for Q in paulis ))
def test_modify_ctrls(self): """ Test for modifying Hamiltonian, add_control, remove_pulse """ N = 2 proc = Processor(N=N) proc.ctrls proc.add_control(sigmaz()) assert_(tensor([sigmaz(), identity(2)]), proc.ctrls[0]) proc.add_control(sigmax(), cyclic_permutation=True) assert_allclose(len(proc.ctrls), 3) assert_allclose(tensor([sigmax(), identity(2)]), proc.ctrls[1]) assert_allclose(tensor([identity(2), sigmax()]), proc.ctrls[2]) proc.add_control(sigmay(), targets=1) assert_allclose(tensor([identity(2), sigmay()]), proc.ctrls[3]) proc.remove_pulse([0, 1, 2]) assert_allclose(tensor([identity(2), sigmay()]), proc.ctrls[0]) proc.remove_pulse(0) assert_allclose(len(proc.ctrls), 0)
def add_states(self, state, kind="vector"): """Add a state vector Qobj to Bloch sphere. Parameters ---------- state : qobj Input state vector. kind : str {'vector','point'} Type of object to plot. """ if isinstance(state, Qobj): state = [state] for st in state: if kind == "vector": vec = [expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st)] self.add_vectors(vec) elif kind == "point": pnt = [expect(sigmax(), st), expect(sigmay(), st), expect(sigmaz(), st)] self.add_points(pnt)
def TestCoherentNoise(): """ Test for pulse genration with coherent noise. """ coeff = np.array([0.1, 0.2, 0.3, 0.4]) tlist = np.array([0., 1., 2., 3.]) ham = sigmaz() pulse1 = Pulse(ham, 1, tlist, coeff) # Add coherent noise with the same tlist pulse1.add_coherent_noise(sigmay(), 0, tlist, coeff) assert_allclose( pulse1.get_ideal_qobjevo(2).ops[0].qobj, tensor(identity(2), sigmaz())) assert_(len(pulse1.coherent_noise) == 1) noise_qu, c_ops = pulse1.get_noisy_qobjevo(2) assert_allclose(c_ops, []) assert_allclose(noise_qu.tlist, np.array([0., 1., 2., 3.])) qobj_list = [ele.qobj for ele in noise_qu.ops] assert_(tensor(identity(2), sigmaz()) in qobj_list) assert_(tensor(sigmay(), identity(2)) in qobj_list) for ele in noise_qu.ops: assert_allclose(ele.coeff, coeff)
def test_unitarity_known(): """ Metrics: Unitarity for known cases. """ def case(q_oper, known_unitarity): assert_almost_equal(unitarity(q_oper), known_unitarity) yield case, to_super(sigmax()), 1.0 yield case, sum(map( to_super, [qeye(2), sigmax(), sigmay(), sigmaz()])) / 4, 0.0 yield case, sum(map(to_super, [qeye(2), sigmax()])) / 2, 1 / 3.0
def test_QobjHerm(): "Qobj Hermicity" N = 10 data = np.random.random( (N, N)) + 1j * np.random.random((N, N)) - (0.5 + 0.5j) q = Qobj(data) assert_equal(q.isherm, False) data = data + data.conj().T q = Qobj(data) assert_(q.isherm) q_a = destroy(5) assert_(not q_a.isherm) q_ad = create(5) assert_(not q_ad.isherm) # test addition of two nonhermitian operators adding up to a hermitian one q_x = q_a + q_ad assert_hermicity(q_x, True) # test addition of one hermitan and one nonhermitian operator q = q_x + q_a assert_hermicity(q, False) # test addition of two hermitan operators q = q_x + q_x assert_hermicity(q, True) # Test multiplication of two Hermitian operators. # This results in a skew-Hermitian operator, so # we're checking here that __mul__ doesn't set wrong # metadata. q = sigmax() * sigmay() assert_hermicity(q, False, "Expected iZ = X * Y to be skew-Hermitian.") # Similarly, we need to check that -Z = X * iY is correctly # identified as Hermitian. q = sigmax() * (1j * sigmay()) assert_hermicity(q, True, "Expected -Z = X * iY to be Hermitian.")
def __init__(self, N, correct_global_phase=True, sx=None, sz=None, sxsy=None): """ Parameters ---------- sx: Integer/List The delta for each of the qubits in the system. sz: Integer/List The epsilon for each of the qubits in the system. sxsy: Integer/List The interaction strength for each of the qubit pair in the system. """ super(SpinChain, self).__init__(N, correct_global_phase) self.sx_ops = [tensor([sigmax() if m == n else identity(2) for n in range(N)]) for m in range(N)] self.sz_ops = [tensor([sigmaz() if m == n else identity(2) for n in range(N)]) for m in range(N)] self.sxsy_ops = [] for n in range(N - 1): x = [identity(2)] * N x[n] = x[n + 1] = sigmax() y = [identity(2)] * N y[n] = y[n + 1] = sigmay() self.sxsy_ops.append(tensor(x) + tensor(y)) if sx is None: self.sx_coeff = [0.25 * 2 * np.pi] * N elif not isinstance(sx, list): self.sx_coeff = [sx * 2 * np.pi] * N else: self.sx_coeff = sx if sz is None: self.sz_coeff = [1.0 * 2 * np.pi] * N elif not isinstance(sz, list): self.sz_coeff = [sz * 2 * np.pi] * N else: self.sz_coeff = sz if sxsy is None: self.sxsy_coeff = [0.1 * 2 * np.pi] * (N - 1) elif not isinstance(sxsy, list): self.sxsy_coeff = [sxsy * 2 * np.pi] * (N - 1) else: self.sxsy_coeff = sxsy
def TestControlAmpNoise(self): """ Test for the control amplitude noise """ tlist = np.array([1, 2, 3, 4, 5, 6]) coeff = np.array([1, 1, 1, 1, 1, 1]) # use external operators and no expansion dummy_qobjevo = QobjEvo(sigmaz(), tlist=tlist) connoise = ControlAmpNoise(ops=sigmax(), coeffs=[coeff], tlist=tlist) noise = connoise.get_noise(N=1, proc_qobjevo=dummy_qobjevo) assert_allclose(noise.ops[0].qobj, sigmax()) assert_allclose(noise.tlist, tlist) assert_allclose(noise.ops[0].coeff, coeff) dummy_qobjevo = QobjEvo(tensor([sigmaz(), sigmaz()]), tlist=tlist) connoise = ControlAmpNoise(ops=[sigmay()], coeffs=[coeff], tlist=tlist, targets=1) noise = connoise.get_noise(N=2, proc_qobjevo=dummy_qobjevo) assert_allclose(noise.ops[0].qobj, tensor([qeye(2), sigmay()])) # use external operators with expansion dummy_qobjevo = QobjEvo(sigmaz(), tlist=tlist) connoise = ControlAmpNoise(ops=sigmaz(), coeffs=[coeff] * 2, tlist=tlist, cyclic_permutation=True) noise = connoise.get_noise(N=2, proc_qobjevo=dummy_qobjevo) assert_allclose(noise.ops[0].qobj, tensor([sigmaz(), qeye(2)])) assert_allclose(noise.ops[1].qobj, tensor([qeye(2), sigmaz()])) # use proc_qobjevo proc_qobjevo = QobjEvo([[sigmaz(), coeff]], tlist=tlist) connoise = ControlAmpNoise(coeffs=[coeff], tlist=tlist) noise = connoise.get_noise(N=2, proc_qobjevo=proc_qobjevo) assert_allclose(noise.ops[0].qobj, sigmaz()) assert_allclose(noise.ops[0].coeff, coeff[0])
def y_gate(N=None, target=0): """Pauli-Y gate or sigmay operator. Returns ------- result : :class:`qutip.Qobj` Quantum object for operator describing a single-qubit rotation through pi radians around the y-axis. """ if N is not None: return gate_expand_1toN(y_gate(), N, target) return sigmay()
def test_unitarity_known(): """ Metrics: Unitarity for known cases. """ def case(q_oper, known_unitarity): assert_almost_equal(unitarity(q_oper), known_unitarity) yield case, to_super(sigmax()), 1.0 yield case, sum(map( to_super, [qeye(2), sigmax(), sigmay(), sigmaz()] )) / 4, 0.0 yield case, sum(map( to_super, [qeye(2), sigmax()] )) / 2, 1 / 3.0
def _spin_hamiltonian(N): from qutip.tensor import tensor from qutip.operators import qeye, sigmax, sigmay, sigmaz # array of spin energy splittings and coupling strengths. here we use # uniform parameters, but in general we don't have too h = 1.0 * 2 * np.pi * np.ones(N) Jz = 0.1 * 2 * np.pi * np.ones(N) Jx = 0.1 * 2 * np.pi * np.ones(N) Jy = 0.1 * 2 * np.pi * np.ones(N) # dephasing rate gamma = 0.01 * np.ones(N) si = qeye(2) sx = sigmax() sy = sigmay() sz = sigmaz() sx_list = [] sy_list = [] sz_list = [] for n in range(N): op_list = [] for m in range(N): op_list.append(si) op_list[n] = sx sx_list.append(tensor(op_list)) op_list[n] = sy sy_list.append(tensor(op_list)) op_list[n] = sz sz_list.append(tensor(op_list)) # construct the hamiltonian H = 0 # energy splitting terms for n in range(N): H += - 0.5 * h[n] * sz_list[n] # interaction terms for n in range(N-1): H += - 0.5 * Jx[n] * sx_list[n] * sx_list[n+1] H += - 0.5 * Jy[n] * sy_list[n] * sy_list[n+1] H += - 0.5 * Jz[n] * sz_list[n] * sz_list[n+1] return H
def __init__(self, N, correct_global_phase=True, sx=None, sz=None, sxsy=None): super(CircularSpinChain, self).__init__(N, correct_global_phase, sx, sz, sxsy) x = [identity(2)] * N x[0] = x[N - 1] = sigmax() y = [identity(2)] * N y[0] = y[N - 1] = sigmay() self.sxsy_ops.append(tensor(x) + tensor(y)) if sxsy is None: self.sxsy_coeff = [0.1 * 2 * np.pi] * N elif not isinstance(sxsy, list): self.sxsy_coeff = [sxsy * 2 * np.pi] * N else: self.sxsy_coeff = sxsy
def test_QobjUnitaryOper(): "Qobj unitarity" # Check some standard operators Sx = sigmax() Sy = sigmay() assert_unitarity(qeye(4), True, "qeye(4) should be unitary.") assert_unitarity(Sx, True, "sigmax() should be unitary.") assert_unitarity(Sy, True, "sigmax() should be unitary.") assert_unitarity(sigmam(), False, "sigmam() should NOT be unitary.") assert_unitarity(destroy(10), False, "destroy(10) should NOT be unitary.") # Check multiplcation of unitary is unitary assert_unitarity(Sx*Sy, True, "sigmax()*sigmay() should be unitary.") # Check some other operations clear unitarity assert_unitarity(Sx+Sy, False, "sigmax()+sigmay() should NOT be unitary.") assert_unitarity(4*Sx, False, "4*sigmax() should NOT be unitary.") assert_unitarity(Sx*4, False, "sigmax()*4 should NOT be unitary.") assert_unitarity(4+Sx, False, "4+sigmax() should NOT be unitary.") assert_unitarity(Sx+4, False, "sigmax()+4 should NOT be unitary.")
def testOperatorListStateList(self): """ expect: operator list and state list """ operators = [sigmax(), sigmay(), sigmaz(), sigmam(), sigmap()] states = [fock(2, 0), fock(2, 1), fock_dm(2, 0), fock_dm(2, 1)] res = expect(operators, states) assert_(len(res) == len(operators)) for r_idx, r in enumerate(res): assert_(isinstance(r, np.ndarray)) if operators[r_idx].isherm: assert_(r.dtype == np.float64) else: assert_(r.dtype == np.complex128) for s_idx, s in enumerate(states): assert_(r[s_idx] == expect(operators[r_idx], states[s_idx]))
def testExpectSolverCompatibility(self): """ expect: operator list and state list """ c_ops = [0.0001 * sigmaz()] e_ops = [sigmax(), sigmay(), sigmaz(), sigmam(), sigmap()] times = np.linspace(0, 10, 100) res1 = mesolve(sigmax(), fock(2, 0), times, c_ops, e_ops) res2 = mesolve(sigmax(), fock(2, 0), times, c_ops, []) e1 = res1.expect e2 = expect(e_ops, res2.states) assert_(len(e1) == len(e2)) for n in range(len(e1)): assert_(len(e1[n]) == len(e2[n])) assert_(isinstance(e1[n], np.ndarray)) assert_(isinstance(e2[n], np.ndarray)) assert_(e1[n].dtype == e2[n].dtype) assert_(all(abs(e1[n] - e2[n]) < 1e-12))
CPTP, expand to arbitrary dimensional systems, etc. """ return Qobj(dims=[[[2], [2]], [[2], [2]]], inpt=array([[1. - pe / 2., 0., 0., 1. - pe], [0., pe / 2., 0., 0.], [0., 0., pe / 2., 0.], [1. - pe, 0., 0., 1. - pe / 2.]]), superrep='choi') # CHANGE OF BASIS FUNCTIONS --------------------------------------------------- # These functions find change of basis matrices, and are useful in converting # between (for instance) Choi and chi matrices. At some point, these should # probably be moved out to another module. _SINGLE_QUBIT_PAULI_BASIS = (identity(2), sigmax(), sigmay(), sigmaz()) def _pauli_basis(nq=1): # NOTE: This is slow as can be. # TODO: Make this sparse. CSR format was causing problems for the [idx, :] # slicing below. B = zeros((4 ** nq, 4 ** nq), dtype=complex) dims = [[[2] * nq] * 2] * 2 for idx, op in enumerate(starmap(tensor, product(_SINGLE_QUBIT_PAULI_BASIS, repeat=nq))): B[:, idx] = operator_to_vector(op).dag().data.todense() return Qobj(B, dims=dims)
def test_known_iscptp(self): """ Superoperator: ishp, iscp, istp and iscptp known cases. """ def case(qobj, shouldhp, shouldcp, shouldtp): hp = qobj.ishp cp = qobj.iscp tp = qobj.istp cptp = qobj.iscptp shouldcptp = shouldcp and shouldtp if ( hp == shouldhp and cp == shouldcp and tp == shouldtp and cptp == shouldcptp ): return fails = [] if hp != shouldhp: fails.append(("ishp", shouldhp, hp)) if tp != shouldtp: fails.append(("istp", shouldtp, tp)) if cp != shouldcp: fails.append(("iscp", shouldcp, cp)) if cptp != shouldcptp: fails.append(("iscptp", shouldcptp, cptp)) raise AssertionError("Expected {}.".format(" and ".join([ "{} == {} (got {})".format(fail, expected, got) for fail, expected, got in fails ]))) # Conjugation by a creation operator should # have be CP (and hence HP), but not TP. a = create(2).dag() S = sprepost(a, a.dag()) case(S, True, True, False) # A single off-diagonal element should not be CP, # nor even HP. S = sprepost(a, a) case(S, False, False, False) # Check that unitaries are CPTP and HP. case(identity(2), True, True, True) case(sigmax(), True, True, True) # Check that unitaries on bipartite systems are CPTP and HP. case(tensor(sigmax(), identity(2)), True, True, True) # Check that a linear combination of bipartitie unitaries is CPTP and HP. S = ( to_super(tensor(sigmax(), identity(2))) + to_super(tensor(identity(2), sigmay())) ) / 2 case(S, True, True, True) # The partial transpose map, whose Choi matrix is SWAP, is TP # and HP but not CP (one negative eigenvalue). W = Qobj(swap(), type='super', superrep='choi') case(W, True, False, True) # Subnormalized maps (representing erasure channels, for instance) # can be CP but not TP. subnorm_map = Qobj(identity(4) * 0.9, type='super', superrep='super') case(subnorm_map, True, True, False) # Check that things which aren't even operators aren't identified as # CPTP. case(basis(2), False, False, False)