def test_phase_damping_error_ideal(self):
     """Test phase damping error with param=0 (ideal)"""
     error = phase_damping_error(0)
     circ, p = error.error_term(0)
     self.assertEqual(p, 1, msg="ideal probability")
     self.assertEqual(circ[0], {"name": "id", "qubits": [0]},
                      msg="ideal circuit")
Example #2
0
 def test_phase_damping_error_full_noncanonical(self):
     """Test phase damping error with param=1 and non-canonical kraus"""
     error = phase_damping_error(1, canonical_kraus=False)
     circ, p = error.error_term(0)
     targets = [np.diag([1, 0]), np.diag([0, 1])]
     self.assertEqual(p, 1, msg="Kraus probability")
     self.assertEqual(circ[0][1], [circ.qubits[0]])
     self.assertTrue(np.allclose(circ[0][0].params, targets), msg="Incorrect kraus matrices")
 def test_phase_damping_error_full_noncanonical(self):
     """Test phase damping error with param=1 and non-canonical kraus"""
     error = phase_damping_error(1, canonical_kraus=False)
     circ, p = error.error_term(0)
     targets = [np.diag([1, 0]), np.diag([0, 1])]
     self.assertEqual(p, 1, msg="Kraus probability")
     self.assertEqual(circ[0]["qubits"], [0])
     for op in circ[0]['params']:
         self.remove_if_found(op, targets)
     self.assertEqual(targets, [], msg="Incorrect kraus matrices")
Example #4
0
 def test_phase_damping_error_noncanonical(self):
     """Test phase damping error with non-canonical kraus"""
     p_phase = 0.3
     error = phase_damping_error(0.3, canonical_kraus=False)
     circ, p = error.error_term(0)
     targets = [np.array([[1, 0], [0, np.sqrt(1 - p_phase)]]),
                np.array([[0, 0], [0, np.sqrt(p_phase)]])]
     self.assertEqual(p, 1, msg="Kraus probability")
     self.assertEqual(circ[0][1], [circ.qubits[0]])
     self.assertTrue(np.allclose(circ[0][0].params, targets), msg="Incorrect kraus matrices")
 def test_phase_damping_error_noncanonical(self):
     """Test phase damping error with non-canonical kraus"""
     p_phase = 0.3
     error = phase_damping_error(0.3, canonical_kraus=False)
     circ, p = error.error_term(0)
     targets = [np.array([[1, 0], [0, np.sqrt(1 - p_phase)]]),
                np.array([[0, 0], [0, np.sqrt(p_phase)]])]
     self.assertEqual(p, 1, msg="Kraus probability")
     self.assertEqual(circ[0]["qubits"], [0])
     for op in circ[0]['params']:
         self.remove_if_found(op, targets)
     self.assertEqual(targets, [], msg="Incorrect kraus matrices")
 def test_phase_damping_error_canonical(self):
     """Test phase damping error with canonical kraus"""
     p_phase = 0.3
     error = phase_damping_error(p_phase, canonical_kraus=True)
     # The canonical form of this channel should be a mixed
     # unitary dephasing channel
     targets = [[{'name': 'z', 'qubits': [0]}],
                [{'name': 'id', 'qubits': [0]}]]
     for j in range(2):
         circ, p = error.error_term(j)
         self.assertEqual(circ[0]["qubits"], [0])
         self.remove_if_found(circ, targets)
     self.assertEqual(targets, [], msg="Incorrect canonical circuits")
Example #7
0
    def test_t2(self):
        """
        Run the simulator with dephasing noise.
        Then verify that the calculated T2 matches the dephasing parameter.
        """

        # 25 numbers ranging from 1 to 200, linearly spaced
        num_of_gates = (np.linspace(1, 300, 35)).astype(int)
        gate_time = 0.11
        num_of_qubits = 2
        qubit = 0

        circs, xdata = t2_circuits(num_of_gates, gate_time, num_of_qubits,
                                   qubit)

        expected_t2 = 20
        gamma = 1 - np.exp(-2 * gate_time / expected_t2)
        error = phase_damping_error(gamma)
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(error, 'id')
        # TODO: Include SPAM errors

        backend = qiskit.Aer.get_backend('qasm_simulator')
        shots = 300
        backend_result = qiskit.execute(circs,
                                        backend,
                                        shots=shots,
                                        backend_options={
                                            'max_parallel_experiments': 0
                                        },
                                        noise_model=noise_model).result()

        initial_t2 = expected_t2
        initial_a = 1
        initial_c = 0.5 * (-1)

        fit = T2Fitter(backend_result,
                       shots,
                       xdata,
                       num_of_qubits,
                       qubit,
                       fit_p0=[initial_a, initial_t2, initial_c],
                       fit_bounds=([0, 0, -1], [2, expected_t2 * 1.2, 1]))

        self.assertAlmostEqual(fit.time,
                               expected_t2,
                               delta=4,
                               msg='Calculated T2 is inaccurate')
        self.assertTrue(
            fit.time_err < 5,
            'Confidence in T2 calculation is too low: ' + str(fit.time_err))
Example #8
0
 def test_phase_damping_error_canonical(self):
     """Test phase damping error with canonical kraus"""
     p_phase = 0.3
     error = phase_damping_error(p_phase, canonical_kraus=True)
     # The canonical form of this channel should be a mixed
     # unitary dephasing channel
     targets = [qi.Pauli("I").to_matrix(),
                qi.Pauli("Z").to_matrix()]
     self.assertEqual(error.size, 1)
     circ, p = error.error_term(0)
     self.assertEqual(p, 1, msg="Kraus probability")
     self.assertEqual(circ[0][1], [circ.qubits[0]])
     for actual, expected in zip(circ[0][0].params, targets):
         self.assertTrue(np.allclose(actual/actual[0][0], expected),
                         msg="Incorrect kraus matrix")
Example #9
0
    def test_t2star(self):
        """
        Run the simulator with phase damping noise.
        Then verify that the calculated T2star matches the phase damping parameter.
        """

        # Setting parameters

        # 25 numbers ranging from 100 to 1000, linearly spaced
        num_of_gates = num_of_gates = np.append((np.linspace(10, 150, 30)).astype(int),
                                                (np.linspace(160,450,20)).astype(int))
        gate_time = 0.1
        num_of_qubits = 1
        qubit = 0

        expected_t2 = 10
        p = 1 - np.exp(-2*gate_time/expected_t2)
        error = phase_damping_error(p)
        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(error, 'id')

        backend = qiskit.Aer.get_backend('qasm_simulator')
        shots = 300


        # Estimating T2* via an exponential function

        circs, xdata, _ = circuits.t2star(num_of_gates, gate_time, num_of_qubits, qubit)
        backend_result = qiskit.execute(circs, backend,
                                        shots=shots,
                                        backend_options={'max_parallel_experiments': 0},
                                        noise_model=noise_model).result()

        initial_t2 = expected_t2
        initial_a = 0.5
        initial_c = 0.5

        fit = T2StarExpFitter(backend_result, shots, xdata, num_of_qubits, qubit,
                              fit_p0=[initial_a, initial_t2, initial_c],
                              fit_bounds=([-0.5, 0, -0.5], [1.5, expected_t2*1.2, 1.5]))

        print(fit.time)
        print(fit.time_err)

        self.assertAlmostEqual(fit.time, expected_t2, delta=2,
                               msg='Calculated T2 is inaccurate')
        self.assertTrue(fit.time_err < 2,
                        'Confidence in T2 calculation is too low: ' + str(fit.time_err))


        # Estimate T2* via an oscilliator function

        circs_osc, xdata, omega = circuits.t2star(num_of_gates, gate_time, num_of_qubits, qubit, 5)

        backend_result = qiskit.execute(circs_osc, backend,
                                        shots=shots,
                                        backend_options={'max_parallel_experiments': 0},
                                        noise_model=noise_model).result()

        initial_a = 0.5
        initial_c = 0.5
        initial_f = omega
        initial_phi = 0

        fit = T2StarOscFitter(backend_result, shots, xdata, num_of_qubits, qubit,
                              fit_p0=[initial_a, initial_t2, initial_f, initial_phi, initial_c],
                              fit_bounds=([-0.5, 0, omega-0.02, -np.pi, -0.5],
                                          [1.5, expected_t2*1.2, omega+0.02, np.pi, 1.5]))

        print(fit.time)
        print(fit.time_err)

        self.assertAlmostEqual(fit.time, expected_t2, delta=2,
                               msg='Calculated T2 is inaccurate')
        self.assertTrue(fit.time_err < 2,
                        'Confidence in T2 calculation is too low: ' + str(fit.time_err))
Example #10
0
 def test_phase_damping_error_ideal(self):
     """Test phase damping error with param=0 (ideal)"""
     error = phase_damping_error(0)
     circ, p = error.error_term(0)
     self.assertEqual(p, 1, msg="ideal probability")
     self.assertTrue(error.ideal(), msg="ideal circuit")
Example #11
0
def quantum_cadets(n_qubits, noise_circuit, damping_error=0.02):
	"""
	n_qubits [int]: total number of qubits - 2^(n_qubits-1) is the number of qft points, plus one sensing qubit
	noise_circuit [function]: function that takes one input (a time index between 0-1) and returns a quantum circuit with 1 qubit
	damping_error [float]: T2 damping error
	"""
	register_size = n_qubits - 1

	# Create a Quantum Circuit acting on the q register
	qr = QuantumRegister(n_qubits, 'q')
	cr = ClassicalRegister(register_size)
	qc = QuantumCircuit(qr, cr)

	# Add a H gate on qubit 1,2,3...N-1
	for i in range(register_size):
		qc.h(i+1)

	# multi-qubit controlled-not (mcmt) gate
	mcmt_gate = MCMT(XGate(), register_size, 1)
	qr_range=[*range(1, n_qubits), 0]

	for bit in range(2**register_size):
		qc.append(mcmt_gate, [qr[i] for i in qr_range])
		# external noise gates
		qc.append(noise_circuit(bit / 2**register_size), [qr[0]])
		qc.append(mcmt_gate, [qr[i] for i in qr_range])

		if bit == 0:
			for i in range(register_size):
				qc.x(i + (n_qubits - register_size))
		elif bit == 2**register_size - 1:
			pass
		else:
			conv_register, XRange = build_encode_circuit(bit, n_qubits, register_size)
			qc.append(conv_register, qr[XRange])

	# run the QFT
	qft = circuit.library.QFT(register_size)
	qc.append(qft, qr[1:n_qubits])

	# map the quantum measurement to classical bits
	qc.measure(range(1, n_qubits), range(0, register_size))

	# display the quantum circuit in text form
	print(qc.draw('text'))
	#qc.draw('mpl')
	plt.show()

	# noise model
	t2_noise_model = NoiseModel()
	t2_noise_model.add_quantum_error(phase_damping_error(damping_error), 'id', [0])

	# run the quantum circuit on the statevector simulator backend
	#backend = Aer.get_backend('statevector_simulator')
	# run the quantum circuit on the qasm simulator backend
	backend = Aer.get_backend('qasm_simulator')
	# number of histogram samples
	shots = 10000

	# execute the quantum program
	job = execute(qc, backend, noise_model=t2_noise_model, shots=shots)
	# outputstate = result.get_statevector(qc, decimals=3)
	# visualization.plot_state_city(outputstate)
	result = job.result()
	# collect the state histogram counts
	counts = result.get_counts(qc)
	#plot_histogram(counts)

	qft_result = np.zeros(2**register_size)
	for f in range(len(qft_result)):
		# invert qubit order and convert to string
		f_bin_str = ('{0:0' + str(register_size) + 'b}').format(f)[::-1]
		if f_bin_str in counts:
			if f:
				# flip frequency axis and assign histogram counts
				qft_result[2**register_size - f] = counts[f_bin_str] / shots
			else:
				# assign histogram counts, no flipping because of qft representation (due to nyquist sampling?)
				qft_result[0] = counts[f_bin_str] / shots

	freq = np.arange(2**register_size)
	plt.plot(freq, qft_result, label='QFT')
	plt.xlabel('Frequency (Hz)')

	# print the final measurement results
	print('QFT spectrum:') 
	print(qft_result)

	# show the plots
	plt.show()