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_FSim() -> None: for _ in range(REPS): theta = random.uniform(-np.pi, +np.pi) phi = random.uniform(-np.pi, +np.pi) gate0 = qf.FSim(theta, phi, 0, 1) # Test with decomposition from Cirq. circ = qf.Circuit() circ += qf.XX(theta / np.pi, 0, 1) circ += qf.YY(theta / np.pi, 0, 1) circ += qf.CZ(0, 1)**(-phi / np.pi) gate1 = circ.asgate() assert qf.gates_close(gate0, gate1) assert qf.gates_close(gate1.H, gate0.H)
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))