From e44e92f020dfe968f2b4ef9cc4d74ffafc17f843 Mon Sep 17 00:00:00 2001 From: JerryChen97 Date: Tue, 18 Feb 2025 16:39:35 -0500 Subject: [PATCH 1/4] Add a helper in math/quantum to calculate --- pennylane/math/quantum.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pennylane/math/quantum.py b/pennylane/math/quantum.py index b879f224871..98f95834353 100644 --- a/pennylane/math/quantum.py +++ b/pennylane/math/quantum.py @@ -20,6 +20,7 @@ from autoray import numpy as np from numpy import float64 # pylint:disable=wrong-import-order +from scipy.sparse import issparse import pennylane as qml @@ -972,6 +973,24 @@ def sqrt_matrix(density_matrix): return vecs @ qml.math.diag(qml.math.sqrt(evs)) @ qml.math.conj(qml.math.transpose(vecs)) +def sqrt_matrix_sparse(density_matrix): + r"""Compute the square root matrix of a sparse density matrix where :math:`\rho = \sqrt{\rho} \times \sqrt{\rho}` + + Args: + density_matrix (sparse): 2D sparse density matrix of the quantum system. + + Returns: + (sparse): Square root of the density matrix. Even thought type as `csr_matrix` or `csc_matrix`, the output is not guaranteed to be sparse as well. + """ + if not issparse(density_matrix): + raise TypeError("Only use this method for sparse matrices, or there will be an inevitable performance hit and divergence risk.") + return _denman_beavers_iterations(mat, max_iter=100, tol=1e-10) + + +def _denman_beavers_iterations(mat, max_iter=100, tol=1e-10): + pass + + def _compute_relative_entropy(rho, sigma, base=None): r""" Compute the quantum relative entropy of density matrix rho with respect to sigma. From 7b2a6e157b9f80ff48faa3977bc152865c5b0bd7 Mon Sep 17 00:00:00 2001 From: JerryChen97 Date: Tue, 18 Feb 2025 17:14:15 -0500 Subject: [PATCH 2/4] attache concrete algorithm --- pennylane/math/quantum.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pennylane/math/quantum.py b/pennylane/math/quantum.py index 98f95834353..1f398690fac 100644 --- a/pennylane/math/quantum.py +++ b/pennylane/math/quantum.py @@ -18,9 +18,11 @@ import itertools from string import ascii_letters as ABC +import scipy as sp +import scipy.sparse.linalg as spla from autoray import numpy as np from numpy import float64 # pylint:disable=wrong-import-order -from scipy.sparse import issparse +from scipy.sparse import csc_matrix, issparse import pennylane as qml @@ -983,12 +985,26 @@ def sqrt_matrix_sparse(density_matrix): (sparse): Square root of the density matrix. Even thought type as `csr_matrix` or `csc_matrix`, the output is not guaranteed to be sparse as well. """ if not issparse(density_matrix): - raise TypeError("Only use this method for sparse matrices, or there will be an inevitable performance hit and divergence risk.") - return _denman_beavers_iterations(mat, max_iter=100, tol=1e-10) + raise TypeError( + "Only use this method for sparse matrices, or there will be an inevitable performance hit and divergence risk." + ) + return _denman_beavers_iterations(density_matrix, max_iter=100, tol=1e-10) def _denman_beavers_iterations(mat, max_iter=100, tol=1e-10): - pass + Ynew = sp.sparse.csc_matrix(mat) + Znew = sp.sparse.eye(mat.shape[0]).tocsc() + for _ in range(max_iter): + Y = Ynew + Z = Znew + # TODO: implement the tol control logic + # basic idea: check norm_diff every 10 iter. If norm_diff < tol, break + Ynew = 0.5 * (Y + spla.inv(Z)) + Znew = 0.5 * (Z + spla.inv(Y)) + + X = spla.inv(Z) + B = Znew + return 2 * X - X @ B @ X def _compute_relative_entropy(rho, sigma, base=None): From e81b3284c41aad1a7424b40694acb2e3262bee75 Mon Sep 17 00:00:00 2001 From: "Yushao Chen (Jerry)" Date: Tue, 18 Feb 2025 17:28:06 -0500 Subject: [PATCH 3/4] Update pennylane/math/quantum.py --- pennylane/math/quantum.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pennylane/math/quantum.py b/pennylane/math/quantum.py index 1f398690fac..16528ea15db 100644 --- a/pennylane/math/quantum.py +++ b/pennylane/math/quantum.py @@ -992,7 +992,9 @@ def sqrt_matrix_sparse(density_matrix): def _denman_beavers_iterations(mat, max_iter=100, tol=1e-10): - Ynew = sp.sparse.csc_matrix(mat) + mat = csc_matrix(mat) + Ynew = mat + Znew = sp.sparse.eye(mat.shape[0]).tocsc() for _ in range(max_iter): Y = Ynew From d699dc7e406df40f9b6ff2ec83d05bc484d2a0d8 Mon Sep 17 00:00:00 2001 From: "Yushao Chen (Jerry)" Date: Tue, 18 Feb 2025 17:29:50 -0500 Subject: [PATCH 4/4] Update pennylane/math/quantum.py --- pennylane/math/quantum.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pennylane/math/quantum.py b/pennylane/math/quantum.py index 16528ea15db..ec27bed9d94 100644 --- a/pennylane/math/quantum.py +++ b/pennylane/math/quantum.py @@ -1001,8 +1001,10 @@ def _denman_beavers_iterations(mat, max_iter=100, tol=1e-10): Z = Znew # TODO: implement the tol control logic # basic idea: check norm_diff every 10 iter. If norm_diff < tol, break - Ynew = 0.5 * (Y + spla.inv(Z)) - Znew = 0.5 * (Z + spla.inv(Y)) + Ynew = 0.5 * (Y + spla.inv(Z)) + Znew = 0.5 * (Z + spla.inv(Y)) + # TODO: common error catch to be here -- failure of spla.inv + X = spla.inv(Z) B = Znew