def test_create_untimed_model(): basis = (bases.general(2), ) class SampleModel(Model): dim = 2 @Model.gate() def rotate_y(self, qubit): return (ParametrizedOperation(lib.rotate_y, basis), ) @Model.gate() def cphase(self, qubit_static, qubit_fluxed): return (lib.cphase(pi).at(qubit_static, qubit_fluxed), ) sample_setup = Setup(""" setup: [] """) m = SampleModel(sample_setup) cnot = m.rotate_y('D0', angle=0.5*pi) + m.cphase('D0', 'D1') + \ m.rotate_y('D0', angle=-0.5*pi) assert cnot.finalize().operation.ptm(basis * 2, basis * 2) == approx( Operation.from_sequence( lib.rotate_y(0.5 * pi).at(0), lib.cphase(pi).at(0, 1), lib.rotate_y(-0.5 * pi).at(0), ).ptm(basis * 2, basis * 2))
def test_create_timed_model(): basis = (bases.general(2), ) class SampleModel(Model): dim = 2 @Model.gate(duration=20) def rotate_y(self, qubit): return ( self.wait(qubit, 10), ParametrizedOperation(lib.rotate_y, basis), self.wait(qubit, 10), ) @Model.gate(duration='t_twoqubit') def cphase(self, qubit_static, qubit_fluxed): return ( self.wait(qubit_static, 0.5 * self.p('t_twoqubit')), self.wait(qubit_fluxed, 0.5 * self.p('t_twoqubit')), lib.cphase(pi).at(qubit_static, qubit_fluxed), self.wait(qubit_static, 0.5 * self.p('t_twoqubit')), self.wait(qubit_fluxed, 0.5 * self.p('t_twoqubit')), ) @Model.gate(duration=lambda qubit, setup: 600 if qubit == 'D0' else 400) def strange_duration_gate(self, qubit): return lib.rotate_y(pi) @staticmethod def _filter_wait_placeholders(operation): return Operation.from_sequence([ unit for unit in operation.units() if not isinstance(unit.operation, WaitPlaceholder) ]) def finalize(self, circuit, bases_in=None): return circuit.finalize([self._filter_wait_placeholders], bases_in) sample_setup = Setup(""" setup: - t_twoqubit: 40 """) m = SampleModel(sample_setup) cnot = m.rotate_y('D0', angle=0.5*pi) + m.cphase('D0', 'D1') + \ m.rotate_y('D0', angle=-0.5*pi) cnot = m.finalize(cnot) assert cnot.operation.ptm(basis * 2, basis * 2) == approx( Operation.from_sequence( lib.rotate_y(0.5 * pi).at(0), lib.cphase(pi).at(0, 1), lib.rotate_y(-0.5 * pi).at(0), ).ptm(basis * 2, basis * 2)) gate1 = m.strange_duration_gate('D0') assert gate1.duration == 600 gate2 = m.strange_duration_gate('D1') assert gate2.duration == 400
def test_circuits_add(self): dim = 2 orplus = lib.rotate_y(0.5 * pi) ocphase = lib.cphase(pi) orminus = lib.rotate_y(-0.5 * pi) grplus = Gate('Q0', dim, orplus) gcphase = Gate(('Q0', 'Q1'), dim, ocphase) grminus = Gate('Q0', dim, orminus) basis = (bases.general(2), ) * 2 circuit = grplus + gcphase assert circuit.qubits == ['Q0', 'Q1'] assert len(circuit.gates) == 2 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(0, 1)).ptm(basis, basis)) circuit = circuit + grminus assert circuit.qubits == ['Q0', 'Q1'] assert len(circuit.gates) == 3 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(0, 1), orminus.at(0)).ptm(basis, basis)) circuit = grplus + (gcphase + grminus) assert circuit.qubits == ['Q0', 'Q1'] assert len(circuit.gates) == 3 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(0, 1), orminus.at(0)).ptm(basis, basis)) grplus = Gate('Q1', dim, orplus) grminus = Gate('Q1', dim, orminus) circuit = grplus + gcphase + grminus assert circuit.qubits == ['Q1', 'Q0'] assert len(circuit.gates) == 3 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(0, 1), orminus.at(0)).ptm(basis, basis)) basis = (basis[0], ) * 3 grplus = Gate('Q2', dim, orplus) grminus = Gate('Q0', dim, orminus) circuit = grplus + gcphase + grminus assert circuit.qubits == ['Q2', 'Q0', 'Q1'] assert len(circuit.gates) == 3 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(1, 2), orminus.at(1)).ptm(basis, basis)) grplus = Gate('Q0', dim, orplus) grminus = Gate('Q2', dim, orminus) circuit = grplus + gcphase + grminus assert circuit.qubits == ['Q0', 'Q1', 'Q2'] assert len(circuit.gates) == 3 assert c_op(circuit).ptm(basis, basis) == approx( Operation.from_sequence(orplus.at(0), ocphase.at(0, 1), orminus.at(2)).ptm(basis, basis))
def test_opt_basis_single_qubit_2d(self): b = bases.general(2) b0 = b.subbasis([0]) b1 = b.subbasis([1]) b01 = b.computational_subbasis() # Identity up to floating point error rot = lib2.rotate_x(2 * np.pi).compile(bases_in=(b0, )) assert rot.bases_in == (b0, ) assert rot.bases_out == (b0, ) rot = lib2.rotate_x(2 * np.pi).compile(bases_in=(b1, )) assert rot.bases_in == (b1, ) assert rot.bases_out == (b1, ) # RX(pi) rot = lib2.rotate_x(np.pi).compile(bases_in=(b0, )) assert rot.bases_in == (b0, ) assert rot.bases_out == (b1, ) rot = lib2.rotate_x(np.pi).compile(bases_in=(b1, )) assert rot.bases_in == (b1, ) assert rot.bases_out == (b0, ) # RY(pi/2) rot = lib2.rotate_y(np.pi / 2).compile(bases_in=(b01, )) assert rot.bases_in[0] == b01 assert rot.bases_out[0].dim_pauli == 3 assert '0' in rot.bases_out[0].labels assert '1' in rot.bases_out[0].labels assert 'X10' in rot.bases_out[0].labels
def test_gate_create(self): dim = 2 gate = Gate('Q0', dim, lib.rotate_y(0.5 * pi), 20.) assert gate.time_start == 0 assert gate.time_end == 20. assert gate.duration == 20. gate = Gate(['Q0', 'Q1'], dim, lib.cphase(0.5 * pi), 40., 125.) assert gate.time_start == 125. assert gate.time_end == approx(165.) assert gate.duration == 40. gate.time_end = 90. assert gate.time_start == approx(50.) assert gate.time_end == 90. assert gate.duration == 40. gate1 = gate.shift(time_start=0.) assert gate.time_start == approx(50.) assert gate.time_end == 90. assert gate.duration == 40. assert gate1.time_start == 0. assert gate1.time_end == 40. assert gate1.duration == 40. gate1 = gate.shift(time_end=123.) assert gate.time_start == approx(50.) assert gate.time_end == 90. assert gate.duration == 40. assert gate1.time_start == approx(83.) assert gate1.time_end == 123. assert gate1.duration == 40.
def test_time_aware_add_gate_no_init_time(self): dim = 2 orplus = lib.rotate_y(0.5 * pi) ocphase = lib.cphase(pi) orminus = lib.rotate_y(-0.5 * pi) gate_q0 = Gate('Q0', dim, orplus, 20.) gate_2q = Gate(['Q0', 'Q1'], dim, ocphase, 40.) gate_q1 = Gate('Q1', dim, orminus, 30.) circuit = gate_q0 + gate_2q assert circuit.time_start == 0. assert circuit.time_end == approx(60.) assert circuit.duration == approx(60.) assert [gate.time_start for gate in circuit.gates] == approx([0., 20.]) circuit = circuit + gate_q1 assert circuit.time_start == 0. assert circuit.time_end == approx(90.) assert circuit.duration == approx(90.) assert [gate.time_start for gate in circuit.gates] == \ approx([0., 20., 60.]) circuit = circuit + gate_q0 assert circuit.time_start == 0. assert circuit.time_end == approx(90.) assert circuit.duration == approx(90.) assert [gate.time_start for gate in circuit.gates] == \ approx([0., 20., 60., 60.]) circuit = gate_q1 + circuit assert circuit.time_start == 0. assert circuit.time_end == approx(100.) assert circuit.duration == approx(100.) assert [gate.time_start for gate in circuit.gates] == \ approx([0., 10., 30., 70., 70.]) circuit = circuit + (gate_q0 + gate_q1) assert circuit.time_start == 0. assert circuit.time_end == approx(130.) assert circuit.duration == approx(130.) assert [gate.time_start for gate in circuit.gates] == \ approx([0., 10., 30., 70., 70., 100., 100.])
def test_chain_create(self): op1 = lib2.rotate_x() op2 = lib2.rotate_y() op3 = lib2.cnot() op_qutrit = lib3.rotate_x() circuit = Operation.from_sequence(op1.at(0), op2.at(0)) assert circuit.num_qubits == 1 assert len(circuit._units) == 2 circuit = Operation.from_sequence(op1.at(1), op2.at(0)) assert circuit.num_qubits == 2 assert len(circuit._units) == 2 with pytest.raises(ValueError, match=".* must form an ordered set .*"): Operation.from_sequence(op1.at(2), op2.at(0)) with pytest.raises(ValueError, match=".* must form an ordered set .*"): Operation.from_sequence(op1.at(1), op2.at(2)) with pytest.raises(ValueError, match="Hilbert dimensionality of op.*"): Operation.from_sequence(op1.at(0), op_qutrit.at(0)) circuit3q = Operation.from_sequence(op1.at(0), op2.at(1), op3.at(0, 1), op1.at(1), op2.at(0), op3.at(0, 2)) assert circuit3q.num_qubits == 3 assert len(circuit3q._units) == 6 with pytest.raises(ValueError, match="Number of indices is not .*"): Operation.from_sequence(op1.at(0), op3.at(0)) with pytest.raises(ValueError, match="Number of indices is not .*"): circuit3q.at(0, 1) circuit4q = Operation.from_sequence(op3.at(0, 2), circuit3q.at(1, 2, 3)) assert len(circuit4q._units) == 7 assert circuit4q._units[0].indices == (0, 2) for o1, o2 in zip(circuit4q._units[1:], circuit3q._units): assert np.all(np.array(o1.indices) == np.array(o2.indices) + 1) circuit4q = Operation.from_sequence(circuit3q.at(2, 0, 3), op3.at(0, 1), op2.at(1)) assert len(circuit4q._units) == 8 assert circuit4q._units[0].indices == (2, ) assert circuit4q._units[1].indices == (0, ) assert circuit4q._units[2].indices == (2, 0) Operation.from_sequence(circuit3q.at(0, 1, 2), Operation.from_sequence(op1, op2).at(1))
def test_compile_single_qubit_2d(self): b = bases.general(2) b0 = b.subbasis([0]) b01 = b.computational_subbasis() op = lib2.rotate_y(np.pi) assert op.shape == (4, 4) op_full = op.compile(bases_in=(b, )) assert op_full.shape == (4, 4) op_cl = op.compile(bases_in=(b01, )) assert op_cl.shape == (2, 2) op = lib2.rotate_x(np.pi / 3) assert op.shape == (4, 4) op_full = op.compile(bases_in=(b, ), bases_out=(b01, )) # X component of a state is irrelevant for the output. assert op_full.shape == (2, 3) op_cl = op.compile(bases_in=(b0, )) assert op_cl.shape == (3, 1)
def test_chain_apply(self): b = (bases.general(2), ) * 3 dm = random_hermitian_matrix(8, seed=93) pv1 = PauliVector.from_dm(dm, b) pv2 = PauliVector.from_dm(dm, b) # Some random gate sequence op_indices = [(lib2.rotate_x(np.pi / 2), (0, )), (lib2.rotate_y(0.3333), (1, )), (lib2.cphase(), (0, 2)), (lib2.cphase(), (1, 2)), (lib2.rotate_x(-np.pi / 2), (0, ))] for op, indices in op_indices: op(pv1, *indices), circuit = Operation.from_sequence(*(op.at(*ix) for op, ix in op_indices)) circuit(pv2, 0, 1, 2) assert np.all(pv1.to_pv() == pv2.to_pv())
def test_ptm(self): # Some random gate sequence op_indices = [(lib2.rotate_x(np.pi / 2), (0, )), (lib2.rotate_y(0.3333), (1, )), (lib2.cphase(), (0, 2)), (lib2.cphase(), (1, 2)), (lib2.rotate_x(-np.pi / 2), (0, ))] circuit = Operation.from_sequence(*(op.at(*ix) for op, ix in op_indices)) b = (bases.general(2), ) * 3 ptm = circuit.ptm(b, b) assert isinstance(ptm, np.ndarray) op_3q = Operation.from_ptm(ptm, b) dm = random_hermitian_matrix(8, seed=93) state1 = PauliVector.from_dm(dm, b) state2 = PauliVector.from_dm(dm, b) circuit(state1, 0, 1, 2) op_3q(state2, 0, 1, 2) assert np.allclose(state1.to_pv(), state2.to_pv())
def strange_duration_gate(self, qubit): return lib.rotate_y(pi)
def cnot_like(angle_cphase, angle_rotate): return Operation.from_sequence( lib.rotate_y(angle_rotate).at(1), lib.cphase(angle_cphase).at(0, 1), lib.rotate_y(-angle_rotate).at(1))