def test_if(): circ = qf.Circuit() c = qf.Register('c') circ += qf.Move(c[0], 0) circ += qf.Move(c[1], 1) circ += qf.If(qf.X(0), c[1]) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 1 assert circ.evolve().memory[c[0]] == 1 circ = qf.Circuit() c = qf.Register('c') circ += qf.Move(c[0], 0) circ += qf.Move(c[1], 0) circ += qf.If(qf.X(0), c[1]) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 0 assert circ.evolve().memory[c[0]] == 0 circ = qf.Circuit() c = qf.Register('c') circ += qf.Move(c[0], 0) circ += qf.Move(c[1], 0) circ += qf.If(qf.X(0), c[1], value=False) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 1 assert circ.evolve().memory[c[0]] == 1
def test_kraus_qubits(): kraus = qf.Kraus([qf.X(1), qf.Y(0)]) assert kraus.qubits == (0, 1) kraus = qf.Kraus([qf.X('a'), qf.Y('b')]) assert len(kraus.qubits) == 2 assert kraus.qubit_nb == 2
def test_control_gate() -> None: gate0 = qf.ControlGate([0], qf.X(1)) gate1 = qf.CNot(0, 1) assert qf.gates_close(gate0, gate1) gateb = qf.ControlGate([1], qf.X(0)) gate2 = qf.CNot(1, 0) assert qf.gates_close(gateb, gate2) gate3 = qf.ControlGate([0], qf.Y(1)) gate4 = qf.CY(0, 1) assert qf.gates_close(gate3, gate4) gate5 = qf.ControlGate([0], qf.Z(1)) gate6 = qf.CZ(0, 1) assert qf.gates_close(gate5, gate6) gate7 = qf.ControlGate([0], qf.H(1)) gate8 = qf.CH(0, 1) assert qf.gates_close(gate7, gate8) gate9 = qf.ControlGate([0, 1], qf.X(2)) gate10 = qf.CCNot(0, 1, 2) assert qf.gates_close(gate9, gate10) gate11 = qf.ControlGate([0], qf.Swap(1, 2)) gate12 = qf.CSwap(0, 1, 2) assert qf.gates_close(gate11, gate12)
def test_kraus_qubits() -> None: kraus = qf.Kraus([qf.X(1), qf.Y(0)]) assert kraus.qubits == (0, 1) kraus = qf.Kraus([qf.X("a"), qf.Y("b")]) assert len(kraus.qubits) == 2 assert kraus.qubit_nb == 2
def test_CH(): # Construct a controlled Hadamard gate gate = qf.identity_gate(2) gate = qf.S(1).H @ gate gate = qf.H(1) @ gate gate = qf.T(1).H @ gate gate = qf.CNOT(0, 1) @ gate gate = qf.T(1) @ gate gate = qf.H(1) @ gate gate = qf.S(1) @ gate # Do nothing ket = qf.zero_state(2) ket = gate.run(ket) assert qf.states_close(ket, qf.zero_state(2)) # Do nothing ket = qf.zero_state(2) ket = qf.X(0).run(ket) ket = gate.run(ket) ket = qf.H(1).run(ket) ket = qf.X(0).run(ket) assert qf.states_close(ket, qf.zero_state(2))
def test_inner_product(): # also tested via test_gate_angle for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) hs = qf.asarray(qf.inner_product(qf.RX(theta).vec, qf.RX(theta).vec)) print('RX({}), hilbert_schmidt = {}'.format(theta, hs)) assert hs / 2 == ALMOST_ONE hs = qf.asarray(qf.inner_product(qf.RZ(theta).vec, qf.RZ(theta).vec)) print('RZ({}), hilbert_schmidt = {}'.format(theta, hs)) assert hs / 2 == ALMOST_ONE hs = qf.asarray(qf.inner_product(qf.RY(theta).vec, qf.RY(theta).vec)) print('RY({}), hilbert_schmidt = {}'.format(theta, hs)) assert hs / 2 == ALMOST_ONE hs = qf.asarray( qf.inner_product(qf.PSWAP(theta).vec, qf.PSWAP(theta).vec)) print('PSWAP({}), hilbert_schmidt = {}'.format(theta, hs)) assert hs / 4 == ALMOST_ONE with pytest.raises(ValueError): qf.inner_product(qf.zero_state(0).vec, qf.X(0).vec) with pytest.raises(ValueError): qf.inner_product(qf.CNOT(0, 1).vec, qf.X(0).vec)
def test_pauli_decompose_hermitian() -> None: gate = qf.X(0) H = gate.asoperator() pl = qf.pauli_decompose_hermitian(H) assert np.allclose(pl.asoperator(), H) gate = qf.X(0) op = gate.asoperator() H = -scipy.linalg.logm(op) / 1.0j pl = qf.pauli_decompose_hermitian(H) assert np.allclose(pl.asoperator(), H) N = 4 gate2 = qf.RandomGate(range(N)) op = gate2.asoperator() H = -scipy.linalg.logm(op) / 1.0j pl = qf.pauli_decompose_hermitian(H) assert np.allclose(pl.asoperator(), H) op = np.ones(shape=[2, 2, 2]) with pytest.raises(ValueError): qf.pauli_decompose_hermitian(op) op = np.ones(shape=[4, 4]) op[0, 1] = 10000 with pytest.raises(ValueError): qf.pauli_decompose_hermitian(op) op = np.ones(shape=[3, 3]) with pytest.raises(ValueError): qf.pauli_decompose_hermitian(op)
def test_inner_product() -> None: # also tested via fubini_study_angle for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) hs = tensors.inner(qf.Rx(theta, 0).tensor, qf.Rx(theta, 0).tensor) print(f"Rx({theta}), hilbert_schmidt = {hs}") assert np.isclose(hs / 2, 1.0) hs = tensors.inner(qf.Rz(theta, 0).tensor, qf.Rz(theta, 0).tensor) print(f"Rz({theta}), hilbert_schmidt = {hs}") assert np.isclose(hs / 2, 1.0) hs = tensors.inner(qf.Ry(theta, 0).tensor, qf.Ry(theta, 0).tensor) print(f"Ry({theta}), hilbert_schmidt = {hs}") assert np.isclose(hs / 2, 1.0) hs = tensors.inner( qf.PSwap(theta, 0, 1).tensor, qf.PSwap(theta, 0, 1).tensor) print(f"PSwap({theta}), hilbert_schmidt = {hs}") assert np.isclose(hs / 4, 1.0) with pytest.raises(ValueError): tensors.inner(qf.zero_state(0).tensor, qf.X(0).tensor) with pytest.raises(ValueError): tensors.inner(qf.CNot(0, 1).tensor, qf.X(0).tensor)
def test_if() -> None: circ = qf.Circuit() c = ["c0", "c1"] circ += qf.Store(c[0], 0) circ += qf.Store(c[1], 0) circ += qf.If(qf.X(0), c[1], value=False) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 1 assert circ.evolve().memory[c[0]] == 1 circ = qf.Circuit() circ += qf.Store(c[0], 0) circ += qf.Store(c[1], 0) circ += qf.If(qf.X(0), c[1]) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 0 assert circ.evolve().memory[c[0]] == 0 circ = qf.Circuit() circ += qf.Store(c[0], 0) circ += qf.Store(c[1], 0) circ += qf.If(qf.X(0), c[1], value=False) circ += qf.Measure(0, c[0]) ket = circ.run() assert ket.memory[c[0]] == 1 assert circ.evolve().memory[c[0]] == 1
def test_join_gates(): gate = qf.join_gates(qf.H(0), qf.X(1)) ket = qf.zero_state(2) ket = gate.run(ket) ket = qf.H(0).run(ket) ket = qf.X(1).run(ket) assert qf.states_close(ket, qf.zero_state(2))
def test_circuit_flat() -> None: circ0 = qf.Circuit([qf.X(0), qf.X(1)]) circ1 = qf.Circuit([qf.Y(0), qf.Y(1)]) circ2 = qf.Circuit([circ1, qf.Z(0), qf.Z(1)]) circ = qf.Circuit([circ0, circ2]) flat = qf.Circuit(circ.flat()) assert len(flat) == 6 assert flat[2].name == "Y"
def test_cswap(): ket = qf.zero_state(3) ket = qf.X(1).run(ket) ket = qf.CSWAP(0, 1, 2).run(ket) assert ket.vec.asarray()[0, 1, 0] == ALMOST_ONE ket = qf.X(0).run(ket) ket = qf.CSWAP(0, 1, 2).run(ket) assert ket.vec.asarray()[1, 0, 1] == ALMOST_ONE
def test_CZ(): ket = qf.zero_state(2) ket = qf.CZ(0, 1).run(ket) assert ket.vec.asarray()[0, 0] == ALMOST_ONE ket = qf.X(0).run(ket) ket = qf.X(1).run(ket) ket = qf.CZ(0, 1).run(ket) assert -ket.vec.asarray()[1, 1] == ALMOST_ONE
def test_CZ() -> None: ket = qf.zero_state(2) ket = qf.CZ(0, 1).run(ket) assert ket.tensor[0, 0] == 1.0 ket = qf.X(0).run(ket) ket = qf.X(1).run(ket) ket = qf.CZ(0, 1).run(ket) assert -ket.tensor[1, 1] == 1.0
def test_conditional_gate() -> None: controlled_gate = qf.conditional_gate(0, qf.X(1), qf.Y(1)) state = qf.zero_state(2) state = controlled_gate.run(state) assert state.tensor[0, 1] == 1.0 state = qf.X(0).run(state) state = controlled_gate.run(state) assert 1.0j * state.tensor[1, 0] == 1.0
def test_conditional_gate(): controlled_gate = qf.conditional_gate(0, qf.X(1), qf.Y(1)) state = qf.zero_state(2) state = controlled_gate.run(state) assert state.vec.asarray()[0, 1] == ALMOST_ONE state = qf.X(0).run(state) state = controlled_gate.run(state) assert 1.0j * state.vec.asarray()[1, 0] == ALMOST_ONE
def test_display_probabilities() -> None: circ = qf.Circuit() circ += qf.X(1) circ += qf.X(2) circ += qf.ProbabilityDisplay(key="prob") ket = circ.run() assert "prob" in ket.memory rho = circ.evolve() assert "prob" in rho.memory
def test_display_state() -> None: circ = qf.Circuit() circ += qf.X(1) circ += qf.X(2) circ += qf.StateDisplay(key="state0") ket = circ.run() assert "state0" in ket.memory rho = circ.evolve() assert "state0" in rho.memory
def test_ccnot(): ket = qf.zero_state(3) ket = qf.CCNOT(0, 1, 2).run(ket) assert ket.vec.asarray()[0, 0, 0] == ALMOST_ONE ket = qf.X(1).run(ket) ket = qf.CCNOT(0, 1, 2).run(ket) assert ket.vec.asarray()[0, 1, 0] == ALMOST_ONE ket = qf.X(0).run(ket) ket = qf.CCNOT(0, 1, 2).run(ket) assert ket.vec.asarray()[1, 1, 1] == ALMOST_ONE
def test_state_labels(): # Quil labeling convention N = 4 qubits = range(N - 1, -1, -1) ket = qf.zero_state(qubits) ket = qf.X(0).run(ket) ket = qf.X(1).run(ket) assert ket.vec.asarray()[0, 0, 1, 1] == ALMOST_ONE ket = ket.relabel([0, 1, 3, 4]) assert ket.vec.asarray()[0, 0, 1, 1] == ALMOST_ONE ket = ket.permute([4, 3, 0, 1])
def test_density_display() -> None: circ = qf.Circuit() circ += qf.X(1) circ += qf.X(2) circ += qf.DensityDisplay(key="bloch1", qubits=[1]) ket = circ.run() assert "bloch1" in ket.memory assert ket.memory["bloch1"].qubits == (1, ) rho = circ.evolve() assert "bloch1" in rho.memory assert rho.memory["bloch1"].qubits == (1, )
def test_cphase_gates(): for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) gate11 = qf.control_gate(0, qf.PHASE(theta, 1)) assert qf.gates_close(gate11, qf.CPHASE(theta, 0, 1)) gate01 = qf.conditional_gate(0, qf.PHASE(theta, 1), qf.I(1)) assert qf.gates_close(gate01, qf.CPHASE01(theta)) gate00 = qf.identity_gate(2) gate00 = qf.X(0) @ gate00 gate00 = qf.X(1) @ gate00 gate00 = gate11 @ gate00 gate00 = qf.X(0) @ gate00 gate00 = qf.X(1) @ gate00 assert qf.gates_close(gate00, qf.CPHASE00(theta)) gate10 = qf.identity_gate(2) gate10 = qf.X(0) @ gate10 gate10 = qf.X(1) @ gate10 gate10 = gate01 @ gate10 gate10 = qf.X(0) @ gate10 gate10 = qf.X(1) @ gate10 assert qf.gates_close(gate10, qf.CPHASE10(theta))
def test_defgate_param(): prog = qf.parse_quil(CP) # ket0 = prog.compile() # qf.print_state(ket0) ket1 = prog.run() qf.print_state(ket1) ket = qf.zero_state(2) ket = qf.X(0).run(ket) ket = qf.X(1).run(ket) ket = qf.CPHASE(1.0, 0, 1).run(ket) qf.print_state(ket) assert qf.states_close(ket1, ket)
def test_qftgate() -> None: circ = qf.Circuit() circ += qf.X(2) circ += qf.QFTGate([0, 1, 2]) ket = qf.zero_state(3) ket = circ.run(ket) true_qft = qf.State( [ 0.35355339 + 0.0j, 0.25000000 + 0.25j, 0.00000000 + 0.35355339j, -0.25000000 + 0.25j, -0.35355339 + 0.0j, -0.25000000 - 0.25j, 0.00000000 - 0.35355339j, 0.25000000 - 0.25j, ] ) assert qf.states_close(ket, true_qft) assert isinstance(qf.QFTGate([0, 1, 2]).H, qf.InvQFTGate) assert isinstance(qf.QFTGate([0, 1, 2]).H.H, qf.QFTGate) qf.QFTGate([0, 1, 2]).H.tensor
def test_gatemul(): # three cnots same as one swap gate0 = qf.identity_gate([0, 1]) gate1 = qf.CNOT(1, 0) gate2 = qf.CNOT(0, 1) gate3 = qf.CNOT(1, 0) gate = gate0 gate = gate1 @ gate gate = gate2 @ gate gate = gate3 @ gate assert qf.gates_close(gate, qf.SWAP()) # Again, but with labels gate0 = qf.identity_gate(['a', 'b']) gate1 = qf.CNOT('b', 'a') gate2 = qf.CNOT('a', 'b') gate3 = qf.CNOT('b', 'a') gate = gate0 gate = gate1 @ gate gate = gate2 @ gate gate = gate3 @ gate assert qf.gates_close(gate, qf.SWAP('a', 'b')) gate4 = qf.X('a') gate = gate4 @ gate with pytest.raises(NotImplementedError): gate = gate4 @ 3
def test_moment() -> None: circ = qf.Circuit() circ += qf.X(0) circ += qf.Swap(1, 2) moment = qf.Moment(circ) assert moment.qubits == (0, 1, 2) assert moment.run() assert moment.evolve() assert isinstance(moment.H, qf.Moment) circ += qf.Y(0) with pytest.raises(ValueError): moment = qf.Moment(circ) assert moment.asgate() assert moment.aschannel() circ1 = qf.Circuit(moment) assert len(circ1) == 2 assert isinstance(moment[1], qf.Swap) moment1 = moment.on("a", "b", "c") moment2 = moment1.rewire({"a": 0, "b": 1, "c": 2}) assert str(moment) == str(moment2)
def test_CH() -> None: gate1 = qf.CH(0, 1) # I picked up this circuit for a CH gate from qiskit # qiskit/extensions/standard/ch.py # But it clearly far too long. CH is locally equivalent to CNOT, # so requires only one CNOT gate. circ2 = qf.Circuit([ qf.H(1), qf.S_H(1), qf.CNot(0, 1), qf.H(1), qf.T(1), qf.CNot(0, 1), qf.T(1), qf.H(1), qf.S(1), qf.X(1), qf.S(0), ]) assert qf.gates_close(gate1, circ2.asgate()) # Here's a better decomposition circ1 = qf.Circuit([qf.YPow(+0.25, 1), qf.CNot(0, 1), qf.YPow(-0.25, 1)]) assert qf.gates_close(gate1, circ1.asgate()) assert qf.circuits_close(circ1, circ2)
def test_unitary_1qubit(): assert qf.almost_unitary(qf.X()) assert qf.almost_unitary(qf.Y()) assert qf.almost_unitary(qf.Z()) assert qf.almost_unitary(qf.H()) assert qf.almost_unitary(qf.S()) assert qf.almost_unitary(qf.T())
def test_circuit_to_pyquil(): circ = qf.Circuit() circ += qf.X(0) prog = qf.forest.circuit_to_pyquil(circ) assert str(prog) == "X 0\n" circ = qf.Circuit() circ1 = qf.Circuit() circ2 = qf.Circuit() circ1 += qf.RY(pi/2, 0) circ1 += qf.RX(pi, 0) circ1 += qf.RY(pi/2, 1) circ1 += qf.RX(pi, 1) circ1 += qf.CNOT(0, 1) circ2 += qf.RX(-pi/2, 1) circ2 += qf.RY(4.71572463191, 1) circ2 += qf.RX(pi/2, 1) circ2 += qf.CNOT(0, 1) circ2 += qf.RX(-2*2.74973750579, 0) circ2 += qf.RX(-2*2.74973750579, 1) circ.extend(circ1) circ.extend(circ2) prog = qf.forest.circuit_to_pyquil(circ) print(prog) assert QUILPROG == str(prog)
def test_parametric_gates1(): for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) assert qf.almost_unitary(qf.RX(theta)) assert qf.almost_unitary(qf.RY(theta)) assert qf.almost_unitary(qf.RZ(theta)) for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) assert qf.almost_unitary(qf.TX(theta)) assert qf.almost_unitary(qf.TY(theta)) assert qf.almost_unitary(qf.TZ(theta)) for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) assert qf.almost_unitary(qf.CPHASE00(theta)) assert qf.almost_unitary(qf.CPHASE01(theta)) assert qf.almost_unitary(qf.CPHASE10(theta)) assert qf.almost_unitary(qf.CPHASE(theta)) assert qf.almost_unitary(qf.PSWAP(theta)) assert qf.gates_close(qf.I(), qf.I()) assert qf.gates_close(qf.RX(pi), qf.X()) assert qf.gates_close(qf.RY(pi), qf.Y()) assert qf.gates_close(qf.RZ(pi), qf.Z())