diff --git a/cirq-core/cirq/circuits/circuit.py b/cirq-core/cirq/circuits/circuit.py index 5a73520f020..3675e011cce 100644 --- a/cirq-core/cirq/circuits/circuit.py +++ b/cirq-core/cirq/circuits/circuit.py @@ -1505,64 +1505,6 @@ def concat_ragged( return cirq.Circuit(buffer[offset : offset + n_acc]) - @_compat.deprecated(deadline='v0.16', fix='Renaming to concat_ragged') - def tetris_concat( - *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT - ) -> 'cirq.AbstractCircuit': - """Concatenates circuits while overlapping them if possible. - - Starts with the first circuit (index 0), then iterates over the other - circuits while folding them in. To fold two circuits together, they - are placed one after the other and then moved inward until just before - their operations would collide. If any of the circuits do not share - qubits and so would not collide, the starts or ends of the circuits will - be aligned, acording to the given align parameter. - - Beware that this method is *not* associative. For example: - - >>> a, b = cirq.LineQubit.range(2) - >>> A = cirq.Circuit(cirq.H(a)) - >>> B = cirq.Circuit(cirq.H(b)) - >>> f = cirq.Circuit.tetris_concat - >>> f(f(A, B), A) == f(A, f(B, A)) - False - >>> len(f(f(f(A, B), A), B)) == len(f(f(A, f(B, A)), B)) - False - - Args: - *circuits: The circuits to concatenate. - align: When to stop when sliding the circuits together. - 'left': Stop when the starts of the circuits align. - 'right': Stop when the ends of the circuits align. - 'first': Stop the first time either the starts or the ends align. Circuits - are never overlapped more than needed to align their starts (in case - the left circuit is smaller) or to align their ends (in case the right - circuit is smaller) - - Returns: - The concatenated and overlapped circuit. - """ - if len(circuits) == 0: - return Circuit() - n_acc = len(circuits[0]) - - if isinstance(align, str): - align = Alignment[align.upper()] - - # Allocate a buffer large enough to append and prepend all the circuits. - pad_len = sum(len(c) for c in circuits) - n_acc - buffer = np.zeros(shape=pad_len * 2 + n_acc, dtype=object) - - # Put the initial circuit in the center of the buffer. - offset = pad_len - buffer[offset : offset + n_acc] = circuits[0].moments - - # Accumulate all the circuits into the buffer. - for k in range(1, len(circuits)): - offset, n_acc = _concat_ragged_helper(offset, n_acc, buffer, circuits[k].moments, align) - - return cirq.Circuit(buffer[offset : offset + n_acc]) - def get_independent_qubit_sets(self) -> List[Set['cirq.Qid']]: """Divide circuit's qubits into independent qubit sets. @@ -1909,14 +1851,6 @@ def concat_ragged( concat_ragged.__doc__ = AbstractCircuit.concat_ragged.__doc__ - @_compat.deprecated(deadline='v0.16', fix='Renaming to concat_ragged') - def tetris_concat( - *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT - ) -> 'cirq.Circuit': - return AbstractCircuit.tetris_concat(*circuits, align=align).unfreeze(copy=False) - - tetris_concat.__doc__ = AbstractCircuit.tetris_concat.__doc__ - def zip( *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT ) -> 'cirq.Circuit': diff --git a/cirq-core/cirq/circuits/circuit_test.py b/cirq-core/cirq/circuits/circuit_test.py index 7febde438fb..1dcbc6e3fa0 100644 --- a/cirq-core/cirq/circuits/circuit_test.py +++ b/cirq-core/cirq/circuits/circuit_test.py @@ -4261,213 +4261,6 @@ def _circuit_diagram_info_(self, args): assert '|c>' in circuit._repr_html_() -def test_tetris_concat_deprecated(): - a, b = cirq.LineQubit.range(2) - empty = cirq.Circuit() - - with cirq.testing.assert_deprecated('ragged', deadline='v0.16', count=None): - assert cirq.Circuit.tetris_concat(empty, empty) == empty - assert cirq.Circuit.tetris_concat() == empty - assert empty.tetris_concat(empty) == empty - assert empty.tetris_concat(empty, empty) == empty - - ha = cirq.Circuit(cirq.H(a)) - hb = cirq.Circuit(cirq.H(b)) - assert ha.tetris_concat(hb) == ha.zip(hb) - - assert ha.tetris_concat(empty) == ha - assert empty.tetris_concat(ha) == ha - - hac = cirq.Circuit(cirq.H(a), cirq.CNOT(a, b)) - assert hac.tetris_concat(hb) == hac + hb - assert hb.tetris_concat(hac) == hb.zip(hac) - - zig = cirq.Circuit(cirq.H(a), cirq.CNOT(a, b), cirq.H(b)) - assert zig.tetris_concat(zig) == cirq.Circuit( - cirq.H(a), - cirq.CNOT(a, b), - cirq.Moment(cirq.H(a), cirq.H(b)), - cirq.CNOT(a, b), - cirq.H(b), - ) - - zag = cirq.Circuit(cirq.H(a), cirq.H(a), cirq.CNOT(a, b), cirq.H(b), cirq.H(b)) - assert zag.tetris_concat(zag) == cirq.Circuit( - cirq.H(a), - cirq.H(a), - cirq.CNOT(a, b), - cirq.Moment(cirq.H(a), cirq.H(b)), - cirq.Moment(cirq.H(a), cirq.H(b)), - cirq.CNOT(a, b), - cirq.H(b), - cirq.H(b), - ) - - space = cirq.Circuit(cirq.Moment()) * 10 - f = cirq.Circuit.tetris_concat - assert len(f(space, ha)) == 10 - assert len(f(space, ha, ha, ha)) == 10 - assert len(f(space, f(ha, ha, ha))) == 10 - assert len(f(space, ha, align='LEFT')) == 10 - assert len(f(space, ha, ha, ha, align='RIGHT')) == 12 - assert len(f(space, f(ha, ha, ha, align='LEFT'))) == 10 - assert len(f(space, f(ha, ha, ha, align='RIGHT'))) == 10 - assert len(f(space, f(ha, ha, ha), align='LEFT')) == 10 - assert len(f(space, f(ha, ha, ha), align='RIGHT')) == 10 - - # L shape overlap (vary c1). - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 4), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 1), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - assert 8 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 6), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - assert 9 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 7), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - - # L shape overlap (vary c2). - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 5, cirq.CZ(a, b)), - ) - ) - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 4, cirq.CZ(a, b)), - ) - ) - assert 7 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 1, cirq.CZ(a, b)), - ) - ) - assert 8 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 6, cirq.CZ(a, b)), - ) - ) - assert 9 == len( - f( - cirq.Circuit(cirq.CZ(a, b), [cirq.H(a)] * 5), - cirq.Circuit([cirq.H(b)] * 7, cirq.CZ(a, b)), - ) - ) - - # When scanning sees a possible hit, continues scanning for earlier hit. - assert 10 == len( - f( - cirq.Circuit( - cirq.Moment(), - cirq.Moment(), - cirq.Moment(), - cirq.Moment(), - cirq.Moment(), - cirq.Moment(cirq.H(a)), - cirq.Moment(), - cirq.Moment(), - cirq.Moment(cirq.H(b)), - ), - cirq.Circuit( - cirq.Moment(), - cirq.Moment(), - cirq.Moment(), - cirq.Moment(cirq.H(a)), - cirq.Moment(), - cirq.Moment(cirq.H(b)), - ), - ) - ) - # Correct tie breaker when one operation sees two possible hits. - for cz_order in [cirq.CZ(a, b), cirq.CZ(b, a)]: - assert 3 == len( - f( - cirq.Circuit(cirq.Moment(cz_order), cirq.Moment(), cirq.Moment()), - cirq.Circuit(cirq.Moment(cirq.H(a)), cirq.Moment(cirq.H(b))), - ) - ) - - # Types. - v = ha.freeze().tetris_concat(empty) - assert type(v) is cirq.FrozenCircuit and v == ha.freeze() - v = ha.tetris_concat(empty.freeze()) - assert type(v) is cirq.Circuit and v == ha - v = ha.freeze().tetris_concat(empty) - assert type(v) is cirq.FrozenCircuit and v == ha.freeze() - v = cirq.Circuit.tetris_concat(ha, empty) - assert type(v) is cirq.Circuit and v == ha - v = cirq.FrozenCircuit.tetris_concat(ha, empty) - assert type(v) is cirq.FrozenCircuit and v == ha.freeze() - - -def test_tetris_concat_alignment_deprecated(): - a, b = cirq.LineQubit.range(2) - - with cirq.testing.assert_deprecated('ragged', deadline='v0.16', count=None): - - assert cirq.Circuit.tetris_concat( - cirq.Circuit(cirq.X(a)), - cirq.Circuit(cirq.Y(b)) * 4, - cirq.Circuit(cirq.Z(a)), - align='first', - ) == cirq.Circuit( - cirq.Moment(cirq.X(a), cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.Z(a), cirq.Y(b)), - ) - - assert cirq.Circuit.tetris_concat( - cirq.Circuit(cirq.X(a)), - cirq.Circuit(cirq.Y(b)) * 4, - cirq.Circuit(cirq.Z(a)), - align='left', - ) == cirq.Circuit( - cirq.Moment(cirq.X(a), cirq.Y(b)), - cirq.Moment(cirq.Z(a), cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - ) - - assert cirq.Circuit.tetris_concat( - cirq.Circuit(cirq.X(a)), - cirq.Circuit(cirq.Y(b)) * 4, - cirq.Circuit(cirq.Z(a)), - align='right', - ) == cirq.Circuit( - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.Y(b)), - cirq.Moment(cirq.X(a), cirq.Y(b)), - cirq.Moment(cirq.Z(a)), - ) - - def test_concat_ragged(): a, b = cirq.LineQubit.range(2) empty = cirq.Circuit() diff --git a/cirq-core/cirq/circuits/frozen_circuit.py b/cirq-core/cirq/circuits/frozen_circuit.py index 75d56a9c3e9..bc735439619 100644 --- a/cirq-core/cirq/circuits/frozen_circuit.py +++ b/cirq-core/cirq/circuits/frozen_circuit.py @@ -20,7 +20,6 @@ from cirq.circuits import AbstractCircuit, Alignment, Circuit from cirq.circuits.insert_strategy import InsertStrategy from cirq.type_workarounds import NotImplementedType -from cirq import ops, protocols, _compat if TYPE_CHECKING: import cirq @@ -172,14 +171,6 @@ def concat_ragged( concat_ragged.__doc__ = AbstractCircuit.concat_ragged.__doc__ - @_compat.deprecated(deadline='v0.16', fix='Renaming to concat_ragged') - def tetris_concat( - *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT - ) -> 'cirq.FrozenCircuit': - return AbstractCircuit.tetris_concat(*circuits, align=align).freeze() - - tetris_concat.__doc__ = AbstractCircuit.tetris_concat.__doc__ - def zip( *circuits: 'cirq.AbstractCircuit', align: Union['cirq.Alignment', str] = Alignment.LEFT ) -> 'cirq.FrozenCircuit':