From f4ec2cc831f9b9fa993ee16c6b26fe30b279c529 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri <7265746+anurudhp@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:20:57 -0700 Subject: [PATCH] Support more symbolic decompositions (#1369) * allow more symbolic decomp in Permutation bloqs * `StatePreparationViaRotation` - support symbolic phasegrad bitsize * permutation - add more symbolic examples * state-prep-rotations - symbolic examples + autotest * assert decomp exists * regen notebooks * update bloq_ex --- qualtran/bloqs/arithmetic/permutation.ipynb | 95 +++++++++++++------ qualtran/bloqs/arithmetic/permutation.py | 38 ++++++-- qualtran/bloqs/arithmetic/permutation_test.py | 46 +++++++-- .../state_preparation_via_rotation.ipynb | 63 +++++++----- .../state_preparation_via_rotation.py | 39 +++++++- .../state_preparation_via_rotation_test.py | 14 ++- qualtran/conftest.py | 6 ++ 7 files changed, 223 insertions(+), 78 deletions(-) diff --git a/qualtran/bloqs/arithmetic/permutation.ipynb b/qualtran/bloqs/arithmetic/permutation.ipynb index 3cb5bd4de..a2f9dc5d7 100644 --- a/qualtran/bloqs/arithmetic/permutation.ipynb +++ b/qualtran/bloqs/arithmetic/permutation.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "a48878df", + "id": "a697fa0f", "metadata": { "cq.autogen": "title_cell" }, @@ -13,7 +13,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d083d346", + "id": "f3a56020", "metadata": { "cq.autogen": "top_imports" }, @@ -30,7 +30,7 @@ }, { "cell_type": "markdown", - "id": "56539662", + "id": "39be898d", "metadata": { "cq.autogen": "Permutation.bloq_doc.md" }, @@ -62,7 +62,7 @@ { "cell_type": "code", "execution_count": null, - "id": "df73124f", + "id": "88b7712d", "metadata": { "cq.autogen": "Permutation.bloq_doc.py" }, @@ -73,7 +73,7 @@ }, { "cell_type": "markdown", - "id": "31147b0d", + "id": "5c4722c6", "metadata": { "cq.autogen": "Permutation.example_instances.md" }, @@ -84,7 +84,7 @@ { "cell_type": "code", "execution_count": null, - "id": "ec6460b6", + "id": "8e38bf3a", "metadata": { "cq.autogen": "Permutation.permutation" }, @@ -96,7 +96,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0c8e04f0", + "id": "52218544", "metadata": { "cq.autogen": "Permutation.permutation_symb" }, @@ -113,7 +113,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8578d036", + "id": "cb1a6988", "metadata": { "cq.autogen": "Permutation.permutation_symb_with_cycles" }, @@ -132,7 +132,7 @@ { "cell_type": "code", "execution_count": null, - "id": "84b5606a", + "id": "f58b58f7", "metadata": { "cq.autogen": "Permutation.sparse_permutation" }, @@ -143,9 +143,26 @@ ")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "e644f2ac", + "metadata": { + "cq.autogen": "Permutation.sparse_permutation_with_symbolic_N" + }, + "outputs": [], + "source": [ + "import sympy\n", + "\n", + "N = sympy.symbols(\"N\", positive=True, integer=True)\n", + "sparse_permutation_with_symbolic_N = Permutation.from_partial_permutation_map(\n", + " N, {0: 1, 1: 3, 2: 4, 3: 7}\n", + ")" + ] + }, { "cell_type": "markdown", - "id": "369df9cb", + "id": "ace174d5", "metadata": { "cq.autogen": "Permutation.graphical_signature.md" }, @@ -156,20 +173,20 @@ { "cell_type": "code", "execution_count": null, - "id": "25b2dc2b", + "id": "1e55dcd4", "metadata": { "cq.autogen": "Permutation.graphical_signature.py" }, "outputs": [], "source": [ "from qualtran.drawing import show_bloqs\n", - "show_bloqs([permutation, permutation_symb, permutation_symb_with_cycles, sparse_permutation],\n", - " ['`permutation`', '`permutation_symb`', '`permutation_symb_with_cycles`', '`sparse_permutation`'])" + "show_bloqs([permutation, permutation_symb, permutation_symb_with_cycles, sparse_permutation, sparse_permutation_with_symbolic_N],\n", + " ['`permutation`', '`permutation_symb`', '`permutation_symb_with_cycles`', '`sparse_permutation`', '`sparse_permutation_with_symbolic_N`'])" ] }, { "cell_type": "markdown", - "id": "ad4321ad", + "id": "32e2b5dd", "metadata": { "cq.autogen": "Permutation.call_graph.md" }, @@ -180,7 +197,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3bfbf3f7", + "id": "fab3fd69", "metadata": { "cq.autogen": "Permutation.call_graph.py" }, @@ -194,7 +211,7 @@ }, { "cell_type": "markdown", - "id": "b3e895db", + "id": "408e209c", "metadata": { "cq.autogen": "PermutationCycle.bloq_doc.md" }, @@ -230,7 +247,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d569cd2c", + "id": "bc68fccd", "metadata": { "cq.autogen": "PermutationCycle.bloq_doc.py" }, @@ -241,7 +258,7 @@ }, { "cell_type": "markdown", - "id": "a93c6e89", + "id": "de4c7922", "metadata": { "cq.autogen": "PermutationCycle.example_instances.md" }, @@ -252,19 +269,23 @@ { "cell_type": "code", "execution_count": null, - "id": "264ba946", + "id": "071de1e1", "metadata": { - "cq.autogen": "PermutationCycle.permutation_cycle" + "cq.autogen": "PermutationCycle.permutation_cycle_symb_N" }, "outputs": [], "source": [ - "permutation_cycle = PermutationCycle(4, (0, 1, 2))" + "import sympy\n", + "\n", + "N = sympy.symbols(\"n\", positive=True, integer=True)\n", + "cycle = (3, 1, 2)\n", + "permutation_cycle_symb_N = PermutationCycle(N, cycle)" ] }, { "cell_type": "code", "execution_count": null, - "id": "78572528", + "id": "fd61e92a", "metadata": { "cq.autogen": "PermutationCycle.permutation_cycle_symb" }, @@ -279,9 +300,21 @@ "permutation_cycle_symb = PermutationCycle(N, cycle)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "b818f3b1", + "metadata": { + "cq.autogen": "PermutationCycle.permutation_cycle" + }, + "outputs": [], + "source": [ + "permutation_cycle = PermutationCycle(4, (0, 1, 2))" + ] + }, { "cell_type": "markdown", - "id": "87615783", + "id": "3d3c3e1b", "metadata": { "cq.autogen": "PermutationCycle.graphical_signature.md" }, @@ -292,20 +325,20 @@ { "cell_type": "code", "execution_count": null, - "id": "f6961010", + "id": "de967993", "metadata": { "cq.autogen": "PermutationCycle.graphical_signature.py" }, "outputs": [], "source": [ "from qualtran.drawing import show_bloqs\n", - "show_bloqs([permutation_cycle, permutation_cycle_symb],\n", - " ['`permutation_cycle`', '`permutation_cycle_symb`'])" + "show_bloqs([permutation_cycle_symb_N, permutation_cycle_symb, permutation_cycle],\n", + " ['`permutation_cycle_symb_N`', '`permutation_cycle_symb`', '`permutation_cycle`'])" ] }, { "cell_type": "markdown", - "id": "16e1c105", + "id": "58deda5c", "metadata": { "cq.autogen": "PermutationCycle.call_graph.md" }, @@ -316,16 +349,16 @@ { "cell_type": "code", "execution_count": null, - "id": "27628f10", + "id": "ec16903f", "metadata": { "cq.autogen": "PermutationCycle.call_graph.py" }, "outputs": [], "source": [ "from qualtran.resource_counting.generalizers import ignore_split_join\n", - "permutation_cycle_g, permutation_cycle_sigma = permutation_cycle.call_graph(max_depth=1, generalizer=ignore_split_join)\n", - "show_call_graph(permutation_cycle_g)\n", - "show_counts_sigma(permutation_cycle_sigma)" + "permutation_cycle_symb_N_g, permutation_cycle_symb_N_sigma = permutation_cycle_symb_N.call_graph(max_depth=1, generalizer=ignore_split_join)\n", + "show_call_graph(permutation_cycle_symb_N_g)\n", + "show_counts_sigma(permutation_cycle_symb_N_sigma)" ] } ], diff --git a/qualtran/bloqs/arithmetic/permutation.py b/qualtran/bloqs/arithmetic/permutation.py index 7deb8fabc..e67b66cc4 100644 --- a/qualtran/bloqs/arithmetic/permutation.py +++ b/qualtran/bloqs/arithmetic/permutation.py @@ -104,9 +104,6 @@ def signature(self) -> Signature: def bitsize(self): return bit_length(self.N - 1) - def is_symbolic(self): - return is_symbolic(self.N, self.cycle) - def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> dict[str, 'SoquetT']: if is_symbolic(self.cycle): raise DecomposeTypeError(f"cannot decompose symbolic {self}") @@ -126,7 +123,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> dict[str, 'So return {'x': x} def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']: - if self.is_symbolic(): + if is_symbolic(self.cycle): x = ssa.new_symbol('x') cycle_len = slen(self.cycle) return { @@ -143,6 +140,16 @@ def _permutation_cycle() -> PermutationCycle: return permutation_cycle +@bloq_example +def _permutation_cycle_symb_N() -> PermutationCycle: + import sympy + + N = sympy.symbols("n", positive=True, integer=True) + cycle = (3, 1, 2) + permutation_cycle_symb_N = PermutationCycle(N, cycle) + return permutation_cycle_symb_N + + @bloq_example def _permutation_cycle_symb() -> PermutationCycle: import sympy @@ -158,7 +165,7 @@ def _permutation_cycle_symb() -> PermutationCycle: _PERMUTATION_CYCLE_DOC = BloqDocSpec( bloq_cls=PermutationCycle, import_line='from qualtran.bloqs.arithmetic.permutation import PermutationCycle', - examples=[_permutation_cycle, _permutation_cycle_symb], + examples=[_permutation_cycle_symb_N, _permutation_cycle_symb, _permutation_cycle], ) @@ -261,7 +268,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'Soquet') -> dict[str, 'Soq return {'x': x} def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']: - if self.is_symbolic(): + if is_symbolic(self.cycles): # worst case cost: single cycle of length N cycle = Shaped((self.N,)) return {(PermutationCycle(self.N, cycle), 1)} @@ -307,8 +314,25 @@ def _sparse_permutation() -> Permutation: return sparse_permutation +@bloq_example +def _sparse_permutation_with_symbolic_N() -> Permutation: + import sympy + + N = sympy.symbols("N", positive=True, integer=True) + sparse_permutation_with_symbolic_N = Permutation.from_partial_permutation_map( + N, {0: 1, 1: 3, 2: 4, 3: 7} + ) + return sparse_permutation_with_symbolic_N + + _PERMUTATION_DOC = BloqDocSpec( bloq_cls=Permutation, import_line='from qualtran.bloqs.arithmetic.permutation import Permutation', - examples=[_permutation, _permutation_symb, _permutation_symb_with_cycles, _sparse_permutation], + examples=[ + _permutation, + _permutation_symb, + _permutation_symb_with_cycles, + _sparse_permutation, + _sparse_permutation_with_symbolic_N, + ], ) diff --git a/qualtran/bloqs/arithmetic/permutation_test.py b/qualtran/bloqs/arithmetic/permutation_test.py index 2414b97d6..07e207300 100644 --- a/qualtran/bloqs/arithmetic/permutation_test.py +++ b/qualtran/bloqs/arithmetic/permutation_test.py @@ -24,16 +24,20 @@ # See the License for the specific language governing permissions and # limitations under the License. import numpy as np +import pytest import sympy +import qualtran.testing as qlt_testing from qualtran import QBit from qualtran.bloqs.arithmetic.permutation import ( _permutation, _permutation_cycle, _permutation_cycle_symb, + _permutation_cycle_symb_N, _permutation_symb, _permutation_symb_with_cycles, _sparse_permutation, + _sparse_permutation_with_symbolic_N, Permutation, PermutationCycle, ) @@ -44,16 +48,38 @@ from qualtran.symbolics import ceil, log2, slen -def test_examples(bloq_autotester): - bloq_autotester(_permutation_cycle) - bloq_autotester(_permutation) - bloq_autotester(_sparse_permutation) - - -def test_symbolic_examples(bloq_autotester): - bloq_autotester(_permutation_cycle_symb) - bloq_autotester(_permutation_symb) - bloq_autotester(_permutation_symb_with_cycles) +@pytest.mark.parametrize( + "bloq_ex", + [ + _permutation_cycle, + _permutation, + _sparse_permutation, + _permutation_cycle_symb, + _permutation_cycle_symb_N, + _permutation_symb, + _permutation_symb_with_cycles, + _sparse_permutation_with_symbolic_N, + ], + ids=lambda bloq_ex: bloq_ex.name, +) +def test_examples(bloq_autotester, bloq_ex): + bloq_autotester(bloq_ex) + + +@pytest.mark.parametrize( + "bloq_ex", + [ + _permutation_cycle, + _permutation, + _sparse_permutation, + _permutation_cycle_symb_N, + _permutation_symb_with_cycles, + _sparse_permutation_with_symbolic_N, + ], + ids=lambda bloq_ex: bloq_ex.name, +) +def test_decomposition(bloq_ex): + qlt_testing.assert_valid_bloq_decomposition(bloq_ex.make()) def test_permutation_cycle_unitary_and_call_graph(): diff --git a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.ipynb b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.ipynb index e5349906f..ee713c6e8 100644 --- a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.ipynb +++ b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "d317cae7", + "id": "2568299e", "metadata": { "cq.autogen": "title_cell" }, @@ -72,7 +72,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8503ea6a", + "id": "4f761ae7", "metadata": { "cq.autogen": "top_imports" }, @@ -89,7 +89,7 @@ }, { "cell_type": "markdown", - "id": "7e8c4520", + "id": "17790c77", "metadata": { "cq.autogen": "StatePreparationViaRotations.bloq_doc.md" }, @@ -118,7 +118,7 @@ { "cell_type": "code", "execution_count": null, - "id": "f1e3b82f", + "id": "55c81370", "metadata": { "cq.autogen": "StatePreparationViaRotations.bloq_doc.py" }, @@ -129,7 +129,7 @@ }, { "cell_type": "markdown", - "id": "5f208fa8", + "id": "d8c2407c", "metadata": { "cq.autogen": "StatePreparationViaRotations.example_instances.md" }, @@ -140,7 +140,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c68e5fd9", + "id": "cd0552db", "metadata": { "cq.autogen": "StatePreparationViaRotations.state_prep_via_rotation" }, @@ -164,7 +164,7 @@ { "cell_type": "code", "execution_count": null, - "id": "88379aff", + "id": "a52e9cf3", "metadata": { "cq.autogen": "StatePreparationViaRotations.state_prep_via_rotation_symb" }, @@ -179,9 +179,35 @@ ")" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "5446822b", + "metadata": { + "cq.autogen": "StatePreparationViaRotations.state_prep_via_rotation_symb_phasegrad" + }, + "outputs": [], + "source": [ + "state_coefs = (\n", + " (-0.42677669529663675 - 0.1767766952966366j),\n", + " (0.17677669529663664 - 0.4267766952966367j),\n", + " (0.17677669529663675 - 0.1767766952966368j),\n", + " (0.07322330470336305 - 0.07322330470336309j),\n", + " (0.4267766952966366 - 0.17677669529663692j),\n", + " (0.42677669529663664 + 0.17677669529663675j),\n", + " (0.0732233047033631 + 0.17677669529663678j),\n", + " (-0.07322330470336308 - 0.17677669529663678j),\n", + ")\n", + "\n", + "phase_bitsize = sympy.Symbol(r\"b_\\text{grad}\")\n", + "state_prep_via_rotation_symb_phasegrad = StatePreparationViaRotations(\n", + " state_coefficients=state_coefs, phase_bitsize=phase_bitsize\n", + ")" + ] + }, { "cell_type": "markdown", - "id": "a2669c47", + "id": "facf9536", "metadata": { "cq.autogen": "StatePreparationViaRotations.graphical_signature.md" }, @@ -192,20 +218,20 @@ { "cell_type": "code", "execution_count": null, - "id": "09a897a8", + "id": "2d801788", "metadata": { "cq.autogen": "StatePreparationViaRotations.graphical_signature.py" }, "outputs": [], "source": [ "from qualtran.drawing import show_bloqs\n", - "show_bloqs([state_prep_via_rotation, state_prep_via_rotation_symb],\n", - " ['`state_prep_via_rotation`', '`state_prep_via_rotation_symb`'])" + "show_bloqs([state_prep_via_rotation, state_prep_via_rotation_symb, state_prep_via_rotation_symb_phasegrad],\n", + " ['`state_prep_via_rotation`', '`state_prep_via_rotation_symb`', '`state_prep_via_rotation_symb_phasegrad`'])" ] }, { "cell_type": "markdown", - "id": "6aa59344", + "id": "c1aeb064", "metadata": { "cq.autogen": "StatePreparationViaRotations.call_graph.md" }, @@ -216,7 +242,7 @@ { "cell_type": "code", "execution_count": null, - "id": "939bd8f8", + "id": "a6fee1d3", "metadata": { "cq.autogen": "StatePreparationViaRotations.call_graph.py" }, @@ -236,16 +262,7 @@ "name": "python3" }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.0" + "name": "python" } }, "nbformat": 4, diff --git a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py index 0914c881e..5fdf8a8e4 100644 --- a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py +++ b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py @@ -86,6 +86,7 @@ bloq_example, BloqBuilder, BloqDocSpec, + DecomposeTypeError, GateWithRegisters, Signature, Soquet, @@ -148,7 +149,8 @@ def __attrs_post_init__(self): # negative number of control bits is not allowed assert self.control_bitsize >= 0 # the register to which the angle is written must be at least of size two - assert self.phase_bitsize > 1 + if not is_symbolic(self.phase_bitsize): + assert self.phase_bitsize > 1 # a valid quantum state must have norm one assert np.isclose(np.linalg.norm(self.state_coefficients), 1) @@ -175,7 +177,7 @@ def rotation_tree(self) -> 'RotationTree': @property def prga_prepare_amplitude(self) -> List['PRGAViaPhaseGradient']: - if is_symbolic(self.state_coefficients): + if is_symbolic(self.state_coefficients, self.phase_bitsize): return [ PRGAViaPhaseGradient( selection_bitsize=self.state_bitsize, @@ -199,8 +201,8 @@ def prga_prepare_amplitude(self) -> List['PRGAViaPhaseGradient']: @property def prga_prepare_phases(self) -> 'PRGAViaPhaseGradient': data_or_shape: Union[Shaped, Tuple[int, ...]] = ( - Shaped((self.state_coefficients.n,)) - if isinstance(self.state_coefficients, HasLength) + Shaped((slen(self.state_coefficients),)) + if is_symbolic(self.state_coefficients) or is_symbolic(self.phase_bitsize) else tuple(self.rotation_tree.get_rom_vals()[1]) ) return PRGAViaPhaseGradient( @@ -216,6 +218,9 @@ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, So * target_state: register where the state is written * phase_gradient: phase gradient state (will be left unaffected) """ + if is_symbolic(self.state_coefficients) or is_symbolic(self.phase_bitsize): + raise DecomposeTypeError(f"cannot decompose symbolic {self}") + if self.uncompute: soqs = self._prepare_phases(bb, **soqs) soqs = self._prepare_amplitudes(bb, **soqs) @@ -350,9 +355,33 @@ def _state_prep_via_rotation_symb() -> StatePreparationViaRotations: return state_prep_via_rotation_symb +@bloq_example +def _state_prep_via_rotation_symb_phasegrad() -> StatePreparationViaRotations: + state_coefs = ( + (-0.42677669529663675 - 0.1767766952966366j), + (0.17677669529663664 - 0.4267766952966367j), + (0.17677669529663675 - 0.1767766952966368j), + (0.07322330470336305 - 0.07322330470336309j), + (0.4267766952966366 - 0.17677669529663692j), + (0.42677669529663664 + 0.17677669529663675j), + (0.0732233047033631 + 0.17677669529663678j), + (-0.07322330470336308 - 0.17677669529663678j), + ) + + phase_bitsize = sympy.Symbol(r"b_\text{grad}") + state_prep_via_rotation_symb_phasegrad = StatePreparationViaRotations( + state_coefficients=state_coefs, phase_bitsize=phase_bitsize + ) + return state_prep_via_rotation_symb_phasegrad + + _STATE_PREP_VIA_ROTATIONS_DOC = BloqDocSpec( bloq_cls=StatePreparationViaRotations, - examples=(_state_prep_via_rotation, _state_prep_via_rotation_symb), + examples=( + _state_prep_via_rotation, + _state_prep_via_rotation_symb, + _state_prep_via_rotation_symb_phasegrad, + ), ) diff --git a/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py b/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py index dfca14355..6b7a77057 100644 --- a/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py +++ b/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py @@ -24,6 +24,7 @@ from qualtran.bloqs.state_preparation.state_preparation_via_rotation import ( _state_prep_via_rotation, _state_prep_via_rotation_symb, + _state_prep_via_rotation_symb_phasegrad, PRGAViaPhaseGradient, StatePreparationViaRotations, ) @@ -34,8 +35,17 @@ def accuracy(state1, state2): return abs(np.dot(state1, state2.conj())) -def test_state_prep_via_rotation(bloq_autotester): - bloq_autotester(_state_prep_via_rotation) +@pytest.mark.parametrize( + "bloq_ex", + [ + _state_prep_via_rotation, + _state_prep_via_rotation_symb, + _state_prep_via_rotation_symb_phasegrad, + ], + ids=lambda bloq_ex: bloq_ex.name, +) +def test_state_prep_via_rotation(bloq_autotester, bloq_ex): + bloq_autotester(bloq_ex) def test_state_prep_via_rotation_symb_quick(): diff --git a/qualtran/conftest.py b/qualtran/conftest.py index e5fe9df21..81b05b8c7 100644 --- a/qualtran/conftest.py +++ b/qualtran/conftest.py @@ -109,6 +109,12 @@ def assert_bloq_example_serializes_for_pytest(bloq_ex: BloqExample): 'sparse_state_prep_alias_symb', # cannot serialize Shaped 'sparse_permutation', # contains nested tuple of inhomogeneous shape 'permutation_cycle_symb', # cannot serialize Shaped + 'permutation_cycle_symb_N', # sympy variable assumptions dropped by serialized + 'permutation_symb', # cannot serialize shaped + 'permutation_symb_with_cycles', # Object arrays cannot be saved when allow_pickle=False + 'sparse_permutation_with_symbolic_N', # setting an array element with a sequence. + 'state_prep_via_rotation_symb', # cannot serialize HasLength + 'state_prep_via_rotation_symb_phasegrad', # cannot serialize Shaped 'sparse_state_prep_via_rotations', # cannot serialize Permutation 'explicit_matrix_block_encoding', # cannot serialize AutoPartition 'symmetric_banded_matrix_block_encoding', # cannot serialize AutoPartition