def homothety_rotation_decomposition(m): r""" Return a couple composed of the homothety and a rotation matrix. The coefficients of the returned pair are either in the ground field of ``m`` or in the algebraic field ``AA``. EXAMPLES:: sage: from flatsurf.geometry.matrix_2x2 import homothety_rotation_decomposition sage: R.<x> = PolynomialRing(QQ) sage: K.<sqrt2> = NumberField(x^2 - 2, embedding=1.4142) sage: m = matrix([[sqrt2, -sqrt2],[sqrt2,sqrt2]]) sage: a,rot = homothety_rotation_decomposition(m) sage: a 2 sage: rot [ 1/2*sqrt2 -1/2*sqrt2] [ 1/2*sqrt2 1/2*sqrt2] """ if not is_similarity(m): raise ValueError("the matrix must be a similarity") det = m.det() if not det.is_square(): if not AA.has_coerce_map_from(m.base_ring()): l = map(number_field_to_AA, m.list()) M = MatrixSpace(AA, 2) m = M(l) else: m = m.change_ring(AA) sqrt_det = det.sqrt() return sqrt_det, m / sqrt_det
def homothety_rotation_decomposition(m): r""" Return a couple composed of the homothety and a rotation matrix. The coefficients of the returned pair are either in the ground field of ``m`` or in the algebraic field ``AA``. EXAMPLES:: sage: from flatsurf.geometry.matrix_2x2 import homothety_rotation_decomposition sage: R.<x> = PolynomialRing(QQ) sage: K.<sqrt2> = NumberField(x^2 - 2, embedding=1.4142) sage: m = matrix([[sqrt2, -sqrt2],[sqrt2,sqrt2]]) sage: a,rot = homothety_rotation_decomposition(m) sage: a 2 sage: rot [ 1/2*sqrt2 -1/2*sqrt2] [ 1/2*sqrt2 1/2*sqrt2] """ if not is_similarity(m): raise ValueError("the matrix must be a similarity") det = m.det() if not det.is_square(): if not AA.has_coerce_map_from(m.base_ring()): l = map(number_field_to_AA,m.list()) M = MatrixSpace(AA,2) m = M(l) else: m = m.change_ring(AA) sqrt_det = det.sqrt() return sqrt_det, m / sqrt_det
def _coerce_map_from_(self, P): r""" Return whether ``P`` coerces into this symbolic subring. INPUT: - ``P`` -- a parent. OUTPUT: A boolean or ``None``. TESTS:: sage: from sage.symbolic.subring import GenericSymbolicSubring sage: GenericSymbolicSubring(vars=tuple()).has_coerce_map_from(SR) # indirect doctest # not tested see #19231 False :: sage: from sage.symbolic.subring import SymbolicSubring sage: C = SymbolicSubring(no_variables=True) sage: C.has_coerce_map_from(ZZ) # indirect doctest True sage: C.has_coerce_map_from(QQ) # indirect doctest True sage: C.has_coerce_map_from(RR) # indirect doctest True sage: C.has_coerce_map_from(RIF) # indirect doctest True sage: C.has_coerce_map_from(CC) # indirect doctest True sage: C.has_coerce_map_from(CIF) # indirect doctest True sage: C.has_coerce_map_from(AA) # indirect doctest True sage: C.has_coerce_map_from(QQbar) # indirect doctest True sage: C.has_coerce_map_from(SR) # indirect doctest False """ if P == SR: # Workaround; can be deleted once #19231 is fixed return False from sage.rings.real_mpfr import mpfr_prec_min from sage.rings.all import (ComplexField, RLF, CLF, AA, QQbar, InfinityRing) from sage.rings.real_mpfi import is_RealIntervalField from sage.rings.complex_interval_field import is_ComplexIntervalField if isinstance(P, type): return SR._coerce_map_from_(P) elif RLF.has_coerce_map_from(P) or \ CLF.has_coerce_map_from(P) or \ AA.has_coerce_map_from(P) or \ QQbar.has_coerce_map_from(P): return True elif (P is InfinityRing or is_RealIntervalField(P) or is_ComplexIntervalField(P)): return True elif ComplexField(mpfr_prec_min()).has_coerce_map_from(P): return P not in (RLF, CLF, AA, QQbar)