def test_trotterization(self): circ_vec = [Circuit(), build_circuit('Z_0')] coef_vec = [-1.0j * 0.5, -1.0j * -0.04544288414432624] # the operator to be exponentiated minus_iH = QubitOperator() for i in range(len(circ_vec)): minus_iH.add(coef_vec[i], circ_vec[i]) # exponentiate the operator Utrot, phase = trotterization.trotterize(minus_iH) inital_state = np.zeros(2**4, dtype=complex) inital_state[3] = np.sqrt(2 / 3) inital_state[12] = -np.sqrt(1 / 3) # initalize a quantum computer with above coeficients # i.e. ca|1100> + cb|0011> qc = Computer(4) qc.set_coeff_vec(inital_state) # apply the troterized minus_iH qc.apply_circuit(Utrot) qc.apply_constant(phase) smart_print(qc) coeffs = qc.get_coeff_vec() assert np.real(coeffs[3]) == approx(0.6980209737879599, abs=1.0e-15) assert np.imag(coeffs[3]) == approx(-0.423595782342996, abs=1.0e-15) assert np.real(coeffs[12]) == approx(-0.5187235657531178, abs=1.0e-15) assert np.imag(coeffs[12]) == approx(0.25349397560041553, abs=1.0e-15)
def test_op_exp_val_1(self): # test direct expectation value measurement trial_state = Computer(4) trial_prep = [None] * 5 trial_prep[0] = gate('H', 0, 0) trial_prep[1] = gate('H', 1, 1) trial_prep[2] = gate('H', 2, 2) trial_prep[3] = gate('H', 3, 3) trial_prep[4] = gate('cX', 0, 1) trial_circ = Circuit() #prepare the circuit for gate_ in trial_prep: trial_circ.add(gate_) # use circuit to prepare trial state trial_state.apply_circuit(trial_circ) # gates needed for [a1^ a2] operator X1 = gate('X', 1, 1) X2 = gate('X', 2, 2) Y1 = gate('Y', 1, 1) Y2 = gate('Y', 2, 2) # initialize circuits to make operator circ1 = Circuit() circ1.add(X2) circ1.add(Y1) circ2 = Circuit() circ2.add(Y2) circ2.add(Y1) circ3 = Circuit() circ3.add(X2) circ3.add(X1) circ4 = Circuit() circ4.add(Y2) circ4.add(X1) #build the quantum operator for [a1^ a2] a1_dag_a2 = QubitOperator() a1_dag_a2.add(0.0 - 0.25j, circ1) a1_dag_a2.add(0.25, circ2) a1_dag_a2.add(0.25, circ3) a1_dag_a2.add(0.0 + 0.25j, circ4) #get direct expectatoin value exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(0.25, abs=2.0e-16)
def test_io_simplified(self): # test direct expectation value measurement trial_state = Computer(4) trial_circ = build_circuit('H_0 H_1 H_2 H_3 cX_0_1') # use circuit to prepare trial state trial_state.apply_circuit(trial_circ) #build the quantum operator for [a1^ a2] a1_dag_a2 = build_operator('0.0-0.25j, X_2 Y_1; 0.25, Y_2 Y_1; \ 0.25, X_2 X_1; 0.0+0.25j, Y_2 X_1') #get direct expectatoin value exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(0.25, abs=2.0e-16)
def test_qft(self): trial_state = Computer(4) trial_circ = build_circuit('X_0 X_1') trial_state.apply_circuit(trial_circ) # verify direct transformation qft(trial_state, 0, 3) a1_dag_a2 = build_operator('1.0, Z_0') exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(0, abs=1.0e-16) # test unitarity qft(trial_state, 0, 2) rev_qft(trial_state, 0, 2) a1_dag_a2 = build_operator('1.0, Z_0') exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(0, abs=1.0e-16) # test reverse transformation qft(trial_state, 0, 3) a1_dag_a2 = build_operator('1.0, Z_0') exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(1.0, abs=1.0e-14)
def test_Z_gate(self): # test the Pauli Y gate nqubits = 1 basis0 = make_basis('0') basis1 = make_basis('1') computer = Computer(nqubits) Z = gate('Z', 0, 0) # test Z|0> = |0> computer.apply_gate(Z) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0 == approx(1, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) # test Z|1> = -|1> computer.set_state([(basis1, 1.0)]) computer.apply_gate(Z) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(-1.0, abs=1.0e-16)
def test_Y_gate(self): # test the Pauli Y gate nqubits = 1 basis0 = make_basis('0') basis1 = make_basis('1') computer = Computer(nqubits) Y = gate('Y', 0, 0) # test Y|0> = i|1> computer.apply_gate(Y) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1.imag == approx(1.0, abs=1.0 - 16) # test Y|1> = -i|0> computer.set_state([(basis1, 1.0)]) computer.apply_gate(Y) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0.imag == approx(-1, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16)
def test_X_gate(self): # test the Pauli X gate nqubits = 1 basis0 = make_basis('0') basis1 = make_basis('1') computer = Computer(nqubits) X = gate('X', 0) # test X|0> = |1> computer.apply_gate(X) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(1, abs=1.0e-16) # test X|1> = |0> computer.set_state([(basis1, 1.0)]) computer.apply_gate(X) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) assert coeff0 == approx(1, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16)
def test_advanced_gates(self): print('\n') trial_state = Computer(4) trial_circ = build_circuit('X_0 X_1') trial_state.apply_circuit(trial_circ) # verify Toffoli gate T_circ = Toffoli(0, 1, 2) print(T_circ.str()) trial_state.apply_circuit(T_circ) # This should turn the state to 1110 a1_dag_a2 = build_operator('1.0, Z_2') exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(-1, abs=9e-16) # Measure qubit 2 should give -1 # verify Fredkin gate F_circ = Fredkin(1, 2, 3) print(F_circ.str()) trial_state.apply_circuit(F_circ) # This should turn the state to 1101 # trial_state.apply_circuit_safe(F_circ) # This should turn the state to 1101 a1_dag_a2 = build_operator('1.0, Z_2') exp = trial_state.direct_op_exp_val(a1_dag_a2) assert exp == approx(1, abs=9e-16) # Measure qubit 2 should give +1
def test_computer(self): print('\n') # test that 1 - 1 = 0 # print('\n'.join(qc.str())) X = gate('X', 0, 0) print(X) Y = gate('Y', 0, 0) print(Y) Z = gate('Z', 0, 0) print(Z) H = gate('H', 0, 0) print(H) R = gate('R', 0, 0, 0.1) print(R) S = gate('S', 0, 0) print(S) T = gate('T', 0, 0) print(T) cX = gate('cX', 0, 1) print(cX) cY = gate('cY', 0, 1) print(cY) cZ = gate('cZ', 0, 1) print(cZ) # qcircuit = Circuit() # qcircuit.add(qg) # qcircuit.add(Gate(GateType.Hgate,1,1)); # print('\n'.join(qcircuit.str())) # self.assertEqual(subtract(1, 1), 0) computer = Computer(16) # print(repr(computer)) # circuit = Circuit() # circuit.add(X) for i in range(3000): computer.apply_gate(X) computer.apply_gate(Y) computer.apply_gate(Z) computer.apply_gate(H)
def test_sparse_operator(self): """ test the SparseMatrix and SparseVector classes """ coeff_vec = [ -0.093750, +0.093750j, -0.093750, -0.093750j, -0.093750, -0.093750j, +0.062500j, -0.093750, -0.093750, +0.093750j, +0.093750, -0.062500, -0.093750j, -0.062500j, +0.062500j, -0.062500, +0.062500, +0.062500, -0.062500j, -0.093750, +0.062500j, -0.062500, -0.062500j, -0.062500, +0.093750j, +0.093750j, +0.062500j, +0.093750, -0.062500, -0.062500, -0.093750j, -0.062500j ] circ_vec = [ build_circuit('X_1 Y_2 X_3 Y_4'), build_circuit('X_1 Y_2 X_3 X_4'), build_circuit('X_1 Y_2 Y_3 X_4'), build_circuit('X_1 X_2 X_3 Y_4'), build_circuit('X_1 X_2 X_3 X_4'), build_circuit('X_1 X_2 Y_3 X_4'), build_circuit('Y_2 X_3 X_4 Z_5 X_6'), build_circuit('Y_1 Y_2 Y_3 Y_4'), build_circuit('Y_1 X_2 X_3 Y_4'), build_circuit('Y_1 X_2 X_3 X_4'), build_circuit('Y_1 Y_2 X_3 X_4'), build_circuit('X_2 X_3 X_4 Z_5 X_6'), build_circuit('Y_1 X_2 Y_3 Y_4'), build_circuit('X_2 Y_3 Y_4 Z_5 Y_6'), build_circuit('X_2 Y_3 X_4 Z_5 X_6'), build_circuit('X_2 Y_3 Y_4 Z_5 X_6'), build_circuit('X_2 X_3 Y_4 Z_5 Y_6'), build_circuit('Y_2 Y_3 X_4 Z_5 X_6'), build_circuit('X_2 X_3 Y_4 Z_5 X_6'), build_circuit('Y_1 X_2 Y_3 X_4'), build_circuit('Y_2 Y_3 X_4 Z_5 Y_6'), build_circuit('Y_2 X_3 X_4 Z_5 Y_6'), build_circuit('X_2 X_3 X_4 Z_5 Y_6'), build_circuit('X_2 Y_3 X_4 Z_5 Y_6'), build_circuit('Y_1 Y_2 Y_3 X_4'), build_circuit('Y_1 Y_2 X_3 Y_4'), build_circuit('Y_2 Y_3 Y_4 Z_5 X_6'), build_circuit('X_1 X_2 Y_3 Y_4'), build_circuit('Y_2 Y_3 Y_4 Z_5 Y_6'), build_circuit('Y_2 X_3 Y_4 Z_5 X_6'), build_circuit('X_1 Y_2 Y_3 Y_4'), build_circuit('Y_2 X_3 Y_4 Z_5 Y_6') ] qubit_op = QubitOperator() for coeff, circ in zip(coeff_vec, circ_vec): qubit_op.add(coeff, circ) num_qb = qubit_op.num_qubits() qci = Computer(num_qb) arb_vec = np.linspace(0, 2 * np.pi, 2**num_qb) arb_vec = arb_vec / np.linalg.norm(arb_vec) qci.set_coeff_vec(arb_vec) sp_mat_op = qubit_op.sparse_matrix(num_qb) ci = np.array(qci.get_coeff_vec()) qci.apply_operator(qubit_op) diff_vec = np.array(qci.get_coeff_vec()) # Reset stae qci.set_coeff_vec(ci) qci.apply_sparse_matrix(sp_mat_op) # see if there is a difference diff_vec = np.array(qci.get_coeff_vec()) - diff_vec diff_val = np.linalg.norm(diff_vec) print('Operator used for sparse matrix operator test: \n', qubit_op) print('||∆||: ', diff_val) assert diff_val < 1.0e-15
def test_trotterization_with_controlled_U(self): circ_vec = [build_circuit('Y_0 X_1'), build_circuit('X_0 Y_1')] coef_vec = [-1.0719145972781818j, 1.0719145972781818j] # the operator to be exponentiated minus_iH = QubitOperator() for i in range(len(circ_vec)): minus_iH.add(coef_vec[i], circ_vec[i]) ancilla_idx = 2 # exponentiate the operator Utrot, phase = trotterization.trotterize_w_cRz(minus_iH, ancilla_idx) # Case 1: positive control # initalize a quantum computer qc = Computer(3) # build HF state qc.apply_gate(gate('X', 0, 0)) # put ancilla in |1> state qc.apply_gate(gate('X', 2, 2)) # apply the troterized minus_iH qc.apply_circuit(Utrot) smart_print(qc) coeffs = qc.get_coeff_vec() assert coeffs[5] == approx(-0.5421829373021542, abs=1.0e-15) assert coeffs[6] == approx(-0.8402604730072732, abs=1.0e-15) # Case 2: negitive control # initalize a quantum computer qc = Computer(3) # build HF state qc.apply_gate(gate('X', 0, 0)) # apply the troterized minus_iH qc.apply_circuit(Utrot) smart_print(qc) coeffs = qc.get_coeff_vec() assert coeffs[1] == approx(1, abs=1.0e-15)
def circuit_tester(prep, test_circ): for gate in test_circ.gates(): id = gate.gate_id() target = gate.target() control = gate.control() num_qubits = 5 qc1 = Computer(num_qubits) qc2 = Computer(num_qubits) qc1.apply_circuit_safe(prep) qc2.apply_circuit_safe(prep) qc1.apply_gate_safe(gate) qc2.apply_gate(gate) C1 = qc1.get_coeff_vec() C2 = qc2.get_coeff_vec() diff_vec = [(C1[i] - C2[i]) * np.conj(C1[i] - C2[i]) for i in range(len(C1))] diff_norm = np.sum(diff_vec) if (np.sum(diff_vec) != (0.0 + 0.0j)): print('|C - C_safe|F^2 control target id') print('----------------------------------------') print(diff_norm, ' ', control, ' ', target, ' ', id) return diff_norm
def test_cX_gate(self): # test the cX/CNOT gate nqubits = 2 basis0 = make_basis('00') # basis0:|00> basis1 = make_basis('01') # basis1:|10> basis2 = make_basis('10') # basis2:|01> basis3 = make_basis('11') # basis3:|11> computer = Computer(nqubits) CNOT = gate('CNOT', 0, 1) # test CNOT|00> = |00> computer.set_state([(basis0, 1.0)]) computer.apply_gate(CNOT) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(1.0, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16) # test CNOT|10> = |11> computer.set_state([(basis1, 1.0)]) computer.apply_gate(CNOT) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3 == approx(1, abs=1.0e-16) # test CNOT|01> = |01> computer.set_state([(basis2, 1.0)]) computer.apply_gate(CNOT) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(1, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16) # test CNOT|11> = |10> computer.set_state([(basis3, 1.0)]) computer.apply_gate(CNOT) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(1, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16) with pytest.raises(ValueError): gate('CNOT', 0, 1.0)
def test_cY_gate(self): # test the cY gate nqubits = 2 basis0 = make_basis('00') # basis0:|00> basis1 = make_basis('01') # basis1:|10> basis2 = make_basis('10') # basis2:|01> basis3 = make_basis('11') # basis3:|11> computer = Computer(nqubits) cY = gate('cY', 0, 1) # test cY|00> = |00> computer.set_state([(basis0, 1.0)]) computer.apply_gate(cY) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(1, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16) # test cY|01> = |01> computer.set_state([(basis2, 1.0)]) computer.apply_gate(cY) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(1, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16) # test cY|10> = i|11> computer.set_state([(basis1, 1.0)]) computer.apply_gate(cY) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1 == approx(0, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3.imag == approx(1, abs=1.0e-16) # test cY|11> = -i|10> computer.set_state([(basis3, 1.0)]) computer.apply_gate(cY) coeff0 = computer.coeff(basis0) coeff1 = computer.coeff(basis1) coeff2 = computer.coeff(basis2) coeff3 = computer.coeff(basis3) assert coeff0 == approx(0, abs=1.0e-16) assert coeff1.imag == approx(-1.0, abs=1.0e-16) assert coeff2 == approx(0, abs=1.0e-16) assert coeff3 == approx(0, abs=1.0e-16)
def test_circuit(self): print('\n') num_qubits = 10 qc1 = Computer(num_qubits) qc2 = Computer(num_qubits) prep_circ = Circuit() circ = Circuit() for i in range(num_qubits): prep_circ.add(gate('H', i, i)) for i in range(num_qubits): prep_circ.add(gate('cR', i, i + 1, 1.116 / (i + 1.0))) for i in range(num_qubits - 1): circ.add(gate('cX', i, i + 1)) circ.add(gate('cX', i + 1, i)) circ.add(gate('cY', i, i + 1)) circ.add(gate('cY', i + 1, i)) circ.add(gate('cZ', i, i + 1)) circ.add(gate('cZ', i + 1, i)) circ.add(gate('cR', i, i + 1, 3.14159 / (i + 1.0))) circ.add(gate('cR', i + 1, i, 2.17284 / (i + 1.0))) qc1.apply_circuit_safe(prep_circ) qc2.apply_circuit_safe(prep_circ) qc1.apply_circuit_safe(circ) qc2.apply_circuit(circ) C1 = qc1.get_coeff_vec() C2 = qc2.get_coeff_vec() diff_vec = [(C1[i] - C2[i]) * np.conj(C1[i] - C2[i]) for i in range(len(C1))] diff_norm = np.sum(diff_vec) print('\nNorm of diff vec |C - Csafe|') print('-----------------------------') print(' ', diff_norm) assert diff_norm == approx(0, abs=1.0e-16)