From 56f5e7ac390258d73bd9897e14b4e15ea2a5715d Mon Sep 17 00:00:00 2001 From: to24toro Date: Tue, 7 Nov 2023 17:51:38 +0900 Subject: [PATCH 01/21] add sparse module --- qiskit_dynamics/arraylias/alias.py | 32 ++++++++++ .../arraylias/register_functions/__init__.py | 24 ++++++++ .../arraylias/register_functions/asarray.py | 50 +++++++++++++++ .../arraylias/register_functions/matmul.py | 38 ++++++++++++ .../arraylias/register_functions/multiply.py | 42 +++++++++++++ .../arraylias/register_functions/rmatmul.py | 49 +++++++++++++++ .../arraylias/register_functions/to_dense.py | 55 +++++++++++++++++ .../to_numeric_matrix_type.py | 57 +++++++++++++++++ .../arraylias/register_functions/to_sparse.py | 61 +++++++++++++++++++ 9 files changed, 408 insertions(+) create mode 100644 qiskit_dynamics/arraylias/register_functions/__init__.py create mode 100644 qiskit_dynamics/arraylias/register_functions/asarray.py create mode 100644 qiskit_dynamics/arraylias/register_functions/matmul.py create mode 100644 qiskit_dynamics/arraylias/register_functions/multiply.py create mode 100644 qiskit_dynamics/arraylias/register_functions/rmatmul.py create mode 100644 qiskit_dynamics/arraylias/register_functions/to_dense.py create mode 100644 qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py create mode 100644 qiskit_dynamics/arraylias/register_functions/to_sparse.py diff --git a/qiskit_dynamics/arraylias/alias.py b/qiskit_dynamics/arraylias/alias.py index 6115d1e72..393693a48 100644 --- a/qiskit_dynamics/arraylias/alias.py +++ b/qiskit_dynamics/arraylias/alias.py @@ -18,12 +18,24 @@ from typing import Union +from scipy.sparse import spmatrix + from arraylias import numpy_alias, scipy_alias from qiskit import QiskitError from qiskit_dynamics.array import Array +from .register_functions import ( + register_asarray, + register_matmul, + register_multiply, + register_rmatmul, + register_todense, + register_to_numeric_matrix_type, + register_tosparse, +) + # global NumPy and SciPy aliases DYNAMICS_NUMPY_ALIAS = numpy_alias() DYNAMICS_SCIPY_ALIAS = scipy_alias() @@ -35,6 +47,26 @@ DYNAMICS_NUMPY = DYNAMICS_NUMPY_ALIAS() DYNAMICS_SCIPY = DYNAMICS_SCIPY_ALIAS() +# register required custom versions of functions for sparse type here +DYNAMICS_NUMPY_ALIAS.register_type(spmatrix, lib="scipy_sparse") + +try: + from jax.experimental.sparse import BCOO + + # register required custom versions of functions for BCOO type here + DYNAMICS_NUMPY_ALIAS.register_type(BCOO, lib="jax_sparse") +except ImportError: + pass + +# register custom functions for numpy_alias +register_asarray(alias=DYNAMICS_NUMPY_ALIAS) +register_todense(alias=DYNAMICS_NUMPY_ALIAS) +register_to_numeric_matrix_type(alias=DYNAMICS_NUMPY_ALIAS) +register_tosparse(alias=DYNAMICS_NUMPY_ALIAS) +register_matmul(alias=DYNAMICS_NUMPY_ALIAS) +register_multiply(alias=DYNAMICS_NUMPY_ALIAS) +register_rmatmul(alias=DYNAMICS_NUMPY_ALIAS) + ArrayLike = Union[Union[DYNAMICS_NUMPY_ALIAS.registered_types()], list] diff --git a/qiskit_dynamics/arraylias/register_functions/__init__.py b/qiskit_dynamics/arraylias/register_functions/__init__.py new file mode 100644 index 000000000..afde1402a --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +""" +Register custom functions using alias +""" + +from .asarray import register_asarray +from .to_dense import register_todense +from .to_numeric_matrix_type import register_to_numeric_matrix_type +from .to_sparse import register_tosparse +from .matmul import register_matmul +from .rmatmul import register_rmatmul +from .multiply import register_multiply diff --git a/qiskit_dynamics/arraylias/register_functions/asarray.py b/qiskit_dynamics/arraylias/register_functions/asarray.py new file mode 100644 index 000000000..ebe933681 --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/asarray.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering asarray functions to alias +""" + +import numpy as np +from scipy.sparse import csr_matrix, issparse + + +def register_asarray(alias): + """register asarray functions to each array libraries""" + + @alias.register_default(path="asarray") + def _(arr): + return arr + + @alias.register_function(lib="scipy_sparse", path="asarray") + def _(arr): + if issparse(arr): + return arr + return csr_matrix(arr) + + try: + from jax.experimental.sparse import BCOO + + @alias.register_function(lib="jax_sparse", path="asarray") + def _(arr): + if type(arr).__name__ == "BCOO": + return arr + return BCOO.fromdense(arr) + + except ImportError: + pass + + @alias.register_fallback(path="asarray") + def _(arr): + return np.asarray(arr) diff --git a/qiskit_dynamics/arraylias/register_functions/matmul.py b/qiskit_dynamics/arraylias/register_functions/matmul.py new file mode 100644 index 000000000..f8bee0028 --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/matmul.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering matmul functions to alias +""" + + +def register_matmul(alias): + """register matmul functions to each array libraries""" + + @alias.register_function(lib="scipy_sparse", path="matmul") + def _(x, y): + return x * y + + try: + from jax.experimental import sparse as jsparse + import jax.numpy as jnp + + jsparse_matmul = jsparse.sparsify(jnp.matmul) + + @alias.register_function(lib="jax_sparse", path="matmul") + def _(x, y): + return jsparse_matmul(x, y) + + except ImportError: + pass diff --git a/qiskit_dynamics/arraylias/register_functions/multiply.py b/qiskit_dynamics/arraylias/register_functions/multiply.py new file mode 100644 index 000000000..c1b8002c9 --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/multiply.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering multiply functions to alias +""" + + +def register_multiply(alias): + """register multiply functions to each array libraries""" + + @alias.register_function(lib="scipy_sparse", path="multiply") + def _(x, y): + return x.multiply(y) + + try: + from jax.experimental import sparse as jsparse + import jax.numpy as jnp + + jsparse_multiply = jsparse.sparsify(jnp.multiply) + + @alias.register_function(lib="jax_sparse", path="multiply") + def _(x, y): + return jsparse_multiply(x, y) + + except ImportError: + pass + + @alias.register_fallback(path="multiply") + def _(x, y): + return x * y diff --git a/qiskit_dynamics/arraylias/register_functions/rmatmul.py b/qiskit_dynamics/arraylias/register_functions/rmatmul.py new file mode 100644 index 000000000..7b5e1c021 --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/rmatmul.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + + +""" +Registering rmatmul functions to alias +""" + +import numpy as np + + +def register_rmatmul(alias): + """register rmatmul functions to each array libraries""" + + @alias.register_function(lib="numpy", path="rmatmul") + def _(x, y): + return np.matmul(y, x) + + @alias.register_function(lib="scipy_sparse", path="rmatmul") + def _(x, y): + return y * x + + try: + from jax.experimental import sparse as jsparse + import jax.numpy as jnp + + jsparse_matmul = jsparse.sparsify(jnp.matmul) + + @alias.register_function(lib="jax", path="rmatmul") + def _(x, y): + return jnp.matmul(y, x) + + @alias.register_function(lib="jax_sparse", path="rmatmul") + def _(x, y): + return jsparse_matmul(y, x) + + except ImportError: + pass diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py new file mode 100644 index 000000000..edf5d129e --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/to_dense.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering to_dense functions to alias +""" + +import numpy as np +from arraylias.exceptions import LibraryError + + +def register_todense(alias): + """register to_dense functions to each array libraries""" + + @alias.register_default(path="to_dense") + def _(arr): + if arr is None: + return None + return arr + + @alias.register_function(lib="numpy", path="to_dense") + def _(arr): + return arr + + try: + + @alias.register_function(lib="jax", path="to_dense") + def _(arr): + return arr + + @alias.register_function(lib="jax_sparse", path="to_dense") + def _(arr): + return arr.todense() + + except LibraryError: + pass + + @alias.register_function(lib="scipy_sparse", path="to_dense") + def _(arr): + return arr.toarray() + + @alias.register_fallback(path="to_dense") + def _(arr): + return np.asarray(arr) diff --git a/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py b/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py new file mode 100644 index 000000000..e57f16245 --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering to_numeric_matrix_type functions to alias +""" + +from arraylias.exceptions import LibraryError +from qiskit_dynamics.type_utils import isinstance_qutip_qobj + + +def register_to_numeric_matrix_type(alias): + """register to_numeric_matrix_type functions to each array libraries""" + + @alias.register_default(path="to_numeric_matrix_type") + def _(arr): + if arr is None: + return None + if isinstance_qutip_qobj(arr): + return alias().to_sparse(arr.data) + return arr + + @alias.register_function(lib="numpy", path="to_numeric_matrix_type") + def _(arr): + return arr + + try: + + @alias.register_function(lib="jax", path="to_numeric_matrix_type") + def _(arr): + return arr + + @alias.register_function(lib="jax_sparse", path="to_numeric_matrix_type") + def _(arr): + return arr + + except LibraryError: + pass + + @alias.register_function(lib="scipy_sparse", path="to_numeric_matrix_type") + def _(arr): + return arr + + @alias.register_fallback(path="to_numeric_matrix_type") + def _(arr): + return arr diff --git a/qiskit_dynamics/arraylias/register_functions/to_sparse.py b/qiskit_dynamics/arraylias/register_functions/to_sparse.py new file mode 100644 index 000000000..7808c196c --- /dev/null +++ b/qiskit_dynamics/arraylias/register_functions/to_sparse.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Registering asarray functions to alias +""" + +import numpy as np +from scipy.sparse import csr_matrix +from qiskit_dynamics.type_utils import isinstance_qutip_qobj + + +def register_tosparse(alias): + """register to_sparse functions to each array libraries""" + + @alias.register_default(path="to_sparse") + def _(arr): + if arr is None: + return None + if isinstance_qutip_qobj(arr): + return arr.data + return arr + + @alias.register_function(lib="numpy", path="to_sparse") + def _(arr): + if arr.ndim < 3: + return csr_matrix(arr) + return np.array([csr_matrix(sub_arr) for sub_arr in arr]) + + try: + from jax.experimental.sparse import BCOO + + @alias.register_function(lib="jax", path="to_sparse") + def _(arr): + return BCOO.fromdense(arr) + + @alias.register_function(lib="jax_sparse", path="to_sparse") + def _(arr): + return arr + + except ImportError: + pass + + @alias.register_function(lib="scipy_sparse", path="to_sparse") + def _(arr): + return arr + + @alias.register_fallback(path="to_sparse") + def _(arr): + return csr_matrix(arr) From 1f0f136529418151c1042fc8912f4800999b9db4 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:49:28 +0900 Subject: [PATCH 02/21] Update qiskit_dynamics/arraylias/register_functions/to_sparse.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/to_sparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/to_sparse.py b/qiskit_dynamics/arraylias/register_functions/to_sparse.py index 7808c196c..2bcee0837 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_sparse.py +++ b/qiskit_dynamics/arraylias/register_functions/to_sparse.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Registering asarray functions to alias +Registering to_sparse functions to alias. """ import numpy as np From a56088fab1534c1490ea84e13c09f5d34727a2cd Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:49:37 +0900 Subject: [PATCH 03/21] Update qiskit_dynamics/arraylias/register_functions/to_sparse.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/to_sparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/to_sparse.py b/qiskit_dynamics/arraylias/register_functions/to_sparse.py index 2bcee0837..a79d603d1 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_sparse.py +++ b/qiskit_dynamics/arraylias/register_functions/to_sparse.py @@ -22,7 +22,7 @@ def register_tosparse(alias): - """register to_sparse functions to each array libraries""" + """Register to_sparse functions to each array library.""" @alias.register_default(path="to_sparse") def _(arr): From ab5ec7dd91fbecdbd5b719eb4e9256be5b1b6f78 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:49:44 +0900 Subject: [PATCH 04/21] Update qiskit_dynamics/arraylias/register_functions/rmatmul.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/rmatmul.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/rmatmul.py b/qiskit_dynamics/arraylias/register_functions/rmatmul.py index 7b5e1c021..6ed41e170 100644 --- a/qiskit_dynamics/arraylias/register_functions/rmatmul.py +++ b/qiskit_dynamics/arraylias/register_functions/rmatmul.py @@ -21,7 +21,7 @@ def register_rmatmul(alias): - """register rmatmul functions to each array libraries""" + """Register rmatmul functions to each array library.""" @alias.register_function(lib="numpy", path="rmatmul") def _(x, y): From 907a8786dbcb2320641499f39b46ca801ee16878 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:49:49 +0900 Subject: [PATCH 05/21] Update qiskit_dynamics/arraylias/register_functions/multiply.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/multiply.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/multiply.py b/qiskit_dynamics/arraylias/register_functions/multiply.py index c1b8002c9..77977c6f0 100644 --- a/qiskit_dynamics/arraylias/register_functions/multiply.py +++ b/qiskit_dynamics/arraylias/register_functions/multiply.py @@ -18,7 +18,7 @@ def register_multiply(alias): - """register multiply functions to each array libraries""" + """Register multiply functions to each array library.""" @alias.register_function(lib="scipy_sparse", path="multiply") def _(x, y): From 025454eaab7582334bec79d523dc145c4de13985 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:49:57 +0900 Subject: [PATCH 06/21] Update qiskit_dynamics/arraylias/register_functions/to_dense.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/to_dense.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py index edf5d129e..89cb27142 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_dense.py +++ b/qiskit_dynamics/arraylias/register_functions/to_dense.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Registering to_dense functions to alias +Register to_dense functions to alias. """ import numpy as np From d9e537d8d526e95ac57e2f0e8459c6baa946811d Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:50:03 +0900 Subject: [PATCH 07/21] Update qiskit_dynamics/arraylias/register_functions/to_dense.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/to_dense.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py index 89cb27142..d00864aa8 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_dense.py +++ b/qiskit_dynamics/arraylias/register_functions/to_dense.py @@ -21,7 +21,7 @@ def register_todense(alias): - """register to_dense functions to each array libraries""" + """Register to_dense functions to each array library.""" @alias.register_default(path="to_dense") def _(arr): From 6687bb6ffae415403c8f0a586f4ae6696f2510c6 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:50:11 +0900 Subject: [PATCH 08/21] Update qiskit_dynamics/arraylias/register_functions/matmul.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/matmul.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/matmul.py b/qiskit_dynamics/arraylias/register_functions/matmul.py index f8bee0028..ef8ec37c9 100644 --- a/qiskit_dynamics/arraylias/register_functions/matmul.py +++ b/qiskit_dynamics/arraylias/register_functions/matmul.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Registering matmul functions to alias +Register matmul functions to alias. """ From 41d8fc7740cfcd6c74fed3084a16a2ed8695ca31 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:50:21 +0900 Subject: [PATCH 09/21] Update qiskit_dynamics/arraylias/register_functions/rmatmul.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/rmatmul.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/rmatmul.py b/qiskit_dynamics/arraylias/register_functions/rmatmul.py index 6ed41e170..708022f76 100644 --- a/qiskit_dynamics/arraylias/register_functions/rmatmul.py +++ b/qiskit_dynamics/arraylias/register_functions/rmatmul.py @@ -14,7 +14,7 @@ """ -Registering rmatmul functions to alias +Register rmatmul functions to alias. """ import numpy as np From d075dedd7183dc079242074d985136eabe1a76f3 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:50:30 +0900 Subject: [PATCH 10/21] Update qiskit_dynamics/arraylias/register_functions/multiply.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/multiply.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/multiply.py b/qiskit_dynamics/arraylias/register_functions/multiply.py index 77977c6f0..9cb2f2ec1 100644 --- a/qiskit_dynamics/arraylias/register_functions/multiply.py +++ b/qiskit_dynamics/arraylias/register_functions/multiply.py @@ -13,7 +13,7 @@ # that they have been altered from the originals. """ -Registering multiply functions to alias +Register multiply functions to alias. """ From 9fe669e6b36702770c060831490e25f2aea06c31 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:50:42 +0900 Subject: [PATCH 11/21] Update qiskit_dynamics/arraylias/register_functions/matmul.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/matmul.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/matmul.py b/qiskit_dynamics/arraylias/register_functions/matmul.py index ef8ec37c9..23e727b71 100644 --- a/qiskit_dynamics/arraylias/register_functions/matmul.py +++ b/qiskit_dynamics/arraylias/register_functions/matmul.py @@ -18,7 +18,7 @@ def register_matmul(alias): - """register matmul functions to each array libraries""" + """Register matmul functions to required array libraries.""" @alias.register_function(lib="scipy_sparse", path="matmul") def _(x, y): From c962a34562ee9e104e2600142a9398f18638477f Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Mon, 13 Nov 2023 22:23:53 +0900 Subject: [PATCH 12/21] Update qiskit_dynamics/arraylias/register_functions/asarray.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/asarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/asarray.py b/qiskit_dynamics/arraylias/register_functions/asarray.py index ebe933681..a4db54228 100644 --- a/qiskit_dynamics/arraylias/register_functions/asarray.py +++ b/qiskit_dynamics/arraylias/register_functions/asarray.py @@ -25,7 +25,7 @@ def register_asarray(alias): @alias.register_default(path="asarray") def _(arr): - return arr + return np.asarray(arr) @alias.register_function(lib="scipy_sparse", path="asarray") def _(arr): From 64cbf56fb630f01410bf946a81a472aa9b8a5431 Mon Sep 17 00:00:00 2001 From: Kento Ueda <38037695+to24toro@users.noreply.github.com> Date: Mon, 13 Nov 2023 22:24:15 +0900 Subject: [PATCH 13/21] Update qiskit_dynamics/arraylias/register_functions/to_dense.py Co-authored-by: Daniel Puzzuoli --- qiskit_dynamics/arraylias/register_functions/to_dense.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py index d00864aa8..0eec3e65c 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_dense.py +++ b/qiskit_dynamics/arraylias/register_functions/to_dense.py @@ -27,7 +27,7 @@ def register_todense(alias): def _(arr): if arr is None: return None - return arr + return np.asarray(arr) @alias.register_function(lib="numpy", path="to_dense") def _(arr): From 8dccad1afb10e0d54c5c7e213bea51d3d9f316a6 Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 15 Nov 2023 10:52:32 +0900 Subject: [PATCH 14/21] change the order of the funtion places --- qiskit_dynamics/arraylias/register_functions/asarray.py | 8 ++++---- qiskit_dynamics/arraylias/register_functions/multiply.py | 8 ++++---- qiskit_dynamics/arraylias/register_functions/to_dense.py | 8 ++++---- .../register_functions/to_numeric_matrix_type.py | 8 ++++---- qiskit_dynamics/arraylias/register_functions/to_sparse.py | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/qiskit_dynamics/arraylias/register_functions/asarray.py b/qiskit_dynamics/arraylias/register_functions/asarray.py index a4db54228..62c5d325b 100644 --- a/qiskit_dynamics/arraylias/register_functions/asarray.py +++ b/qiskit_dynamics/arraylias/register_functions/asarray.py @@ -27,6 +27,10 @@ def register_asarray(alias): def _(arr): return np.asarray(arr) + @alias.register_fallback(path="asarray") + def _(arr): + return np.asarray(arr) + @alias.register_function(lib="scipy_sparse", path="asarray") def _(arr): if issparse(arr): @@ -44,7 +48,3 @@ def _(arr): except ImportError: pass - - @alias.register_fallback(path="asarray") - def _(arr): - return np.asarray(arr) diff --git a/qiskit_dynamics/arraylias/register_functions/multiply.py b/qiskit_dynamics/arraylias/register_functions/multiply.py index 9cb2f2ec1..88765821d 100644 --- a/qiskit_dynamics/arraylias/register_functions/multiply.py +++ b/qiskit_dynamics/arraylias/register_functions/multiply.py @@ -20,6 +20,10 @@ def register_multiply(alias): """Register multiply functions to each array library.""" + @alias.register_fallback(path="multiply") + def _(x, y): + return x * y + @alias.register_function(lib="scipy_sparse", path="multiply") def _(x, y): return x.multiply(y) @@ -36,7 +40,3 @@ def _(x, y): except ImportError: pass - - @alias.register_fallback(path="multiply") - def _(x, y): - return x * y diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py index 0eec3e65c..b1ecd03d3 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_dense.py +++ b/qiskit_dynamics/arraylias/register_functions/to_dense.py @@ -29,6 +29,10 @@ def _(arr): return None return np.asarray(arr) + @alias.register_fallback(path="to_dense") + def _(arr): + return np.asarray(arr) + @alias.register_function(lib="numpy", path="to_dense") def _(arr): return arr @@ -49,7 +53,3 @@ def _(arr): @alias.register_function(lib="scipy_sparse", path="to_dense") def _(arr): return arr.toarray() - - @alias.register_fallback(path="to_dense") - def _(arr): - return np.asarray(arr) diff --git a/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py b/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py index e57f16245..3f25a56a6 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py +++ b/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py @@ -31,6 +31,10 @@ def _(arr): return alias().to_sparse(arr.data) return arr + @alias.register_fallback(path="to_numeric_matrix_type") + def _(arr): + return arr + @alias.register_function(lib="numpy", path="to_numeric_matrix_type") def _(arr): return arr @@ -51,7 +55,3 @@ def _(arr): @alias.register_function(lib="scipy_sparse", path="to_numeric_matrix_type") def _(arr): return arr - - @alias.register_fallback(path="to_numeric_matrix_type") - def _(arr): - return arr diff --git a/qiskit_dynamics/arraylias/register_functions/to_sparse.py b/qiskit_dynamics/arraylias/register_functions/to_sparse.py index a79d603d1..8f5a09e64 100644 --- a/qiskit_dynamics/arraylias/register_functions/to_sparse.py +++ b/qiskit_dynamics/arraylias/register_functions/to_sparse.py @@ -32,6 +32,10 @@ def _(arr): return arr.data return arr + @alias.register_fallback(path="to_sparse") + def _(arr): + return csr_matrix(arr) + @alias.register_function(lib="numpy", path="to_sparse") def _(arr): if arr.ndim < 3: @@ -55,7 +59,3 @@ def _(arr): @alias.register_function(lib="scipy_sparse", path="to_sparse") def _(arr): return arr - - @alias.register_fallback(path="to_sparse") - def _(arr): - return csr_matrix(arr) From 44c1c4f5c0f4b2791dc384f071cded6266e4c5cb Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 15 Nov 2023 21:20:51 +0900 Subject: [PATCH 15/21] remove to_dense to_sparse to_numeric_matrix_type --- .../arraylias/register_functions/to_dense.py | 55 ----------------- .../to_numeric_matrix_type.py | 57 ----------------- .../arraylias/register_functions/to_sparse.py | 61 ------------------- 3 files changed, 173 deletions(-) delete mode 100644 qiskit_dynamics/arraylias/register_functions/to_dense.py delete mode 100644 qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py delete mode 100644 qiskit_dynamics/arraylias/register_functions/to_sparse.py diff --git a/qiskit_dynamics/arraylias/register_functions/to_dense.py b/qiskit_dynamics/arraylias/register_functions/to_dense.py deleted file mode 100644 index b1ecd03d3..000000000 --- a/qiskit_dynamics/arraylias/register_functions/to_dense.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2023. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Register to_dense functions to alias. -""" - -import numpy as np -from arraylias.exceptions import LibraryError - - -def register_todense(alias): - """Register to_dense functions to each array library.""" - - @alias.register_default(path="to_dense") - def _(arr): - if arr is None: - return None - return np.asarray(arr) - - @alias.register_fallback(path="to_dense") - def _(arr): - return np.asarray(arr) - - @alias.register_function(lib="numpy", path="to_dense") - def _(arr): - return arr - - try: - - @alias.register_function(lib="jax", path="to_dense") - def _(arr): - return arr - - @alias.register_function(lib="jax_sparse", path="to_dense") - def _(arr): - return arr.todense() - - except LibraryError: - pass - - @alias.register_function(lib="scipy_sparse", path="to_dense") - def _(arr): - return arr.toarray() diff --git a/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py b/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py deleted file mode 100644 index 3f25a56a6..000000000 --- a/qiskit_dynamics/arraylias/register_functions/to_numeric_matrix_type.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2023. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Registering to_numeric_matrix_type functions to alias -""" - -from arraylias.exceptions import LibraryError -from qiskit_dynamics.type_utils import isinstance_qutip_qobj - - -def register_to_numeric_matrix_type(alias): - """register to_numeric_matrix_type functions to each array libraries""" - - @alias.register_default(path="to_numeric_matrix_type") - def _(arr): - if arr is None: - return None - if isinstance_qutip_qobj(arr): - return alias().to_sparse(arr.data) - return arr - - @alias.register_fallback(path="to_numeric_matrix_type") - def _(arr): - return arr - - @alias.register_function(lib="numpy", path="to_numeric_matrix_type") - def _(arr): - return arr - - try: - - @alias.register_function(lib="jax", path="to_numeric_matrix_type") - def _(arr): - return arr - - @alias.register_function(lib="jax_sparse", path="to_numeric_matrix_type") - def _(arr): - return arr - - except LibraryError: - pass - - @alias.register_function(lib="scipy_sparse", path="to_numeric_matrix_type") - def _(arr): - return arr diff --git a/qiskit_dynamics/arraylias/register_functions/to_sparse.py b/qiskit_dynamics/arraylias/register_functions/to_sparse.py deleted file mode 100644 index 8f5a09e64..000000000 --- a/qiskit_dynamics/arraylias/register_functions/to_sparse.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- - -# This code is part of Qiskit. -# -# (C) Copyright IBM 2023. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -""" -Registering to_sparse functions to alias. -""" - -import numpy as np -from scipy.sparse import csr_matrix -from qiskit_dynamics.type_utils import isinstance_qutip_qobj - - -def register_tosparse(alias): - """Register to_sparse functions to each array library.""" - - @alias.register_default(path="to_sparse") - def _(arr): - if arr is None: - return None - if isinstance_qutip_qobj(arr): - return arr.data - return arr - - @alias.register_fallback(path="to_sparse") - def _(arr): - return csr_matrix(arr) - - @alias.register_function(lib="numpy", path="to_sparse") - def _(arr): - if arr.ndim < 3: - return csr_matrix(arr) - return np.array([csr_matrix(sub_arr) for sub_arr in arr]) - - try: - from jax.experimental.sparse import BCOO - - @alias.register_function(lib="jax", path="to_sparse") - def _(arr): - return BCOO.fromdense(arr) - - @alias.register_function(lib="jax_sparse", path="to_sparse") - def _(arr): - return arr - - except ImportError: - pass - - @alias.register_function(lib="scipy_sparse", path="to_sparse") - def _(arr): - return arr From ced1dc4a1cd5db121de79e20ab3f41b6eeabe6d9 Mon Sep 17 00:00:00 2001 From: to24toro Date: Wed, 15 Nov 2023 21:34:27 +0900 Subject: [PATCH 16/21] lint --- qiskit_dynamics/arraylias/register_functions/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qiskit_dynamics/arraylias/register_functions/__init__.py b/qiskit_dynamics/arraylias/register_functions/__init__.py index afde1402a..4da5fc49c 100644 --- a/qiskit_dynamics/arraylias/register_functions/__init__.py +++ b/qiskit_dynamics/arraylias/register_functions/__init__.py @@ -16,9 +16,6 @@ """ from .asarray import register_asarray -from .to_dense import register_todense -from .to_numeric_matrix_type import register_to_numeric_matrix_type -from .to_sparse import register_tosparse from .matmul import register_matmul from .rmatmul import register_rmatmul from .multiply import register_multiply From 9fdce087f2af0b387d9919875b853f8cc27def6e Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Wed, 15 Nov 2023 07:23:10 -0800 Subject: [PATCH 17/21] Update alias.py removing import of non-existant register functions --- qiskit_dynamics/arraylias/alias.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qiskit_dynamics/arraylias/alias.py b/qiskit_dynamics/arraylias/alias.py index 393693a48..c15ba9eb8 100644 --- a/qiskit_dynamics/arraylias/alias.py +++ b/qiskit_dynamics/arraylias/alias.py @@ -31,9 +31,6 @@ register_matmul, register_multiply, register_rmatmul, - register_todense, - register_to_numeric_matrix_type, - register_tosparse, ) # global NumPy and SciPy aliases From 12ddc087898e03529e5f688a88e6af54527f9934 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Wed, 15 Nov 2023 07:26:29 -0800 Subject: [PATCH 18/21] Update alias.py Removing calls of non-existant functions --- qiskit_dynamics/arraylias/alias.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qiskit_dynamics/arraylias/alias.py b/qiskit_dynamics/arraylias/alias.py index c15ba9eb8..8868b98c1 100644 --- a/qiskit_dynamics/arraylias/alias.py +++ b/qiskit_dynamics/arraylias/alias.py @@ -57,9 +57,6 @@ # register custom functions for numpy_alias register_asarray(alias=DYNAMICS_NUMPY_ALIAS) -register_todense(alias=DYNAMICS_NUMPY_ALIAS) -register_to_numeric_matrix_type(alias=DYNAMICS_NUMPY_ALIAS) -register_tosparse(alias=DYNAMICS_NUMPY_ALIAS) register_matmul(alias=DYNAMICS_NUMPY_ALIAS) register_multiply(alias=DYNAMICS_NUMPY_ALIAS) register_rmatmul(alias=DYNAMICS_NUMPY_ALIAS) From f6f109ed4a147a14a77da5fb99619a8f18032415 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 16 Nov 2023 12:54:14 +0900 Subject: [PATCH 19/21] addtest --- .../register_functions/test_asarray.py | 53 ++++++++++++++++ .../register_functions/test_matmul.py | 44 +++++++++++++ .../register_functions/test_multiply.py | 50 +++++++++++++++ .../register_functions/test_rmatmul.py | 61 +++++++++++++++++++ test/dynamics/arraylias/test_alias.py | 24 ++++++++ 5 files changed, 232 insertions(+) create mode 100644 test/dynamics/arraylias/register_functions/test_asarray.py create mode 100644 test/dynamics/arraylias/register_functions/test_matmul.py create mode 100644 test/dynamics/arraylias/register_functions/test_multiply.py create mode 100644 test/dynamics/arraylias/register_functions/test_rmatmul.py diff --git a/test/dynamics/arraylias/register_functions/test_asarray.py b/test/dynamics/arraylias/register_functions/test_asarray.py new file mode 100644 index 000000000..942183449 --- /dev/null +++ b/test/dynamics/arraylias/register_functions/test_asarray.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Test asarray functions +""" +import unittest +import numpy as np +from scipy.sparse import csr_matrix +from qiskit.quantum_info.operators import Operator + + +from qiskit_dynamics import DYNAMICS_NUMPY_ALIAS +from qiskit_dynamics import DYNAMICS_NUMPY as unp + + +class TestAsarrayFunction(unittest.TestCase): + """Test cases for asarray functions registered in dynamics_numpy_alias.""" + + def test_register_default(self): + """Test register_default.""" + arr = Operator.from_label("X") + self.assertTrue(isinstance(unp.asarray(arr), np.ndarray)) + + def test_scipy_sparse(self): + """Test asarray for scipy_sparse.""" + arr = np.array([[1, 0], [0, 1]]) + sparse_arr = csr_matrix([[1, 0], [0, 1]]) + self.assertTrue(isinstance(unp.asarray(sparse_arr), csr_matrix)) + self.assertTrue(isinstance(DYNAMICS_NUMPY_ALIAS(like=sparse_arr).asarray(arr), csr_matrix)) + + def test_jax_sparse(self): + """Test asarray for jax_sparse.""" + try: + from jax.experimental.sparse import BCOO + + arr = np.array([[1, 0], [0, 1]]) + sparse_arr = BCOO.fromdense([[1, 0], [0, 1]]) + self.assertTrue(isinstance(unp.asarray(sparse_arr), BCOO)) + self.assertTrue(isinstance(DYNAMICS_NUMPY_ALIAS(like=sparse_arr).asarray(arr), BCOO)) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/register_functions/test_matmul.py b/test/dynamics/arraylias/register_functions/test_matmul.py new file mode 100644 index 000000000..3d727f338 --- /dev/null +++ b/test/dynamics/arraylias/register_functions/test_matmul.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Test matmul functions +""" +import unittest +import numpy as np +from scipy.sparse import csr_matrix + +from qiskit_dynamics import DYNAMICS_NUMPY as unp +from ...common import QiskitDynamicsTestCase + + +class TestMultiplyFunction(QiskitDynamicsTestCase): + """Test cases for matmul functions registered in dynamics_numpy_alias.""" + + def test_scipy_sparse(self): + """Test matmul for scipy_sparse.""" + x = csr_matrix([[1, 0], [0, 1]]) + y = csr_matrix([[2, 2], [2, 2]]) + self.assertAllClose(csr_matrix.toarray(unp.matmul(x, y)), [[2, 2], [2, 2]]) + + def test_jax_sparse(self): + """Test matmul for jax_sparse.""" + try: + from jax.experimental.sparse import BCOO + + x = BCOO.fromdense([[1, 0], [0, 1]]) + y = BCOO.fromdense([[2, 2], [2, 2]]) + self.assertAllClose(BCOO.todense(unp.matmul(x, y)), [[2, 2], [2, 2]]) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/register_functions/test_multiply.py b/test/dynamics/arraylias/register_functions/test_multiply.py new file mode 100644 index 000000000..311dbdf0a --- /dev/null +++ b/test/dynamics/arraylias/register_functions/test_multiply.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Test multiply functions +""" +import unittest +import numpy as np +from scipy.sparse import csr_matrix + +from qiskit_dynamics import DYNAMICS_NUMPY as unp +from ...common import QiskitDynamicsTestCase + + +class TestMultiplyFunction(QiskitDynamicsTestCase): + """Test cases for multiply functions registered in dynamics_numpy_alias.""" + + def test_register_fallback(self): + """Test register_fallback.""" + x = np.array([1, 0]) + y = np.array([1, 0]) + self.assertAllClose(unp.multiply(x, y), [1, 0]) + + def test_scipy_sparse(self): + """Test multiply for scipy_sparse.""" + x = csr_matrix([[1, 0], [0, 1]]) + y = csr_matrix([[2, 2], [2, 2]]) + self.assertAllClose(csr_matrix.toarray(unp.multiply(x, y)), [[2, 0], [0, 2]]) + + def test_jax_sparse(self): + """Test multiply for jax_sparse.""" + try: + from jax.experimental.sparse import BCOO + + x = BCOO.fromdense([[1, 0], [0, 1]]) + y = BCOO.fromdense([[2, 2], [2, 2]]) + self.assertAllClose(BCOO.todense(unp.multiply(x, y)), [[2, 0], [0, 2]]) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/register_functions/test_rmatmul.py b/test/dynamics/arraylias/register_functions/test_rmatmul.py new file mode 100644 index 000000000..f24e39b35 --- /dev/null +++ b/test/dynamics/arraylias/register_functions/test_rmatmul.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2023. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" +Test rmatmul functions +""" +import unittest +import numpy as np +from scipy.sparse import csr_matrix + +from qiskit_dynamics import DYNAMICS_NUMPY as unp +from ...common import QiskitDynamicsTestCase + + +class TestMultiplyFunction(QiskitDynamicsTestCase): + """Test cases for rmatmul functions registered in dynamics_numpy_alias.""" + + def test_numpy(self): + """Test rmatmul for numpy.""" + x = np.array([[1, 1], [1, 1]]) + y = np.array([[1, 2], [3, 4]]) + self.assertAllClose(unp.rmatmul(x, y), [[3, 3], [7, 7]]) + + def test_scipy_sparse(self): + """Test rmatmul for scipy_sparse.""" + x = csr_matrix([[1, 1], [1, 1]]) + y = csr_matrix([[1, 2], [3, 4]]) + self.assertAllClose(csr_matrix.toarray(unp.rmatmul(x, y)), [[3, 3], [7, 7]]) + + def test_jax(self): + """Test rmatmul for jax.""" + try: + import jax.numpy as jnp + + x = jnp.array([[1, 1], [1, 1]]) + y = jnp.array([[1, 2], [3, 4]]) + self.assertAllClose(unp.rmatmul(x, y), [[3, 3], [7, 7]]) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err + + def test_jax_sparse(self): + """Test rmatmul for jax_sparse.""" + try: + from jax.experimental.sparse import BCOO + + x = BCOO.fromdense([[1, 1], [1, 1]]) + y = BCOO.fromdense([[1, 2], [3, 4]]) + self.assertAllClose(BCOO.todense(unp.rmatmul(x, y)), [[3, 3], [7, 7]]) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/test_alias.py b/test/dynamics/arraylias/test_alias.py index fdba7fae1..c342d0b3a 100644 --- a/test/dynamics/arraylias/test_alias.py +++ b/test/dynamics/arraylias/test_alias.py @@ -16,10 +16,13 @@ """ from functools import partial +import unittest import numpy as np import scipy as sp +from scipy.sparse import csr_matrix +from qiskit_dynamics import DYNAMICS_NUMPY_ALIAS from qiskit_dynamics import DYNAMICS_NUMPY as unp from qiskit_dynamics import DYNAMICS_SCIPY as usp @@ -52,3 +55,24 @@ def test_simple_case(self): expected = sp.fft.dct(np.array([1.0, 2.0, 3.0])) self.assertAllClose(output, expected) + + +class TestDynamicsNumpyAliasType(unittest.TestCase): + """Test cases for which types are registered in dynamics_numpy_alias.""" + + def test_spmatrix_type(self): + """Test spmatrix is registered as scipy_sparse.""" + sp_matrix = csr_matrix([[0.0, 1.0], [1.0, 0.0]]) + registered_type_name = "scipy_sparse" + self.assertTrue(registered_type_name in DYNAMICS_NUMPY_ALIAS.infer_libs(sp_matrix)) + + def test_bcoo_type(self): + """Test bcoo is registered.""" + try: + from jax.experimental.sparse import BCOO + + bcoo = BCOO.fromdense([[0.0, 1.0], [1.0, 0.0]]) + registered_type_name = "jax_sparse" + self.assertTrue(registered_type_name in DYNAMICS_NUMPY_ALIAS.infer_libs(bcoo)[0]) + except ImportError as err: + raise unittest.SkipTest("Skipping jax tests.") from err From 8b674fe67dbf6870edb273f565e2f3be30e05348 Mon Sep 17 00:00:00 2001 From: to24toro Date: Thu, 16 Nov 2023 12:54:38 +0900 Subject: [PATCH 20/21] remove fallback --- qiskit_dynamics/arraylias/register_functions/asarray.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qiskit_dynamics/arraylias/register_functions/asarray.py b/qiskit_dynamics/arraylias/register_functions/asarray.py index 62c5d325b..14cbb4452 100644 --- a/qiskit_dynamics/arraylias/register_functions/asarray.py +++ b/qiskit_dynamics/arraylias/register_functions/asarray.py @@ -27,10 +27,6 @@ def register_asarray(alias): def _(arr): return np.asarray(arr) - @alias.register_fallback(path="asarray") - def _(arr): - return np.asarray(arr) - @alias.register_function(lib="scipy_sparse", path="asarray") def _(arr): if issparse(arr): From 6567b8f637372e5cf20bfb57c8edabc5e9b6932c Mon Sep 17 00:00:00 2001 From: to24toro Date: Fri, 17 Nov 2023 10:31:03 +0900 Subject: [PATCH 21/21] add validating type of output of funcs --- test/dynamics/arraylias/register_functions/test_matmul.py | 4 +++- test/dynamics/arraylias/register_functions/test_multiply.py | 3 +++ test/dynamics/arraylias/register_functions/test_rmatmul.py | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/test/dynamics/arraylias/register_functions/test_matmul.py b/test/dynamics/arraylias/register_functions/test_matmul.py index 3d727f338..1aae7ab44 100644 --- a/test/dynamics/arraylias/register_functions/test_matmul.py +++ b/test/dynamics/arraylias/register_functions/test_matmul.py @@ -23,13 +23,14 @@ from ...common import QiskitDynamicsTestCase -class TestMultiplyFunction(QiskitDynamicsTestCase): +class TestMatmulFunction(QiskitDynamicsTestCase): """Test cases for matmul functions registered in dynamics_numpy_alias.""" def test_scipy_sparse(self): """Test matmul for scipy_sparse.""" x = csr_matrix([[1, 0], [0, 1]]) y = csr_matrix([[2, 2], [2, 2]]) + self.assertTrue(isinstance(unp.matmul(x, y), csr_matrix)) self.assertAllClose(csr_matrix.toarray(unp.matmul(x, y)), [[2, 2], [2, 2]]) def test_jax_sparse(self): @@ -39,6 +40,7 @@ def test_jax_sparse(self): x = BCOO.fromdense([[1, 0], [0, 1]]) y = BCOO.fromdense([[2, 2], [2, 2]]) + self.assertTrue(isinstance(unp.matmul(x, y), BCOO)) self.assertAllClose(BCOO.todense(unp.matmul(x, y)), [[2, 2], [2, 2]]) except ImportError as err: raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/register_functions/test_multiply.py b/test/dynamics/arraylias/register_functions/test_multiply.py index 311dbdf0a..bf763df63 100644 --- a/test/dynamics/arraylias/register_functions/test_multiply.py +++ b/test/dynamics/arraylias/register_functions/test_multiply.py @@ -30,12 +30,14 @@ def test_register_fallback(self): """Test register_fallback.""" x = np.array([1, 0]) y = np.array([1, 0]) + self.assertTrue(isinstance(unp.multiply(x, y), np.ndarray)) self.assertAllClose(unp.multiply(x, y), [1, 0]) def test_scipy_sparse(self): """Test multiply for scipy_sparse.""" x = csr_matrix([[1, 0], [0, 1]]) y = csr_matrix([[2, 2], [2, 2]]) + self.assertTrue(isinstance(unp.multiply(x, y), csr_matrix)) self.assertAllClose(csr_matrix.toarray(unp.multiply(x, y)), [[2, 0], [0, 2]]) def test_jax_sparse(self): @@ -45,6 +47,7 @@ def test_jax_sparse(self): x = BCOO.fromdense([[1, 0], [0, 1]]) y = BCOO.fromdense([[2, 2], [2, 2]]) + self.assertTrue(isinstance(unp.multiply(x, y), BCOO)) self.assertAllClose(BCOO.todense(unp.multiply(x, y)), [[2, 0], [0, 2]]) except ImportError as err: raise unittest.SkipTest("Skipping jax tests.") from err diff --git a/test/dynamics/arraylias/register_functions/test_rmatmul.py b/test/dynamics/arraylias/register_functions/test_rmatmul.py index f24e39b35..2abe11c6e 100644 --- a/test/dynamics/arraylias/register_functions/test_rmatmul.py +++ b/test/dynamics/arraylias/register_functions/test_rmatmul.py @@ -23,19 +23,21 @@ from ...common import QiskitDynamicsTestCase -class TestMultiplyFunction(QiskitDynamicsTestCase): +class TestRmatmulFunction(QiskitDynamicsTestCase): """Test cases for rmatmul functions registered in dynamics_numpy_alias.""" def test_numpy(self): """Test rmatmul for numpy.""" x = np.array([[1, 1], [1, 1]]) y = np.array([[1, 2], [3, 4]]) + self.assertTrue(isinstance(unp.rmatmul(x, y), np.ndarray)) self.assertAllClose(unp.rmatmul(x, y), [[3, 3], [7, 7]]) def test_scipy_sparse(self): """Test rmatmul for scipy_sparse.""" x = csr_matrix([[1, 1], [1, 1]]) y = csr_matrix([[1, 2], [3, 4]]) + self.assertTrue(isinstance(unp.rmatmul(x, y), csr_matrix)) self.assertAllClose(csr_matrix.toarray(unp.rmatmul(x, y)), [[3, 3], [7, 7]]) def test_jax(self): @@ -45,6 +47,7 @@ def test_jax(self): x = jnp.array([[1, 1], [1, 1]]) y = jnp.array([[1, 2], [3, 4]]) + self.assertTrue(isinstance(unp.rmatmul(x, y), jnp.ndarray)) self.assertAllClose(unp.rmatmul(x, y), [[3, 3], [7, 7]]) except ImportError as err: raise unittest.SkipTest("Skipping jax tests.") from err @@ -56,6 +59,7 @@ def test_jax_sparse(self): x = BCOO.fromdense([[1, 1], [1, 1]]) y = BCOO.fromdense([[1, 2], [3, 4]]) + self.assertTrue(isinstance(unp.rmatmul(x, y), BCOO)) self.assertAllClose(BCOO.todense(unp.rmatmul(x, y)), [[3, 3], [7, 7]]) except ImportError as err: raise unittest.SkipTest("Skipping jax tests.") from err