def test_inverse(): # Random circuit circ = qf.Circuit() circ += qf.TY(1 / 2, 0) circ += qf.H(0) circ += qf.TY(1 / 2, 1) circ += qf.TX(1.23123, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-1 / 2, 1) circ += qf.TY(4.71572463191 / pi, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-2 * 2.74973750579 / pi, 0) circ += qf.TX(-2 * 2.74973750579 / pi, 1) circ_inv = circ.H ket = circ.run() qf.print_state(ket) ket = circ_inv.run(ket) qf.print_state(ket) print(ket.qubits) print(true_ket().qubits) assert qf.states_close(ket, qf.zero_state(2)) ket = qf.zero_state(2) circ.extend(circ_inv) ket = circ.run(ket) assert qf.states_close(ket, qf.zero_state(2))
def test_decomp_stdgates(): gate0 = qf.I(0, 1) gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.CNOT(0, 1) gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.SWAP(0, 1) gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.ISWAP(0, 1) gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.CNOT(0, 1)**0.5 gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.SWAP(0, 1)**0.5 gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1) gate0 = qf.ISWAP(0, 1)**0.5 gate1 = qf.canonical_decomposition(gate0).asgate() assert qf.gates_close(gate0, gate1)
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_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_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_gate_permute(): gate0 = qf.CNOT(0, 1) gate1 = qf.CNOT(1, 0) assert not qf.gates_close(gate0, gate1) gate2 = gate1.permute([0, 1]) assert gate2.qubits == (0, 1) assert qf.gates_close(gate1, gate2)
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_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_chan_permute(): chan0 = qf.CNOT(0, 1).aschannel() chan1 = qf.CNOT(1, 0).aschannel() assert not qf.channels_close(chan0, chan1) chan2 = chan1.permute([0, 1]) assert chan2.qubits == (0, 1) assert qf.channels_close(chan1, chan2) chan3 = chan1.relabel([0, 1]) assert qf.channels_close(chan0, chan3)
def _test_circ(): # Adapted from referenceQVM circ = qf.Circuit() circ += qf.TY(1 / 2, 0) circ += qf.TX(1, 0) circ += qf.TY(1 / 2, 1) circ += qf.TX(1, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-1 / 2, 1) circ += qf.TY(4.71572463191 / np.pi, 1) circ += qf.TX(1 / 2, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-2 * 2.74973750579 / np.pi, 0) circ += qf.TX(-2 * 2.74973750579 / np.pi, 1) return circ
def test_diamond_norm(): # Test cases borrowed from qutip, # https://github.com/qutip/qutip/blob/master/qutip/tests/test_metrics.py # which were in turn generated using QuantumUtils for MATLAB # (https://goo.gl/oWXhO9) RTOL = 0.01 chan0 = qf.I(0).aschannel() chan1 = qf.X(0).aschannel() dn = qf.diamond_norm(chan0, chan1) assert np.isclose(2.0, dn, rtol=RTOL) turns_dnorm = [[1.000000e-03, 3.141591e-03], [3.100000e-03, 9.738899e-03], [1.000000e-02, 3.141463e-02], [3.100000e-02, 9.735089e-02], [1.000000e-01, 3.128689e-01], [3.100000e-01, 9.358596e-01]] for turns, target in turns_dnorm: chan0 = qf.TX(0).aschannel() chan1 = qf.TX(turns).aschannel() dn = qf.diamond_norm(chan0, chan1) assert np.isclose(target, dn, rtol=RTOL) hadamard_mixtures = [[1.000000e-03, 2.000000e-03], [3.100000e-03, 6.200000e-03], [1.000000e-02, 2.000000e-02], [3.100000e-02, 6.200000e-02], [1.000000e-01, 2.000000e-01], [3.100000e-01, 6.200000e-01]] for p, target in hadamard_mixtures: # FIXME: implement __rmul__ for channels chan0 = qf.I(0).aschannel() * (1 - p) + qf.H(0).aschannel() * p chan1 = qf.I(0).aschannel() dn = qf.diamond_norm(chan0, chan1) assert np.isclose(dn, target, rtol=RTOL) chan0 = qf.TY(0.5, 0).aschannel() chan1 = qf.I(0).aschannel() dn = qf.diamond_norm(chan0, chan1) assert np.isclose(dn, np.sqrt(2), rtol=RTOL) chan0 = qf.CNOT(0, 1).aschannel() chan1 = qf.CNOT(1, 0).aschannel() qf.diamond_norm(chan0, chan1)
def test_sample(): ket = qf.zero_state(2) ket = qf.H(0).run(ket) ket = qf.CNOT(0, 1).run(ket) samples = ket.sample(10) assert samples.sum() == 10
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_components(): circ = qf.Circuit() circ += qf.H(0) circ += qf.H(1) dag = qf.DAGCircuit(circ) assert dag.component_nb() == 2 circ += qf.CNOT(0, 1) dag = qf.DAGCircuit(circ) assert dag.component_nb() == 1 circ0 = qf.ghz_circuit([0, 2, 4, 6, 8]) circ1 = qf.ghz_circuit([1, 3, 5, 7, 9]) circ = qf.Circuit() circ.extend(circ0) circ.extend(circ1) dag = qf.DAGCircuit(circ) comps = dag.components() assert dag.component_nb() == 2 circ0 = qf.qft_circuit([0, 2, 4, 6]) circ1 = qf.ghz_circuit([1, 3, 5, 7]) circ.extend(circ0) circ.extend(circ1) circ += qf.H(10) dag = qf.DAGCircuit(circ) comps = dag.components() assert dag.component_nb() == 3 assert len(comps) == 3
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_kronecker_decomp_errors(): # Wrong number of qubits with pytest.raises(ValueError): qf.kronecker_decomposition(qf.X(0)) # Not kronecker product with pytest.raises(ValueError): qf.kronecker_decomposition(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_qaoa_circuit_turns(): circ = qf.Circuit() circ += qf.TY(1 / 2, 0) circ += qf.TX(1, 0) circ += qf.TY(1 / 2, 1) circ += qf.TX(1, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-1 / 2, 1) circ += qf.TY(4.71572463191 / pi, 1) circ += qf.TX(1 / 2, 1) circ += qf.CNOT(0, 1) circ += qf.TX(-2 * 2.74973750579 / pi, 0) circ += qf.TX(-2 * 2.74973750579 / pi, 1) ket = qf.zero_state(2) ket = circ.run(ket) assert qf.states_close(ket, true_ket())
def test_print_gate(): stream = io.StringIO() qf.print_gate(qf.CNOT(), file=stream) s = stream.getvalue() ref = ("00 -> 00 : (1+0j)\n" + "01 -> 01 : (1+0j)\n" + "10 -> 11 : (1+0j)\n" + "11 -> 10 : (1+0j)\n") assert s == ref
def test_sample_bell(): rho = qf.zero_state(2).asdensity() chan = qf.H(0).aschannel() rho = chan.evolve(rho) chan = qf.CNOT(0, 1).aschannel() # TODO: chanmul rho = chan.evolve(rho) prob = qf.asarray(rho.probabilities()) assert np.allclose(prob, [[0.5, 0], [0, 0.5]])
def test_qaoa_circuit(): circ = qf.Circuit() circ += qf.RY(pi / 2, 0) circ += qf.RX(pi, 0) circ += qf.RY(pi / 2, 1) circ += qf.RX(pi, 1) circ += qf.CNOT(0, 1) circ += qf.RX(-pi / 2, 1) circ += qf.RY(4.71572463191, 1) circ += qf.RX(pi / 2, 1) circ += qf.CNOT(0, 1) circ += qf.RX(-2 * 2.74973750579, 0) circ += qf.RX(-2 * 2.74973750579, 1) ket = qf.zero_state(2) ket = circ.run(ket) assert qf.states_close(ket, true_ket())
def test_circuit_wires(): circ = qf.Circuit() circ += qf.TY(1 / 2, 0) circ += qf.TX(1, 10) circ += qf.TY(1 / 2, 1) circ += qf.TX(1, 1) circ += qf.CNOT(0, 4) bits = circ.qubits assert bits == (0, 1, 4, 10)
def test_qaoa(): ket_true = [ 0.00167784 + 1.00210180e-05 * 1j, 0.5 - 4.99997185e-01 * 1j, 0.5 - 4.99997185e-01 * 1j, 0.00167784 + 1.00210180e-05 * 1j ] rho_true = qf.State(ket_true).asdensity() rho = qf.zero_state(2).asdensity() rho = qf.RY(pi / 2, 0).aschannel().evolve(rho) rho = qf.RX(pi, 0).aschannel().evolve(rho) rho = qf.RY(pi / 2, 1).aschannel().evolve(rho) rho = qf.RX(pi, 1).aschannel().evolve(rho) rho = qf.CNOT(0, 1).aschannel().evolve(rho) rho = qf.RX(-pi / 2, 1).aschannel().evolve(rho) rho = qf.RY(4.71572463191, 1).aschannel().evolve(rho) rho = qf.RX(pi / 2, 1).aschannel().evolve(rho) rho = qf.CNOT(0, 1).aschannel().evolve(rho) rho = qf.RX(-2 * 2.74973750579, 0).aschannel().evolve(rho) rho = qf.RX(-2 * 2.74973750579, 1).aschannel().evolve(rho) assert qf.densities_close(rho, rho_true)
def test_channel_errors(): chan = qf.CNOT(0, 1).aschannel() with pytest.raises(TypeError): chan.run(qf.zero_state(2)) with pytest.raises(TypeError): chan.asgate() assert chan.aschannel() is chan with pytest.raises(NotImplementedError): chan @ 123
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_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_elements(): 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 += circ1 circ.extend(circ2) gates = list(circ.elements) assert len(gates) == 11 assert circ.size() == 11 assert gates[4].name == 'CNOT'
def test_qubit_qaoa_circuit(): # Adapted from reference QVM wf_true = np.array([ 0.00167784 + 1.00210180e-05 * 1j, 0.50000000 - 4.99997185e-01 * 1j, 0.50000000 - 4.99997185e-01 * 1j, 0.00167784 + 1.00210180e-05 * 1j ]) ket_true = qf.State(wf_true.reshape((2, 2))) ket = qf.zero_state(2) ket = qf.RY(pi / 2, 0).run(ket) ket = qf.RX(pi, 0).run(ket) ket = qf.RY(pi / 2, 1).run(ket) ket = qf.RX(pi, 1).run(ket) ket = qf.CNOT(0, 1).run(ket) ket = qf.RX(-pi / 2, 1).run(ket) ket = qf.RY(4.71572463191, 1).run(ket) ket = qf.RX(pi / 2, 1).run(ket) ket = qf.CNOT(0, 1).run(ket) ket = qf.RX(-2 * 2.74973750579, 0).run(ket) ket = qf.RX(-2 * 2.74973750579, 1).run(ket) assert qf.states_close(ket, ket_true)
def test_measure(): ket = qf.zero_state(2) res = ket.measure() assert np.allclose(res, [0, 0]) ket = qf.X(0).run(ket) res = ket.measure() assert np.allclose(res, [1, 0]) ket = qf.H(0).run(ket) ket = qf.CNOT(0, 1).run(ket) for _ in range(REPS): res = ket.measure() assert res[0] == res[1] # Both qubits measured in same state
def test_qaoa_circuit(): circ = qf.Circuit() circ += qf.RY(pi/2, 0) circ += qf.RX(pi, 0) circ += qf.RY(pi/2, 1) circ += qf.RX(pi, 1) circ += qf.CNOT(0, 1) circ += qf.RX(-pi/2, 1) circ += qf.RY(4.71572463191, 1) circ += qf.RX(pi/2, 1) circ += qf.CNOT(0, 1) circ += qf.RX(-2*2.74973750579, 0) circ += qf.RX(-2*2.74973750579, 1) ket = qf.zero_state(2) ket = circ.run(ket) prog = qf.forest.circuit_to_pyquil(circ) qvm = qf.forest.QuantumFlowQVM() wf = qvm.load(prog).run().wait().wavefunction() state = qf.forest.wavefunction_to_state(wf) assert qf.states_close(ket, state)