def test_stdgates(gatet: Type[qf.StdGate]) -> None: # Test creation gate = _randomize_gate(gatet) # Test correct number of qubits assert gate.qubit_nb == gatet.cv_qubit_nb # Test hermitian conjugate inv_gate = gate.H gate.tensor inv_gate.tensor # Test inverse eye = gate @ inv_gate assert qf.gates_close(qf.IdentityGate(range(gate.qubit_nb)), eye) assert qf.gates_phase_close(qf.IdentityGate(range(gate.qubit_nb)), eye) # Test pow assert qf.gates_close(gate ** -1, inv_gate) assert qf.gates_close((gate ** 0.5) ** 2, gate) assert qf.gates_close((gate ** 0.3) @ (gate ** 0.7), gate) hgate = qf.Unitary((gate ** 0.5).tensor, gate.qubits) assert qf.gates_close(hgate @ hgate, gate)
def test_gate_mul() -> None: # three cnots same as one swap gate0 = qf.IdentityGate([0, 1]) gate1 = qf.CNot(1, 0) gate2 = qf.CNot(0, 1) gate3 = qf.CNot(1, 0) gate = gate1 @ gate0 gate = gate2 @ gate gate = gate3 @ gate assert qf.gates_close(gate, qf.Swap(0, 1)) # Again, but with labels gate0 = qf.IdentityGate(["a", "b"]) gate1 = qf.CNot("b", "a") gate2 = qf.CNot("a", "b") gate3 = qf.CNot("b", "a") gate = gate1 @ gate0 gate = gate2 @ gate gate = gate3 @ gate assert qf.gates_close(gate, qf.Swap("a", "b")) gate4 = qf.X("a") _ = gate4 @ gate with pytest.raises(NotImplementedError): _ = gate4 @ 3 # type: ignore
def test_identitygate() -> None: qubits = [3, 4, 5, 6, 7, 8] gate = qf.IdentityGate(qubits) ket0 = qf.random_state(qubits) ket1 = gate.run(ket0) assert qf.states_close(ket0, ket1) circ = qf.Circuit(gate.decompose()) assert len(circ) == 6 for n in range(1, 6): assert qf.IdentityGate(list(range(n))).qubit_nb == n assert gate.hamiltonian.is_zero() assert gate ** 2 is gate
def test_identity() -> None: chan = qf.IdentityGate([1]).aschannel() rho = qf.random_density(2) after = chan.evolve(rho) assert qf.densities_close(rho, after) assert chan.name == "Channel"
def test_fubini_study_angle() -> None: for _ in range(REPS): theta = random.uniform(-np.pi, +np.pi) ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Rx(theta, 0).su().tensor) assert np.isclose(2 * ang / abs(theta), 1.0) ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Ry(theta, 0).tensor) assert np.isclose(2 * ang / abs(theta), 1.0) ang = qf.fubini_study_angle(qf.I(0).tensor, qf.Rz(theta, 0).tensor) assert np.isclose(2 * ang / abs(theta), 1.0) ang = qf.fubini_study_angle(qf.Swap(0, 1).tensor, qf.PSwap(theta, 0, 1).tensor) assert np.isclose(2 * ang / abs(theta), 1.0) ang = qf.fubini_study_angle(qf.I(0).tensor, qf.PhaseShift(theta, 0).tensor) assert np.isclose(2 * ang / abs(theta), 1.0) assert qf.fubini_study_close(qf.Rz(theta, 0).tensor, qf.Rz(theta, 0).tensor) for n in range(1, 6): eye = qf.IdentityGate(list(range(n))) assert np.isclose(qf.fubini_study_angle(eye.tensor, eye.tensor), 0.0) with pytest.raises(ValueError): qf.fubini_study_angle(qf.RandomGate([1]).tensor, qf.RandomGate([0, 1]).tensor)
def test_decomp_stdgates() -> None: gate0 = qf.IdentityGate([0, 1]) gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate2 = qf.CNot(0, 1) gate3 = qf.canonical_decomposition(gate2).asgate() assert qf.gates_close(gate2, gate3) gate4 = qf.Swap(0, 1) gate5 = qf.canonical_decomposition(gate4).asgate() assert qf.gates_close(gate4, gate5) gate6 = qf.ISwap(0, 1) gate7 = qf.canonical_decomposition(gate6).asgate() assert qf.gates_close(gate6, gate7) gate8 = qf.CNot(0, 1)**0.5 gate9 = qf.canonical_decomposition(gate8).asgate() assert qf.gates_close(gate8, gate9) gate10 = qf.Swap(0, 1)**0.5 gate11 = qf.canonical_decomposition(gate10).asgate() assert qf.gates_close(gate10, gate11) gate12 = qf.ISwap(0, 1)**0.5 gate13 = qf.canonical_decomposition(gate12).asgate() assert qf.gates_close(gate12, gate13)
def test_inverse_random() -> None: K = 4 for _ in range(REPS): gate = qf.RandomGate(range(K)) inv = gate.H gate1 = inv @ gate # TODO: almost_identity assert qf.gates_close(qf.IdentityGate([0, 1, 2, 3]), gate1)
def test_multiswapgate() -> None: # Should be same as a swap. perm0 = qf.MultiSwapGate([0, 1], [1, 0]) gate0 = qf.Swap(0, 1) assert qf.gates_close(perm0.asgate(), gate0) assert qf.gates_close(perm0.asgate(), perm0.H.asgate()) perm1 = qf.MultiSwapGate.from_gates(qf.Circuit([gate0])) assert qf.gates_close(perm0.asgate(), perm1.asgate()) perm2 = qf.MultiSwapGate.from_gates(qf.Circuit([perm1])) assert qf.gates_close(perm0, perm2) with pytest.raises(ValueError): qf.MultiSwapGate.from_gates(qf.Circuit(qf.CNot(0, 1))) N = 8 qubits_in = list(range(N)) qubits_out = np.random.permutation(qubits_in) permN = qf.MultiSwapGate(qubits_in, qubits_out) assert qf.gates_close(perm0.asgate(), perm1.asgate()) iden = qf.Circuit([permN, permN.H]) assert qf.almost_identity(iden.asgate()) assert qf.circuits_close(iden, qf.Circuit([qf.IdentityGate(qubits_in)])) swaps = qf.Circuit(permN.decompose()) # Add identity so we don't lose qubits swaps += qf.IdentityGate(permN.qubits_in) permN2 = qf.MultiSwapGate.from_gates(swaps) assert qf.circuits_close(swaps, qf.Circuit([permN])) assert qf.circuits_close(swaps, qf.Circuit([permN2])) assert qf.circuits_close(qf.Circuit([permN]), qf.Circuit([permN2])) with pytest.raises(ValueError): _ = qf.MultiSwapGate([0, 1], [1, 2]) # Channels assert qf.channels_close(perm0.aschannel(), gate0.aschannel()) rho0 = qf.random_state([0, 1, 3]).asdensity() rho1 = perm0.evolve(rho0) rho2 = gate0.aschannel().evolve(rho0) assert qf.densities_close(rho1, rho2)
def test_cnot_reverse() -> None: # Hadamards reverse control on CNot gate0 = qf.H(0) @ qf.IdentityGate([0, 1]) 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(0, 1), gate0)
def test_gradient_errors() -> None: circ = qf.Circuit() circ += qf.CPhase(0.2, 0, 1) # Not (currently) differentiable qubits = circ.qubits ket0 = qf.zero_state(qubits) ket1 = qf.random_state(qubits) with pytest.raises(ValueError): qf.state_fidelity_gradients(ket0, ket1, circ) with pytest.raises(ValueError): qf.parameter_shift_circuits(circ, 0) with pytest.raises(ValueError): qf.expectation_gradients(ket0, circ, qf.IdentityGate([0, 1]))
def test_CPhase_gates() -> None: for _ in range(REPS): theta = random.uniform(-4 * np.pi, +4 * np.pi) gate11 = qf.ControlGate([0], qf.PhaseShift(theta, 1)) assert qf.gates_close(gate11, qf.CPhase(theta, 0, 1)) gate00 = qf.X(0) @ qf.IdentityGate([0, 1]) 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.X(0) @ qf.IdentityGate([0, 1]) gate10 = qf.X(1) @ gate10 gate10 = qf.CPhase01(theta, 0, 1) @ gate10 gate10 = qf.X(0) @ gate10 gate10 = qf.X(1) @ gate10 assert qf.gates_close(gate10, qf.CPhase10(theta)) gate0 = qf.CPhase(theta) ** 2 gate1 = qf.CPhase(theta * 2) assert qf.gates_close(gate0, gate1)
def test_xy() -> None: assert qf.gates_close(qf.XY(0, 0, 1), qf.IdentityGate([0, 1])) assert qf.gates_close(qf.XY(-0.5, 0, 1), qf.ISwap(0, 1)) assert qf.gates_close(qf.XY(0.5, 0, 1), qf.ISwap(0, 1).H)
def test_channel_chi() -> None: chan = qf.IdentityGate([0, 1, 2]).aschannel() chi = chan.chi() assert chi.shape == (64, 64)