def test_two_qubits(self) -> None: sigmax = np.array([[0, 1], [1, 0]]) sigmay = np.array([[0, -1j], [1j, 0]]) xx = np.kron(sigmax, sigmax) y1 = np.kron(sigmay, np.identity(qubit_dimension)) y2 = np.kron(np.identity(qubit_dimension), sigmay) terms = [ HamiltonianTerm(2 * xx), HamiltonianTerm(1.5 * y1), HamiltonianTerm(1.1 * y2)] h = Hamiltonian(terms) u = h.get_time_evolution_operator(0) assert isinstance(u, Unitary) assert u.get_dimension() == h.get_dimension() assert u.close_to(Unitary.identity(h.get_dimension())) time = 1.234 u = h.get_time_evolution_operator(time) num_trotter_steps = 20 randomized_trotter_sequence = h.get_trotter_sequence( time, num_trotter_steps, randomize=True) assert isinstance(randomized_trotter_sequence, UnitarySequence) num_repetitions = 1000 qdrift_sequence = h.get_qdrift_sequence(time, num_repetitions) assert isinstance(qdrift_sequence, UnitarySequence) assert qdrift_sequence.get_length() == num_repetitions # should be close assert u.close_to(randomized_trotter_sequence.product(), 0.95), \ u.distance_from(randomized_trotter_sequence.product()) assert u.close_to(qdrift_sequence.product(), 0.95), \ u.distance_from(qdrift_sequence.product()) # but should not be exactly the same assert not u.close_to(randomized_trotter_sequence.product()) assert not u.close_to(qdrift_sequence.product()) assert not randomized_trotter_sequence.product().close_to( qdrift_sequence.product())
def test_inverse_fixed(self) -> None: dimension = 2 operation_name = 'U' unitary = Unitary(dimension, np.array([[np.exp(1j * np.pi / 4), 0], [0, 1j]]), operation_name) inverse = unitary.inverse() assert unitary.left_multiply(inverse).close_to(np.identity(dimension)) assert unitary.right_multiply(inverse).close_to(np.identity(dimension)) assert inverse.get_display_name() == 'U†' double_inverse = inverse.inverse() assert double_inverse.get_display_name() == 'U' assert unitary.close_to(double_inverse)
def test_undo(self) -> None: dimension = 2 identity = Unitary.identity(dimension) sequence = UnitarySequence(dimension) assert sequence.get_length() == 0 with pytest.raises(Exception): sequence.undo() sequence.append_first( UnitarySequenceEntry(UnitaryDefinitions.sigmax(), [0])) assert sequence.get_length() == 1 assert sequence.product().close_to(UnitaryDefinitions.sigmax()) sequence.undo() assert sequence.get_length() == 0 assert sequence.product().close_to(identity) with pytest.raises(Exception): sequence.undo() sequence.append_first( UnitarySequenceEntry(UnitaryDefinitions.sigmay(), [0])) sequence.append_first( UnitarySequenceEntry(UnitaryDefinitions.sigmay(), [0])) assert sequence.get_length() == 2 assert sequence.product().close_to(identity) sequence.remove_last() assert sequence.get_length() == 1 assert sequence.product().close_to(UnitaryDefinitions.sigmay()) sequence.undo() assert sequence.get_length() == 2 assert sequence.product().close_to(identity) with pytest.raises(Exception): sequence.undo()
def __init__( self, unitary: Unitary, allowed_apply_to: Optional[List[List[int]]] = None ): ''' Creates a UnitaryPrimitive object. ''' if allowed_apply_to is not None: allowed_apply_to = list(allowed_apply_to) assert np.all([ len(apply_to) == len(set(apply_to)) for apply_to in allowed_apply_to]) assert np.all([ 2**len(apply_to) == unitary.get_dimension() for apply_to in allowed_apply_to]) assert np.all([ np.min(apply_to) >= 0 for apply_to in allowed_apply_to]) self.unitary = unitary self.allowed_apply_to = allowed_apply_to
def test_mismatched_dimension(self) -> None: dimension = 4 with pytest.raises(Exception): Unitary(dimension, np.identity(dimension - 1))
def test_non_unitary_matrix(self) -> None: dimension = 2 with pytest.raises(Exception): Unitary(dimension, np.array([[1, 0], [1, 1]]))
def test_non_square_matrix(self) -> None: dimension = 2 with pytest.raises(Exception): Unitary(dimension, np.array([[1, 0, 0], [0, 1, 0]]))
def test_gms(self) -> None: for num_qubits in [3, 4, 5]: u = UnitaryDefinitions.gms(num_qubits) assert ( u.left_multiply(u).left_multiply(u).left_multiply(u).close_to( Unitary.identity(u.get_dimension())))
def test_default(self) -> None: dimension = 4 unitary = Unitary(dimension) assert unitary.get_dimension() == dimension assert unitary.close_to(np.identity(dimension))
def test_display_name(self) -> None: dimension = 2 operation_name = "Rx" unitary = Unitary(dimension, np.array([[np.exp(1j * np.pi / 4), 0], [0, 1j]]), operation_name) display_name_with_zero_parameters = unitary.get_display_name() assert isinstance(display_name_with_zero_parameters, str) assert operation_name == display_name_with_zero_parameters parameter_name_1 = "abc" unitary = Unitary(dimension, unitary.get_matrix(), operation_name, {parameter_name_1: (1.0, True)}) display_name_with_one_parameter = unitary.get_display_name() assert isinstance(display_name_with_one_parameter, str) assert operation_name in display_name_with_one_parameter parameter_name_2 = "def" unitary = Unitary(dimension, unitary.get_matrix(), operation_name, { parameter_name_1: (1.0, True), parameter_name_2: (2.0, False) }) display_name_with_two_parameters = unitary.get_display_name() print(display_name_with_two_parameters) assert isinstance(display_name_with_two_parameters, str) assert operation_name in display_name_with_two_parameters assert parameter_name_1 in display_name_with_two_parameters assert parameter_name_2 in display_name_with_two_parameters