From ccb8a87938fbc29ecdca73b3c9781e84da6afd04 Mon Sep 17 00:00:00 2001 From: Doug Strain Date: Mon, 13 May 2024 18:36:11 -0700 Subject: [PATCH 1/2] Suppress superfluous warnings from numpy - On MacOS, with numpy ~1.26, np.linalg.det gives spurious warnings when passed a complex array. - Suppress these warnings, as they are just annoying and do not signify anything. --- cirq-core/cirq/linalg/decompositions.py | 24 ++++++++++++------- cirq-core/cirq/linalg/diagonalize.py | 9 +++---- cirq-core/cirq/linalg/predicates.py | 14 ++++++----- cirq-core/cirq/linalg/transformations.py | 3 ++- cirq-core/cirq/testing/lin_alg_utils.py | 8 ++++--- .../controlled_gate_decomposition.py | 4 +++- 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/cirq-core/cirq/linalg/decompositions.py b/cirq-core/cirq/linalg/decompositions.py index 82bc5e3b876..1bbd4f0b6e4 100644 --- a/cirq-core/cirq/linalg/decompositions.py +++ b/cirq-core/cirq/linalg/decompositions.py @@ -222,8 +222,9 @@ def kron_factor_4x4_to_2x2s(matrix: np.ndarray) -> Tuple[complex, np.ndarray, np f2[(a & 1) ^ i, (b & 1) ^ j] = matrix[a ^ i, b ^ j] # Rescale factors to have unit determinants. - f1 /= np.sqrt(np.linalg.det(f1)) or 1 - f2 /= np.sqrt(np.linalg.det(f2)) or 1 + with np.errstate(divide="ignore", invalid="ignore"): + f1 /= np.sqrt(np.linalg.det(f1)) or 1 + f2 /= np.sqrt(np.linalg.det(f2)) or 1 # Determine global phase. g = matrix[a, b] / (f1[a >> 1, b >> 1] * f2[a & 1, b & 1]) @@ -451,14 +452,18 @@ def __init__( single_qubit_operations_after: a0, a1 from the above equation. """ self.global_phase: complex = global_phase - self.single_qubit_operations_before: Tuple[np.ndarray, np.ndarray] = ( - single_qubit_operations_before - or (np.eye(2, dtype=np.complex64), np.eye(2, dtype=np.complex64)) + self.single_qubit_operations_before: Tuple[ + np.ndarray, np.ndarray + ] = single_qubit_operations_before or ( + np.eye(2, dtype=np.complex64), + np.eye(2, dtype=np.complex64), ) self.interaction_coefficients = interaction_coefficients - self.single_qubit_operations_after: Tuple[np.ndarray, np.ndarray] = ( - single_qubit_operations_after - or (np.eye(2, dtype=np.complex64), np.eye(2, dtype=np.complex64)) + self.single_qubit_operations_after: Tuple[ + np.ndarray, np.ndarray + ] = single_qubit_operations_after or ( + np.eye(2, dtype=np.complex64), + np.eye(2, dtype=np.complex64), ) def _value_equality_values_(self) -> Any: @@ -965,7 +970,8 @@ def kak_vector( # The algorithm in the appendix mentioned above is slightly incorrect in # that it only works for elements of SU(4). A phase correction must be # added to deal with U(4). - phases = np.log(-1j * np.linalg.det(unitary)).imag + np.pi / 2 + with np.errstate(divide="ignore", invalid="ignore"): + phases = np.log(-1j * np.linalg.det(unitary)).imag + np.pi / 2 evals *= np.exp(-1j * phases / 2)[..., np.newaxis] # The following steps follow the appendix exactly. diff --git a/cirq-core/cirq/linalg/diagonalize.py b/cirq-core/cirq/linalg/diagonalize.py index 96bf52fe860..959e92b3edc 100644 --- a/cirq-core/cirq/linalg/diagonalize.py +++ b/cirq-core/cirq/linalg/diagonalize.py @@ -255,10 +255,11 @@ def bidiagonalize_unitary_with_special_orthogonals( ) # Convert to special orthogonal w/o breaking diagonalization. - if np.linalg.det(left) < 0: - left[0, :] *= -1 - if np.linalg.det(right) < 0: - right[:, 0] *= -1 + with np.errstate(divide="ignore", invalid="ignore"): + if np.linalg.det(left) < 0: + left[0, :] *= -1 + if np.linalg.det(right) < 0: + right[:, 0] *= -1 diag = combinators.dot(left, mat, right) diff --git a/cirq-core/cirq/linalg/predicates.py b/cirq-core/cirq/linalg/predicates.py index bbfba50eddf..f0a25f5958a 100644 --- a/cirq-core/cirq/linalg/predicates.py +++ b/cirq-core/cirq/linalg/predicates.py @@ -91,9 +91,10 @@ def is_special_orthogonal(matrix: np.ndarray, *, rtol: float = 1e-5, atol: float Returns: Whether the matrix is special orthogonal within the given tolerance. """ - return is_orthogonal(matrix, rtol=rtol, atol=atol) and ( - matrix.shape[0] == 0 or np.allclose(np.linalg.det(matrix), 1, rtol=rtol, atol=atol) - ) + with np.errstate(divide="ignore", invalid="ignore"): + return is_orthogonal(matrix, rtol=rtol, atol=atol) and ( + matrix.shape[0] == 0 or np.allclose(np.linalg.det(matrix), 1, rtol=rtol, atol=atol) + ) def is_unitary(matrix: np.ndarray, *, rtol: float = 1e-5, atol: float = 1e-8) -> bool: @@ -128,9 +129,10 @@ def is_special_unitary(matrix: np.ndarray, *, rtol: float = 1e-5, atol: float = Whether the matrix is unitary with unit determinant within the given tolerance. """ - return is_unitary(matrix, rtol=rtol, atol=atol) and ( - matrix.shape[0] == 0 or np.allclose(np.linalg.det(matrix), 1, rtol=rtol, atol=atol) - ) + with np.errstate(divide="ignore", invalid="ignore"): + return is_unitary(matrix, rtol=rtol, atol=atol) and ( + matrix.shape[0] == 0 or np.allclose(np.linalg.det(matrix), 1, rtol=rtol, atol=atol) + ) def is_normal(matrix: np.ndarray, *, rtol: float = 1e-5, atol: float = 1e-8) -> bool: diff --git a/cirq-core/cirq/linalg/transformations.py b/cirq-core/cirq/linalg/transformations.py index 9a9f8942fdc..2ef730aaea2 100644 --- a/cirq-core/cirq/linalg/transformations.py +++ b/cirq-core/cirq/linalg/transformations.py @@ -592,7 +592,8 @@ def to_special(u: np.ndarray) -> np.ndarray: Returns: the special unitary matrix """ - return u * (np.linalg.det(u) ** (-1 / len(u))) + with np.errstate(divide="ignore", invalid="ignore"): + return u * (np.linalg.det(u) ** (-1 / len(u))) def state_vector_kronecker_product(t1: np.ndarray, t2: np.ndarray) -> np.ndarray: diff --git a/cirq-core/cirq/testing/lin_alg_utils.py b/cirq-core/cirq/testing/lin_alg_utils.py index f1228ecd011..ad005fd0e6d 100644 --- a/cirq-core/cirq/testing/lin_alg_utils.py +++ b/cirq-core/cirq/testing/lin_alg_utils.py @@ -133,7 +133,8 @@ def random_special_unitary( The sampled special unitary. """ r = random_unitary(dim, random_state=random_state) - r[0, :] /= np.linalg.det(r) + with np.errstate(divide="ignore", invalid="ignore"): + r[0, :] /= np.linalg.det(r) return r @@ -152,8 +153,9 @@ def random_special_orthogonal( The sampled special orthogonal matrix. """ m = random_orthogonal(dim, random_state=random_state) - if np.linalg.det(m) < 0: - m[0, :] *= -1 + with np.errstate(divide="ignore", invalid="ignore"): + if np.linalg.det(m) < 0: + m[0, :] *= -1 return m diff --git a/cirq-core/cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py b/cirq-core/cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py index af01e926499..64ec15dafe3 100644 --- a/cirq-core/cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +++ b/cirq-core/cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py @@ -47,7 +47,9 @@ def _decompose_abc(matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarr See [1], chapter 4. """ assert matrix.shape == (2, 2) - delta = np.angle(np.linalg.det(matrix)) * 0.5 + with np.errstate(divide="ignore", invalid="ignore"): + # On MacOS, np.linalg.det emits superflous warnings + delta = np.angle(np.linalg.det(matrix)) * 0.5 alpha = np.angle(matrix[0, 0]) + np.angle(matrix[0, 1]) - 2 * delta beta = np.angle(matrix[0, 0]) - np.angle(matrix[0, 1]) From 3905278826bb5732c32d9f21ccedccda0a052fe1 Mon Sep 17 00:00:00 2001 From: Doug Strain Date: Mon, 13 May 2024 18:40:45 -0700 Subject: [PATCH 2/2] Wrong black version. --- cirq-core/cirq/linalg/decompositions.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cirq-core/cirq/linalg/decompositions.py b/cirq-core/cirq/linalg/decompositions.py index 1bbd4f0b6e4..5c51cd79698 100644 --- a/cirq-core/cirq/linalg/decompositions.py +++ b/cirq-core/cirq/linalg/decompositions.py @@ -452,18 +452,14 @@ def __init__( single_qubit_operations_after: a0, a1 from the above equation. """ self.global_phase: complex = global_phase - self.single_qubit_operations_before: Tuple[ - np.ndarray, np.ndarray - ] = single_qubit_operations_before or ( - np.eye(2, dtype=np.complex64), - np.eye(2, dtype=np.complex64), + self.single_qubit_operations_before: Tuple[np.ndarray, np.ndarray] = ( + single_qubit_operations_before + or (np.eye(2, dtype=np.complex64), np.eye(2, dtype=np.complex64)) ) self.interaction_coefficients = interaction_coefficients - self.single_qubit_operations_after: Tuple[ - np.ndarray, np.ndarray - ] = single_qubit_operations_after or ( - np.eye(2, dtype=np.complex64), - np.eye(2, dtype=np.complex64), + self.single_qubit_operations_after: Tuple[np.ndarray, np.ndarray] = ( + single_qubit_operations_after + or (np.eye(2, dtype=np.complex64), np.eye(2, dtype=np.complex64)) ) def _value_equality_values_(self) -> Any: