Coverage for src/braket/circuits/gate.py : 100%

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.
14from typing import Any, Sequence, Tuple
16import numpy as np
17from braket.circuits.operator import Operator
18from braket.circuits.qubit_set import QubitSet
20# TODO: Add parameters support
21# TODO: Add printing / visualization capabilities
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 """
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.
42 Raises:
43 ValueError: `qubit_count` is less than 1, `ascii_symbols` are None, or
44 `ascii_symbols` length != `qubit_count`
45 """
47 if qubit_count < 1:
48 raise ValueError(f"qubit_count, {qubit_count}, must be greater than zero")
49 self._qubit_count = qubit_count
51 if ascii_symbols is None:
52 raise ValueError(f"ascii_symbols must not be None")
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)
59 @property
60 def qubit_count(self) -> int:
61 """int: Returns number of qubits this gate interacts with."""
62 return self._qubit_count
64 @property
65 def ascii_symbols(self) -> Tuple[str]:
66 """Tuple[str]: Returns the ascii symbols for the gate."""
67 return self._ascii_symbols
69 @property
70 def name(self) -> str:
71 """
72 Returns the name of the gate
74 Returns:
75 The name of the gate as a string
76 """
77 return self.__class__.__name__
79 def to_ir(self, target: QubitSet) -> Any:
80 """Returns IR object of gate and target
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.")
89 def to_matrix(self, *args, **kwargs) -> Any:
90 """Returns a matrix representation of the gate
92 Returns:
93 np.ndarray: A matrix representation of the gate
94 """
95 raise NotImplementedError("to_matrix has not been implemented yet.")
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
107 def matrix_equivalence(self, other):
108 """
109 Return if the matrix form of two gates are equivalent
111 Args:
112 other (Gate): Gate instance to compare this gate to
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
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})"
129 @classmethod
130 def register_gate(cls, gate: "Gate"):
131 """Register a gate implementation by adding it into the Gate class.
133 Args:
134 gate (Gate): Gate instance to register.
135 """
136 setattr(cls, gate.__name__, gate)