def test_unitary_exceptions() -> None: tensor = qf.CNot(1, 0).tensor with pytest.raises(ValueError): qf.Unitary(tensor, [0]) with pytest.raises(ValueError): qf.Unitary(tensor, [0, 1, 2])
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_evolve(gatet: Type[qf.StdGate]) -> None: gate0 = _randomize_gate(gatet) gate1 = qf.Unitary(gate0.tensor, gate0.qubits) rho = qf.random_density(gate0.qubits) rho0 = gate0.evolve(rho) rho1 = gate1.evolve(rho) assert qf.densities_close(rho0, rho1)
def test_gate_run(gatet: Type[qf.StdGate]) -> None: gate0 = _randomize_gate(gatet) gate1 = qf.Unitary(gate0.tensor, gate0.qubits) ket = qf.random_state(gate0.qubits) ket0 = gate0.run(ket) ket1 = gate1.run(ket) assert qf.states_close(ket0, ket1)
def test_circuit_to_qutip() -> None: q0, q1, q2 = 0, 1, 2 circ0 = qf.Circuit() circ0 += qf.I(q0) circ0 += qf.Ph(0.1, q0) circ0 += qf.X(q0) circ0 += qf.Y(q1) 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.CNot(q0, q1) circ0 += qf.CNot(q1, q0) circ0 += qf.Swap(q0, q1) circ0 += qf.ISwap(q0, q1) circ0 += qf.CCNot(q0, q1, q2) circ0 += qf.CSwap(q0, q1, q2) circ0 == qf.I(q0) circ0 += qf.Rx(0.1, q0) circ0 += qf.Ry(0.2, q1) circ0 += qf.Rz(0.3, q2) circ0 += qf.V(q0) circ0 += qf.H(q1) circ0 += qf.CY(q0, q1) circ0 += qf.CZ(q0, q1) circ0 += qf.CS(q1, q2) circ0 += qf.CT(q0, q1) circ0 += qf.SqrtSwap(q0, q1) circ0 += qf.SqrtISwap(q0, q1) circ0 += qf.CCNot(q0, q1, q2) circ0 += qf.CSwap(q0, q1, q2) circ0 += qf.CPhase(0.1, q1, q2) # Not yet supported # circ0 += qf.B(q1, q2) # circ0 += qf.Swap(q1, q2) ** 0.1 qbc = xqutip.circuit_to_qutip(circ0) U = gate_sequence_product(qbc.propagators()) gate0 = qf.Unitary(U.full(), qubits=[0, 1, 2]) assert qf.gates_close(gate0, circ0.asgate()) circ1 = xqutip.qutip_to_circuit(qbc) assert qf.gates_close(circ0.asgate(), circ1.asgate())
def test_PauliGate_pow() -> None: alpha = 0.4 gate0 = qf.PauliGate(qf.sZ(0), alpha) gate1 = gate0 ** 0.3 gate2 = qf.Unitary(gate0.tensor, gate0.qubits) ** 0.3 assert qf.gates_close(gate1, gate2) assert qf.gates_close(gate1.H, gate2 ** -1) gate3 = qf.unitary_from_hamiltonian(gate0.hamiltonian, qubits=gate0.qubits) assert qf.gates_close(gate0, gate3) s = str(gate0) print(s)
def test_translate_to_qutip() -> None: circ0 = qf.Circuit() circ0 += qf.Can(0.1, 0.2, 0.3, 0, 1) qbc = xqutip.circuit_to_qutip(circ0, translate=True) U = gate_sequence_product(qbc.propagators()) gate0 = qf.Unitary(U.full(), qubits=[0, 1]) assert qf.gates_close(gate0, circ0.asgate()) with pytest.raises(ValueError): xqutip.circuit_to_qutip(circ0, translate=False) circ1 = qf.Circuit() circ1 += qf.Can(0.1, 0.2, 0.3, "a", "b") with pytest.raises(ValueError): xqutip.circuit_to_qutip(circ1, translate=True)
def test_transpose_map() -> None: # The transpose map is a superoperator that transposes a 1-qubit # density matrix. Not physical. # quant-ph/0202124 q0 = 0 ops = [ qf.Unitary(np.asarray([[1, 0], [0, 0]]), [q0]), qf.Unitary(np.asarray([[0, 0], [0, 1]]), [q0]), qf.Unitary(np.asarray([[0, 1], [1, 0]]) / np.sqrt(2), [q0]), qf.Unitary(np.asarray([[0, 1], [-1, 0]]) / np.sqrt(2), [q0]), ] kraus = qf.Kraus(ops, weights=(1, 1, 1, -1)) rho0 = qf.random_density(1) rho1 = kraus.evolve(rho0) op0 = rho0.asoperator() op1 = rho1.asoperator() assert np.allclose(op0.T, op1) # The Choi matrix should be same as Swap operator choi = kraus.aschannel().choi() assert np.allclose(choi, qf.Swap(0, 2).asoperator())
def test_kronecker_decomposition() -> None: for _ in range(REPS): left = qf.RandomGate([1]).asoperator() right = qf.RandomGate([1]).asoperator() both = np.kron(left, right) gate0 = qf.Unitary(both, [0, 1]) circ = qf.kronecker_decomposition(gate0) gate1 = circ.asgate() assert qf.gates_close(gate0, gate1) circ2 = qf.Circuit() circ2 += qf.Z(0) circ2 += qf.H(1) gate2 = circ2.asgate() circ3 = qf.kronecker_decomposition(gate2) gate3 = circ3.asgate() assert qf.gates_close(gate2, gate3) circ4 = qf.kronecker_decomposition(gate0, euler="XYX") gate4 = circ4.asgate() assert qf.gates_close(gate0, gate4)
def test_PauliGate_more() -> None: alphas = [0.1, 2.0, -3.14, -0.4] paulis = [ qf.sZ(0) + 1, qf.sY(0), qf.sX(0), 0.5 * np.pi * qf.sZ(0) * qf.sZ(1), 0.5 * np.pi * qf.sX(0) * qf.sZ(1), ] for alpha in alphas: for pauli in paulis: circ = qf.PauliGate(pauli, alpha) qbs = circ.qubits str(pauli) op = pauli.asoperator(qbs) U = scipy.linalg.expm(-1.0j * alpha * op) gate = qf.Unitary(U, qbs) assert qf.gates_close(gate, circ.asgate()) pauli = qf.sX(0) + qf.sZ(0) with pytest.raises(ValueError): qf.Circuit(qf.PauliGate(pauli, 0.2).decompose())
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))