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_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_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_identity(): chan = qf.identity_gate(1).aschannel() rho = qf.random_density(2) after = chan.evolve(rho) assert qf.densities_close(rho, after) assert chan.name == 'Channel'
def test_inverse_random(): K = 4 for _ in range(REPS): gate = qf.random_gate(K) inv = gate.H gate = inv @ gate assert qf.gates_close(qf.identity_gate(4), gate)
def test_fubini_study_angle(): for _ in range(REPS): theta = random.uniform(-pi, +pi) ang = qf.asarray(qf.fubini_study_angle(qf.I().vec, qf.RX(theta).vec)) assert 2 * ang / abs(theta) == ALMOST_ONE ang = qf.asarray(qf.fubini_study_angle(qf.I().vec, qf.RY(theta).vec)) assert 2 * ang / abs(theta) == ALMOST_ONE ang = qf.asarray(qf.fubini_study_angle(qf.I().vec, qf.RZ(theta).vec)) assert 2 * ang / abs(theta) == ALMOST_ONE ang = qf.asarray( qf.fubini_study_angle(qf.SWAP().vec, qf.PSWAP(theta).vec)) assert 2 * ang / abs(theta) == ALMOST_ONE ang = qf.asarray(qf.fubini_study_angle(qf.I().vec, qf.PHASE(theta).vec)) assert 2 * ang / abs(theta) == ALMOST_ONE for n in range(1, 6): eye = qf.identity_gate(n) assert qf.asarray(qf.fubini_study_angle(eye.vec, eye.vec)) \ == ALMOST_ZERO with pytest.raises(ValueError): qf.fubini_study_angle(qf.random_gate(1).vec, qf.random_gate(2).vec)
def test_gates_close(): assert not qf.gates_close(qf.I(), qf.identity_gate(2)) assert qf.gates_close(qf.I(), qf.I()) assert qf.gates_close(qf.P0(), qf.P0()) assert not qf.gates_close(qf.P0(), qf.P1()) assert qf.gates_close(qf.CNOT(0, 1), qf.CNOT(0, 1)) assert not qf.gates_close(qf.CNOT(1, 0), qf.CNOT(0, 1))
def test_pseudo_hadamard(): # 1-qubit pseudo-Hadamard gates turn a cnot into a CZ gate = qf.identity_gate(2) gate = qf.TY(3 / 2, 1).H @ gate gate = qf.CNOT(0, 1) @ gate gate = qf.TY(3 / 2, 1) @ gate assert qf.gates_close(gate, qf.CZ())
def test_cnot(): # three cnots same as one swap gate = qf.identity_gate(2) gate = qf.CNOT(1, 0) @ gate gate = qf.CNOT(0, 1) @ gate gate = qf.CNOT(1, 0) @ gate res = qf.asarray(qf.inner_product(gate.vec, qf.SWAP().vec)) assert abs(res) / 4 == ALMOST_ONE
def test_XX_YY_ZZ(): gates = [qf.XX, qf.YY, qf.ZZ] for gate_class in gates: t = random.uniform(-2, +2) gate = gate_class(t) assert qf.almost_unitary(gate) inv = gate.H assert type(gate) == type(inv) assert qf.gates_close(qf.identity_gate(2), gate @ inv)
def test_CAN(): t1 = random.uniform(-2, +2) t2 = random.uniform(-2, +2) t3 = random.uniform(-2, +2) gate = qf.CAN(t1, t2, t3) assert qf.almost_unitary(gate) inv = gate.H assert type(gate) == type(inv) assert qf.gates_close(qf.identity_gate(2), inv @ gate)
def test_gate_inverse(): inv = qf.S().H eye = qf.S() @ inv assert qf.gates_close(eye, qf.I()) inv = qf.ISWAP().H eye = qf.ISWAP() @ inv assert qf.gates_close(eye, qf.identity_gate(2))
def test_inverse_parametric_2qubit(): gates = [qf.CPHASE00, qf.CPHASE01, qf.CPHASE10, qf.CPHASE, qf.PSWAP] for gate in gates: for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) g = gate(theta) inv = g.H assert qf.gates_close(qf.identity_gate(2), g @ inv) assert type(g) == type(inv)
def test_cnot_reverse(): # Hadamards reverse control on CNOT gate0 = qf.identity_gate(2) gate0 = qf.H(0) @ gate0 gate0 = qf.H(1) @ gate0 gate0 = qf.CNOT(1, 0) @ gate0 gate0 = qf.H(0) @ gate0 gate0 = qf.H(1) @ gate0 assert qf.gates_close(qf.CNOT(), gate0)
def test_EXCH(): t = random.uniform(-2, +2) gate = qf.EXCH(t) assert qf.almost_unitary(gate) inv = gate.H assert type(gate) == type(inv) assert qf.gates_close(qf.identity_gate(2), inv @ gate) gate1 = qf.CANONICAL(t, t, t) assert qf.gates_close(gate, gate1)
def test_inverse_tgates_2qubit(): gates = [qf.PISWAP] for gate in gates: for _ in range(REPS): t = random.uniform(-2, +2) g = gate(t) inv = g.H assert qf.gates_close(qf.identity_gate(2), g @ inv) assert type(g) == type(inv)
def test_piswap(): for _ in range(REPS): theta = random.uniform(-4 * pi, +4 * pi) assert qf.almost_unitary(qf.PISWAP(theta)) for _ in range(REPS): theta = random.uniform(0, +pi) assert qf.gates_close(qf.PISWAP(0), qf.identity_gate(2)) assert qf.gates_close(qf.PISWAP(pi / 4), qf.ISWAP())
def test_channel_add(): chan1 = qf.identity_gate(1).aschannel() chan1 *= 0.5 chan2 = qf.X().aschannel() chan2 *= 0.5 chan = chan1 + chan2 assert chan is not None chan3 = qf.X(3).aschannel() with pytest.raises(ValueError): chan = chan1 + chan3 with pytest.raises(NotImplementedError): chan = chan1 + 2.0 assert chan is not None
def test_partial_trace(): data = [1] * (2**16) r8 = qf.QubitVector(data, range(2)) r4 = qf.QubitVector(data, range(4)) r2 = qf.QubitVector(data, range(8)) tr2 = r2.partial_trace([1]) assert tr2.qubits == (0, 2, 3, 4, 5, 6, 7) assert tr2.rank == 2 tr2 = r2.partial_trace([2, 3]) assert tr2.qubits == (0, 1, 4, 5, 6, 7) assert tr2.rank == 2 tr4 = r4.partial_trace([0]) assert tr4.qubits == (1, 2, 3) assert tr4.rank == 4 tr8 = r8.partial_trace([1]) assert tr8.qubits == (0, ) assert tr8.rank == 8 with pytest.raises(ValueError): r2.partial_trace(range(8)) chan012 = qf.identity_gate(3).aschannel() assert np.isclose(qf.asarray(chan012.trace()), 64) # 2**(2**3) chan02 = chan012.partial_trace([1]) assert np.isclose(qf.asarray(chan02.trace()), 32) # TODO: Checkme chan2 = chan012.partial_trace([0, 1]) assert np.isclose(qf.asarray(chan2.trace()), 16) # TODO: checkme # partial traced channels should be identities still, upto normalization assert qf.channels_close(chan2, qf.I(2).aschannel()) # TODO: Channel.normalize() with pytest.raises(ValueError): qf.zero_state(4).vec.partial_trace([1, 2])
def test_repr(): g = qf.H() assert str(g) == 'H 0' g = qf.RX(3.12) assert str(g) == 'RX(3.12) 0' g = qf.identity_gate(2) assert str(g) == 'I 0 1' g = qf.random_gate(4) assert str(g) == 'RAND4 0 1 2 3' g = qf.H(0) assert str(g) == 'H 0' g = qf.CNOT(0, 1) assert str(g) == 'CNOT 0 1' g = qf.Gate(qf.CNOT().tensor) assert str(g).startswith('<quantumflow.ops.Gate')
def test_identity_gate(): N = 5 eye = qf.asarray(qf.identity_gate(N).asoperator()) assert np.allclose(eye, np.eye(2**N))
def test_gate_bits(): for n in range(1, 6): assert qf.identity_gate(n).qubit_nb == n
def test_channel_chi(): chan = qf.identity_gate(3).aschannel() chi = qf.asarray(chan.chi()) assert chi.shape == (64, 64)
def test_almost_identity(): assert not qf.almost_identity(qf.X()) assert qf.almost_identity(qf.identity_gate(4))