4242 VarianceMP ,
4343)
4444from pennylane .operation import Operator
45- from pennylane .ops import Conditional , Controlled , GlobalPhase , Identity
45+ from pennylane .ops import Adjoint , Conditional , Controlled , GlobalPhase , Identity
4646from pennylane .tape import QuantumScript
47+ from pennylane .templates .subroutines import TemporaryAND
4748
4849
4950def _add_cond_grouping_symbols (op , layer_str , config ):
@@ -77,7 +78,7 @@ def _add_cond_grouping_symbols(op, layer_str, config):
7778 return layer_str
7879
7980
80- def _add_grouping_symbols (op_wires , layer_str , config ):
81+ def _add_grouping_symbols (op_wires , layer_str , config , closing = False ):
8182 """Adds symbols indicating the extent of a given sequence of wires.
8283 Does nothing if the sequence has length 0 or 1."""
8384
@@ -87,11 +88,18 @@ def _add_grouping_symbols(op_wires, layer_str, config):
8788 mapped_wires = [config .wire_map [w ] for w in op_wires ]
8889 min_w , max_w = min (mapped_wires ), max (mapped_wires )
8990
90- layer_str [min_w ] = "╭"
91- layer_str [max_w ] = "╰"
91+ if closing :
92+ layer_str [min_w ] += "╮"
93+ layer_str [max_w ] += "╯"
9294
93- for w in range (min_w + 1 , max_w ):
94- layer_str [w ] = "├" if w in mapped_wires else "│"
95+ for w in range (min_w + 1 , max_w ):
96+ layer_str [w ] += "┤" if w in mapped_wires else "│"
97+ else :
98+ layer_str [min_w ] = "╭"
99+ layer_str [max_w ] = "╰"
100+
101+ for w in range (min_w + 1 , max_w ):
102+ layer_str [w ] = "├" if w in mapped_wires else "│"
95103
96104 return layer_str
97105
@@ -159,6 +167,47 @@ def _add_controlled_global_op(obj, layer_str, config):
159167 return layer_str
160168
161169
170+ def _add_elbow_core (obj , layer_str , config ):
171+ cvals = obj .hyperparameters ["control_values" ]
172+ mapped_wires = [config .wire_map [w ] for w in obj .wires ]
173+ layer_str [mapped_wires [0 ]] += "●" if cvals [0 ] else "○"
174+ layer_str [mapped_wires [1 ]] += "●" if cvals [1 ] else "○"
175+ layer_str [mapped_wires [2 ]] += "─"
176+ return layer_str , mapped_wires
177+
178+
179+ @_add_obj .register
180+ def _add_left_elbow (
181+ obj : TemporaryAND , layer_str , config , tape_cache = None , skip_grouping_symbols = False
182+ ):
183+ """Updates ``layer_str`` with ``op`` operation of type ``TemporaryAND``,
184+ also known as left elbow."""
185+ layer_str = _add_grouping_symbols (obj .wires , layer_str , config )
186+ layer_str , _ = _add_elbow_core (obj , layer_str , config )
187+ return layer_str
188+
189+
190+ def _add_right_elbow (obj : TemporaryAND , layer_str , config ):
191+ """Updates ``layer_str`` with ``op`` operation of type ``Adjoint(TemporaryAND)``,
192+ also known as right elbow."""
193+ layer_str , mapped_wires = _add_elbow_core (obj , layer_str , config )
194+ # Fill with "─" on intermediate wires the elbow does not act on, to shift "|" correctly
195+ for w in range (min (mapped_wires ) + 1 , max (mapped_wires )):
196+ if w not in mapped_wires :
197+ layer_str [w ] += "─"
198+ return _add_grouping_symbols (obj .wires , layer_str , config , closing = True )
199+
200+
201+ @_add_obj .register
202+ def _add_adjoint (obj : Adjoint , layer_str , config , tape_cache = None , skip_grouping_symbols = False ):
203+ """Updates ``layer_str`` with ``op`` operation of type Adjoint. Currently
204+ only differs from ``_add_op`` if the base of the adjoint op is a ``TemporaryAND``,
205+ making the overall object a right elbow."""
206+ if isinstance (obj .base , TemporaryAND ):
207+ return _add_right_elbow (obj .base , layer_str , config )
208+ return _add_op (obj , layer_str , config , tape_cache , skip_grouping_symbols )
209+
210+
162211@_add_obj .register
163212def _add_op (obj : Operator , layer_str , config , tape_cache = None , skip_grouping_symbols = False ):
164213 """Updates ``layer_str`` with ``op`` operation."""
0 commit comments