def test_RZZ() -> None: theta = 0.23 gate0 = qf.RZZ(theta, 0, 1) gate1 = qf.ZZ(theta / np.pi, 0, 1) assert qf.gates_close(gate0, gate1) assert qf.gates_close(gate0.H, gate1.H) assert qf.gates_close(gate0**0.12, gate1**0.12)
def test_phase_estimation_circuit(): N = 8 phase = 1 / 4 gate = qf.RZ(-4 * np.pi * phase, N) circ = qf.phase_estimation_circuit(gate, range(N)) res = circ.run().measure()[0:N] est_phase = bitlist_to_int(res) / 2**N assert phase - est_phase == ALMOST_ZERO phase = 12 / 256 gate = qf.RZ(-4 * np.pi * phase, N) circ = qf.phase_estimation_circuit(gate, range(N)) res = circ.run().measure()[0:N] est_phase = bitlist_to_int(res) / 2**N assert phase - est_phase == ALMOST_ZERO gate = qf.ZZ(-4 * phase, N, N + 1) circ = qf.phase_estimation_circuit(gate, range(N)) res = circ.run().measure()[0:N] est_phase = bitlist_to_int(res) / 2**N assert phase - est_phase == ALMOST_ZERO with pytest.raises(ValueError): # Gate and output qubits overlap circ = qf.phase_estimation_circuit(gate, range(N + 1))
def test_gates_commute() -> None: assert qf.gates_commute(qf.X(0), qf.X(0)) assert not qf.gates_commute(qf.X(0), qf.T(0)) assert qf.gates_commute(qf.X(0), qf.T(1)) assert qf.gates_commute(qf.S(0), qf.T(0)) assert qf.gates_commute(qf.S(0), qf.T(0)) assert qf.gates_commute(qf.XX(0.1, 0, 1), qf.X(0)) assert not qf.gates_commute(qf.ZZ(0.1, 0, 1), qf.X(0))
def test_gates_to_latex(): circ = qf.Circuit() circ += qf.I(7) circ += qf.X(0) circ += qf.Y(1) circ += qf.Z(2) circ += qf.H(3) circ += qf.S(4) circ += qf.T(5) circ += qf.S_H(6) circ += qf.T_H(7) circ += qf.RX(-0.5*pi, 0) circ += qf.RY(0.5*pi, 1) circ += qf.RZ((1/3)*pi, 1) circ += qf.RY(0.222, 1) circ += qf.TX(0.5, 0) circ += qf.TY(0.5, 1) circ += qf.TZ(0.4, 1) circ += qf.TZ(0.47276, 1) # Gate with cunning hack gate = qf.RZ(0.4, 1) gate.params['theta'] = qf.Parameter('\\theta') circ += gate circ += qf.CNOT(1, 2) circ += qf.CNOT(2, 1) circ += qf.CZ(1, 3) circ += qf.SWAP(1, 5) circ += qf.ISWAP(4, 2) # circ += qf.Barrier(0, 1, 2, 3, 4, 5, 6) # Not yet supported circ += qf.CCNOT(1, 2, 3) circ += qf.CSWAP(4, 5, 6) circ += qf.P0(0) circ += qf.P1(1) circ += qf.Reset(2) circ += qf.Reset(4, 5, 6) circ += qf.H(4) # circ += qf.Reset() # FIXME. Should fail with clear error message circ += qf.XX(0.25, 1, 3) circ += qf.YY(0.75, 1, 3) circ += qf.ZZ(1/3, 3, 1) circ += qf.Measure(0) latex = qf.circuit_to_latex(circ) print(latex)
def test_phase_estimation_circuit_3() -> None: N = 8 phase = 12 / 256 gate = qf.ZZ(-4 * phase, N, N + 1) circ = qf.phase_estimation_circuit(gate, range(N)) res = circ.run().measure()[0:N] est_phase = bitlist_to_int(res) / 2 ** N assert np.isclose(phase, est_phase) with pytest.raises(ValueError): # Gate and output qubits overlap _ = qf.phase_estimation_circuit(gate, range(N + 1))
def test_circuit_to_circ() -> None: q0, q1, q2 = "q0", "q1", "q2" circ0 = qf.Circuit() circ0 += qf.I(q0) circ0 += qf.X(q1) circ0 += qf.Y(q2) circ0 += qf.Z(q0) circ0 += qf.S(q1) circ0 += qf.T(q2) circ0 += qf.H(q0) circ0 += qf.H(q1) circ0 += qf.H(q2) circ0 += qf.XPow(0.6, q0) circ0 += qf.YPow(0.6, q1) circ0 += qf.ZPow(0.6, q2) circ0 += qf.XX(0.2, q0, q1) circ0 += qf.YY(0.3, q1, q2) circ0 += qf.ZZ(0.4, q2, q0) circ0 += qf.CZ(q0, q1) circ0 += qf.CNot(q0, q1) circ0 += qf.Swap(q0, q1) circ0 += qf.ISwap(q0, q1) circ0 += qf.CCZ(q0, q1, q2) circ0 += qf.CCNot(q0, q1, q2) circ0 += qf.CSwap(q0, q1, q2) circ0 += qf.FSim(1, 2, q0, q1) diag0 = qf.circuit_to_diagram(circ0) # print() # print(diag0) cqc = circuit_to_cirq(circ0) # print(cqc) circ1 = cirq_to_circuit(cqc) diag1 = qf.circuit_to_diagram(circ1) # print() # print(diag1) assert diag0 == diag1
def test_cirq_simulator() -> None: q0, q1, q2 = "q0", "q1", "q2" circ0 = qf.Circuit() circ0 += qf.I(q0) circ0 += qf.I(q1) circ0 += qf.I(q2) circ0 += qf.X(q1) circ0 += qf.Y(q2) circ0 += qf.Z(q0) circ0 += qf.S(q1) circ0 += qf.T(q2) circ0 += qf.H(q0) circ0 += qf.H(q1) circ0 += qf.H(q2) circ0 += qf.XPow(0.6, q0) circ0 += qf.YPow(0.6, q1) circ0 += qf.ZPow(0.6, q2) circ0 += qf.XX(0.2, q0, q1) circ0 += qf.YY(0.3, q1, q2) circ0 += qf.ZZ(0.4, q2, q0) circ0 += qf.CZ(q0, q1) circ0 += qf.CNot(q0, q1) circ0 += qf.Swap(q0, q1) circ0 += qf.ISwap(q0, q1) circ0 += qf.CCZ(q0, q1, q2) circ0 += qf.CCNot(q0, q1, q2) circ0 += qf.CSwap(q0, q1, q2) ket0 = qf.random_state([q0, q1, q2]) ket1 = circ0.run(ket0) sim = CirqSimulator(circ0) ket2 = sim.run(ket0) assert ket1.qubits == ket2.qubits print(qf.state_angle(ket1, ket2)) assert qf.states_close(ket1, ket2) assert qf.states_close(circ0.run(), sim.run())
def test_specialize_2q() -> None: q0, q1 = 3, 5 assert isinstance(qf.Can(0.0, 0.0, 0.0, q0, q1).specialize(), qf.I) assert isinstance(qf.Can(0.213, 0.0, 0.0, q0, q1).specialize(), qf.XX) assert isinstance(qf.Can(0.0, 0.213, 0.0, q0, q1).specialize(), qf.YY) assert isinstance(qf.Can(0.0, 0.0, 0.213, q0, q1).specialize(), qf.ZZ) assert isinstance( qf.Can(0.213, 0.213, 0.213, q0, q1).specialize(), qf.Exch) assert isinstance(qf.Can(0.5, 0.32, 0.213, q0, q1).specialize(), qf.Can) assert isinstance(qf.CNotPow(0.2, q0, q1).specialize(), qf.CNotPow) assert isinstance(qf.CNotPow(0.0, q0, q1).specialize(), qf.I) assert isinstance(qf.CNotPow(1.0, q0, q1).specialize(), qf.CNot) assert isinstance(qf.XX(0.0, q0, q1).specialize(), qf.I) assert isinstance(qf.YY(0.0, q0, q1).specialize(), qf.I) assert isinstance(qf.ZZ(0.0, q0, q1).specialize(), qf.I) assert isinstance(qf.Exch(0.0, q0, q1).specialize(), qf.I)
def test_gatepow(): gates = [ qf.I(), qf.X(), qf.Y(), qf.Z(), qf.H(), qf.S(), qf.T(), qf.PHASE(0.1), qf.RX(0.2), qf.RY(0.3), qf.RZ(0.4), qf.CZ(), qf.CNOT(), qf.SWAP(), qf.ISWAP(), qf.CPHASE00(0.5), qf.CPHASE01(0.6), qf.CPHASE10(0.6), qf.CPHASE(0.7), qf.PSWAP(0.15), qf.CCNOT(), qf.CSWAP(), qf.TX(2.7), qf.TY(1.2), qf.TZ(0.3), qf.ZYZ(3.5, 0.9, 2.1), qf.CANONICAL(0.1, 0.2, 7.4), qf.XX(1.8), qf.YY(0.9), qf.ZZ(0.45), qf.PISWAP(0.2), qf.EXCH(0.1), qf.TH(0.3) ] for gate in gates: assert qf.gates_close(gate.H, gate**-1) for gate in gates: sqrt_gate = gate**(1 / 2) two_gate = sqrt_gate @ sqrt_gate assert qf.gates_close(gate, two_gate) for gate in gates: gate0 = gate**0.3 gate1 = gate**0.7 gate2 = gate0 @ gate1 assert qf.gates_close(gate, gate2) for K in range(1, 5): gate = qf.random_gate(K) # FIXME: Throw error on K=0 sqrt_gate = gate**0.5 two_gate = sqrt_gate @ sqrt_gate assert qf.gates_close(gate, two_gate) for gate in gates: rgate = qf.Gate((gate**0.5).tensor) tgate = rgate @ rgate assert qf.gates_close(gate, tgate)
def test_visualize_circuit() -> None: circ = qf.Circuit() circ += qf.I(7) circ += qf.X(0) circ += qf.Y(1) circ += qf.Z(2) circ += qf.H(3) circ += qf.S(4) circ += qf.T(5) circ += qf.S_H(6) circ += qf.T_H(7) circ += qf.Rx(-0.5 * pi, 0) circ += qf.Ry(0.5 * pi, 4) circ += qf.Rz((1 / 3) * pi, 5) circ += qf.Ry(0.222, 6) circ += qf.XPow(0.5, 0) circ += qf.YPow(0.5, 2) circ += qf.ZPow(0.4, 2) circ += qf.HPow(0.5, 3) circ += qf.ZPow(0.47276, 1) # Gate with symbolic parameter # gate = qf.Rz(Symbol('\\theta'), 1) # circ += gate circ += qf.CNot(1, 2) circ += qf.CNot(2, 1) # circ += qf.IDEN(*range(8)) circ += qf.ISwap(4, 2) circ += qf.ISwap(6, 5) circ += qf.CZ(1, 3) circ += qf.Swap(1, 5) # circ += qf.Barrier(0, 1, 2, 3, 4, 5, 6) # Not yet supported in latex circ += qf.CCNot(1, 2, 3) circ += qf.CSwap(4, 5, 6) circ += qf.P0(0) circ += qf.P1(1) circ += qf.Reset(2) circ += qf.Reset(4, 5, 6) circ += qf.H(4) circ += qf.XX(0.25, 1, 4) circ += qf.XX(0.25, 1, 2) circ += qf.YY(0.75, 1, 3) circ += qf.ZZ(1 / 3, 3, 1) circ += qf.CPhase(0, 0, 1) circ += qf.CPhase(pi * 1 / 2, 0, 4) circ += qf.Can(1 / 3, 1 / 2, 1 / 2, 0, 1) circ += qf.Can(1 / 3, 1 / 2, 1 / 2, 2, 4) circ += qf.Can(1 / 3, 1 / 2, 1 / 2, 6, 5) # circ += qf.Measure(0) # circ += qf.Measure(1, 1) circ += qf.PSwap(pi / 2, 6, 7) circ += qf.Ph(1 / 4, 7) circ += qf.CH(1, 6) circ += qf.visualization.NoWire([0, 1, 2]) # circ += qf.visualization.NoWire(4, 1, 2) if os.environ.get("QF_VIZTEST"): print() print(qf.circuit_to_diagram(circ)) qf.circuit_to_diagram(circ) qf.circuit_to_latex(circ) qf.circuit_to_latex(circ, package="qcircuit") qf.circuit_to_latex(circ, package="quantikz") qf.circuit_to_diagram(circ) qf.circuit_to_diagram(circ, use_unicode=False) latex = qf.circuit_to_latex(circ, package="qcircuit") print(latex) if os.environ.get("QF_VIZTEST"): qf.latex_to_image(latex).show() latex = qf.circuit_to_latex(circ, package="quantikz") print(latex) if os.environ.get("QF_VIZTEST"): qf.latex_to_image(latex).show()
def test_cirq_to_circuit() -> None: q0 = cq.LineQubit(0) q1 = cq.LineQubit(1) q2 = cq.LineQubit(2) gate = cirq_to_circuit(cq.Circuit(cq.X(q0)))[0] assert isinstance(gate, qf.X) assert gate.qubits == (0, ) gate = cirq_to_circuit(cq.Circuit(cq.X(q1)**0.4))[0] assert isinstance(gate, qf.XPow) assert gate.qubits == (1, ) gate = cirq_to_circuit(cq.Circuit(cq.CZ(q1, q0)))[0] assert isinstance(gate, qf.CZ) assert gate.qubits == (1, 0) gate = cirq_to_circuit(cq.Circuit(cq.CZ(q1, q0)**0.3))[0] assert isinstance(gate, qf.CZPow) assert gate.qubits == (1, 0) assert gate.param("t") == 0.3 gate = cirq_to_circuit(cq.Circuit(cq.CNOT(q0, q1)))[0] assert isinstance(gate, qf.CNot) assert gate.qubits == (0, 1) gate = cirq_to_circuit(cq.Circuit(cq.CNOT(q0, q1)**0.25))[0] assert isinstance(gate, qf.CNotPow) assert gate.qubits == (0, 1) assert gate.param("t") == 0.25 gate = cirq_to_circuit(cq.Circuit(cq.SWAP(q0, q1)))[0] assert isinstance(gate, qf.Swap) gate = cirq_to_circuit(cq.Circuit(cq.ISWAP(q0, q1)))[0] assert isinstance(gate, qf.ISwap) gate = cirq_to_circuit(cq.Circuit(cq.CSWAP(q0, q1, q2)))[0] assert isinstance(gate, qf.CSwap) gate = cirq_to_circuit(cq.Circuit(cq.CCX(q0, q1, q2)))[0] assert isinstance(gate, qf.CCNot) gate = cirq_to_circuit(cq.Circuit(cq.CCZ(q0, q1, q2)))[0] assert isinstance(gate, qf.CCZ) gate = cirq_to_circuit(cq.Circuit(cq.I(q0)))[0] assert isinstance(gate, qf.I) gate = cirq_to_circuit(cq.Circuit(cq.XX(q0, q2)))[0] assert isinstance(gate, qf.XX) assert gate.param("t") == 1.0 gate = cirq_to_circuit(cq.Circuit(cq.XX(q0, q2)**0.3))[0] assert isinstance(gate, qf.XX) assert gate.param("t") == 0.3 gate = cirq_to_circuit(cq.Circuit(cq.YY(q0, q2)))[0] assert isinstance(gate, qf.YY) assert gate.param("t") == 1.0 gate = cirq_to_circuit(cq.Circuit(cq.YY(q0, q2)**0.3))[0] assert isinstance(gate, qf.YY) assert gate.param("t") == 0.3 gate = cirq_to_circuit(cq.Circuit(cq.ZZ(q0, q2)))[0] assert isinstance(gate, qf.ZZ) assert gate.param("t") == 1.0 gate = cirq_to_circuit(cq.Circuit(cq.ZZ(q0, q2)**0.3))[0] assert isinstance(gate, qf.ZZ) assert gate.param("t") == 0.3 # Check that cirq's parity gates are the same as QF's XX, YY, ZZ # up to parity U = (cq.XX(q0, q2)**0.8)._unitary_() gate0 = qf.Unitary(U, [0, 1]) assert qf.gates_close(gate0, qf.XX(0.8, 0, 1)) U = (cq.YY(q0, q2)**0.3)._unitary_() gate0 = qf.Unitary(U, [0, 1]) assert qf.gates_close(gate0, qf.YY(0.3, 0, 1)) U = (cq.ZZ(q0, q2)**0.2)._unitary_() gate0 = qf.Unitary(U, [0, 1]) assert qf.gates_close(gate0, qf.ZZ(0.2, 0, 1))