Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"). You 

4# may not use this file except in compliance with the License. A copy of 

5# the License is located at 

6# 

7# http://aws.amazon.com/apache2.0/ 

8# 

9# or in the "license" file accompanying this file. This file is 

10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

11# ANY KIND, either express or implied. See the License for the specific 

12# language governing permissions and limitations under the License. 

13 

14from typing import Any, Sequence, Tuple 

15 

16import numpy as np 

17from braket.circuits.operator import Operator 

18from braket.circuits.qubit_set import QubitSet 

19 

20# TODO: Add parameters support 

21# TODO: Add printing / visualization capabilities 

22 

23 

24class Gate(Operator): 

25 """ 

26 Class `Gate` represents a quantum gate that operates on N qubits. Gates are considered the 

27 building blocks of quantum circuits. This class is considered the gate definition containing 

28 the metadata that defines what a gate is and what it does. 

29 """ 

30 

31 def __init__(self, qubit_count: int, ascii_symbols: Sequence[str]): 

32 """ 

33 Args: 

34 qubit_count (int): Number of qubits this gate interacts with. 

35 ascii_symbols (Sequence[str]): ASCII string symbols for the gate. These are used when 

36 printing a diagram of circuits. Length must be the same as `qubit_count`, and 

37 index ordering is expected to correlate with target ordering on the instruction. 

38 For instance, if CNOT instruction has the control qubit on the first index and 

39 target qubit on the second index. Then ASCII symbols would have ["C", "X"] to 

40 correlate a symbol with that index. 

41 

42 Raises: 

43 ValueError: `qubit_count` is less than 1, `ascii_symbols` are None, or 

44 `ascii_symbols` length != `qubit_count` 

45 """ 

46 

47 if qubit_count < 1: 

48 raise ValueError(f"qubit_count, {qubit_count}, must be greater than zero") 

49 self._qubit_count = qubit_count 

50 

51 if ascii_symbols is None: 

52 raise ValueError(f"ascii_symbols must not be None") 

53 

54 if len(ascii_symbols) != qubit_count: 

55 msg = f"ascii_symbols, {ascii_symbols}, length must equal qubit_count, {qubit_count}" 

56 raise ValueError(msg) 

57 self._ascii_symbols = tuple(ascii_symbols) 

58 

59 @property 

60 def qubit_count(self) -> int: 

61 """int: Returns number of qubits this gate interacts with.""" 

62 return self._qubit_count 

63 

64 @property 

65 def ascii_symbols(self) -> Tuple[str]: 

66 """Tuple[str]: Returns the ascii symbols for the gate.""" 

67 return self._ascii_symbols 

68 

69 @property 

70 def name(self) -> str: 

71 """ 

72 Returns the name of the gate 

73 

74 Returns: 

75 The name of the gate as a string 

76 """ 

77 return self.__class__.__name__ 

78 

79 def to_ir(self, target: QubitSet) -> Any: 

80 """Returns IR object of gate and target 

81 

82 Args: 

83 target (QubitSet): target qubit(s) 

84 Returns: 

85 IR object of the gate and target 

86 """ 

87 raise NotImplementedError("to_ir has not been implemented yet.") 

88 

89 def to_matrix(self, *args, **kwargs) -> Any: 

90 """Returns a matrix representation of the gate 

91 

92 Returns: 

93 np.ndarray: A matrix representation of the gate 

94 """ 

95 raise NotImplementedError("to_matrix has not been implemented yet.") 

96 

97 def __eq__(self, other): 

98 if not isinstance(other, Gate): 

99 return NotImplemented 

100 if self.name == other.name: 

101 if hasattr(self, "angle"): 

102 return self.angle == other.angle 

103 return True 

104 else: 

105 return False 

106 

107 def matrix_equivalence(self, other): 

108 """ 

109 Return if the matrix form of two gates are equivalent 

110 

111 Args: 

112 other (Gate): Gate instance to compare this gate to 

113 

114 Returns: 

115 True if matrix forms of this gate and the gate compared to are equivalent 

116 """ 

117 if not isinstance(other, Gate): 

118 return NotImplemented 

119 try: 

120 return np.allclose(self.to_matrix(), other.to_matrix()) 

121 except ValueError: 

122 return False 

123 

124 def __repr__(self): 

125 if hasattr(self, "angle"): 

126 return f"{self.name}('angle': {self.angle}, 'qubit_count': {self.qubit_count})" 

127 return f"{self.name}('qubit_count': {self.qubit_count})" 

128 

129 @classmethod 

130 def register_gate(cls, gate: "Gate"): 

131 """Register a gate implementation by adding it into the Gate class. 

132 

133 Args: 

134 gate (Gate): Gate instance to register. 

135 """ 

136 setattr(cls, gate.__name__, gate)