From d8018de3b38b683f5207f536ca2e7d374d0f5c7a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 26 Nov 2024 13:33:41 -0500 Subject: [PATCH] mjo/eja/eja_operator.py: add is_isometry() method --- mjo/eja/eja_operator.py | 91 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/mjo/eja/eja_operator.py b/mjo/eja/eja_operator.py index 689b7ec..4c1d60d 100644 --- a/mjo/eja/eja_operator.py +++ b/mjo/eja/eja_operator.py @@ -572,6 +572,97 @@ class EJAOperator(Map): return self.matrix().is_invertible() + def is_isometry(self): + r""" + Return whether or not this operator is an isometry. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA, + ....: HadamardEJA, + ....: JordanSpinEJA, + ....: RealSymmetricEJA, + ....: TrivialEJA, + ....: random_eja) + sage: from mjo.eja.eja_operator import EJAOperator + sage: from mjo.random import random_unitary_matrix + + EXAMPLES: + + The easiest way to construct an isometry is to send an + orthonormal basis in one algebra to an orthonormal basis in + another:: + + sage: J1 = RealSymmetricEJA(2) + sage: J2 = JordanSpinEJA(3, prefix='c') + sage: M = matrix.identity(J1.base_ring(), 3) + sage: L = EJAOperator(J1,J2,M) + sage: [ [bi.inner_product(bj) for bi in J1.basis()] + ....: for bj in J1.basis() ] + [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + sage: [ [ci.inner_product(cj) for ci in J2.basis()] + ....: for cj in J2.basis() ] + [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + sage: [ L(b) for b in J1.basis() ] + [c0, c1, c2] + sage: L.is_isometry() + True + + But if you have orthonormal bases on both sides, of course you + could use any orthogonal matrix:: + + sage: J1 = ComplexHermitianEJA(2) + sage: J2 = JordanSpinEJA(4) + sage: M = random_unitary_matrix(J1.base_ring(), J1.dimension()) + sage: L = EJAOperator(J1,J2,M) + sage: L.is_isometry() + True + + The zero operator is an isometry in a trivial algebra:: + + sage: J = TrivialEJA() + sage: J.zero().operator().is_isometry() + True + + A "famous" non-isometry is to transpose the factors of a + cartesian product of two one-dimensional spin algebras where + the inner product on one factor is twice the inner product on + the other. This is given as a counterexample in Section III.5 + of Faraut & Koranyi:: + + sage: J1 = HadamardEJA(1) + sage: J2 = HadamardEJA(1, prefix='c') + sage: J2._inner_product_matrix = 2*J1._inner_product_matrix + sage: J = cartesian_product([J1,J2]) + sage: M = matrix(J1.base_ring(), [[0,1],[1,0]]) + sage: L = EJAOperator(J,J,M) + sage: L.is_isometry() + False + + TESTS: + + The identity operator is always an isometry:: + + sage: J = random_eja() + sage: J.one().operator().is_isometry() + True + + The zero operator is never an isometry in a nontrivial algebra:: + + sage: J = random_eja() + sage: not J.is_trivial() and J.zero().operator().is_isometry() + False + + """ + # The basis may not be orthonormalized, so just having an + # orthogonal matrix is not sufficient to determine isometry. + return all( + b1.inner_product(b2) == self(b1).inner_product(self(b2)) + for b1 in self.domain().basis() + for b2 in self.domain().basis() + ) + + def matrix(self): """ Return the matrix representation of this operator with respect -- 2.49.0