Path: blob/master/src/sage/geometry/hyperplane_arrangement/affine_subspace.py
8817 views
"""1Affine Subspaces of a Vector Space23An affine subspace of a vector space is a translation of a linear4subspace. The affine subspaces here are only used internally in5hyperplane arrangements. You should not use them for interactive work6or return them to the user.78EXAMPLES::910sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace11sage: a = AffineSubspace([1,0,0,0], QQ^4)12sage: a.dimension()13414sage: a.point()15(1, 0, 0, 0)16sage: a.linear_part()17Vector space of dimension 4 over Rational Field18sage: a19Affine space p + W where:20p = (1, 0, 0, 0)21W = Vector space of dimension 4 over Rational Field22sage: b = AffineSubspace((1,0,0,0), matrix(QQ, [[1,2,3,4]]).right_kernel())23sage: c = AffineSubspace((0,2,0,0), matrix(QQ, [[0,0,1,2]]).right_kernel())24sage: b.intersection(c)25Affine space p + W where:26p = (-3, 2, 0, 0)27W = Vector space of degree 4 and dimension 2 over Rational Field28Basis matrix:29[ 1 0 -1 1/2]30[ 0 1 -2 1]31sage: b < a32True33sage: c < b34False35sage: A = AffineSubspace([8,38,21,250], VectorSpace(GF(19),4))36sage: A37Affine space p + W where:38p = (8, 0, 2, 3)39W = Vector space of dimension 4 over Finite Field of size 194041TESTS::4243sage: A = AffineSubspace([2], VectorSpace(QQ, 1))44sage: A.point()45(2)46sage: A.linear_part()47Vector space of dimension 1 over Rational Field48sage: A.linear_part().basis_matrix()49[1]50sage: A = AffineSubspace([], VectorSpace(QQ, 0))51sage: A.point()52()53sage: A.linear_part()54Vector space of dimension 0 over Rational Field55sage: A.linear_part().basis_matrix()56[]57"""5859#*****************************************************************************60# Copyright (C) 2013 David Perkinson <[email protected]>61# Volker Braun <[email protected]>62#63# Distributed under the terms of the GNU General Public License (GPL)64# as published by the Free Software Foundation; either version 2 of65# the License, or (at your option) any later version.66# http://www.gnu.org/licenses/67#*****************************************************************************6869from sage.structure.sage_object import SageObject70from sage.matrix.constructor import vector717273class AffineSubspace(SageObject):74"""75An affine subspace.7677INPUT:7879- ``p`` -- list/tuple/iterable representing a point on the80affine space8182- ``V`` -- vector subspace8384OUTPUT:8586Affine subspace parallel to ``V`` and passing through ``p``.8788EXAMPLES::8990sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace91sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))92sage: a93Affine space p + W where:94p = (1, 0, 0, 0)95W = Vector space of dimension 4 over Rational Field96"""97def __init__(self, p, V):98r"""99Construct an :class:`AffineSubspace`.100101TESTS::102103sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace104sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))105sage: TestSuite(a).run()106sage: AffineSubspace(0, VectorSpace(QQ,4)).point()107(0, 0, 0, 0)108"""109R = V.base_ring()110from sage.categories.all import Fields111if R not in Fields():112R = R.fraction_field()113V = V.change_ring(R)114self._base_ring = R115self._linear_part = V116p = V.ambient_vector_space()(p)117p.set_immutable()118self._point = p119120def __hash__(self):121"""122Return a hash value.123124EXAMPLES::125126sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace127sage: a = AffineSubspace([1,0,0,0], VectorSpace(QQ,4))128sage: a.__hash__() # random output129-3713096828371451969130"""131# note that the point is not canonically chosen, but the linear part is132return hash(self._linear_part)133134def _repr_(self):135r"""136String representation for an :class:`AffineSubspace`.137138OUTPUT:139140A string.141142EXAMPLES::143144sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace145sage: a = AffineSubspace([1,0,0,0],VectorSpace(QQ,4))146sage: a147Affine space p + W where:148p = (1, 0, 0, 0)149W = Vector space of dimension 4 over Rational Field150"""151return "Affine space p + W where:\n p = "+str(self._point)+"\n W = "+str(self._linear_part)152153def __eq__(self, other):154r"""155Test whether ``self`` is equal to ``other``.156157INPUT:158159- ``other`` -- an :class:`AffineSubspace`160161OUTPUT:162163A boolean.164165EXAMPLES::166167sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace168sage: a = AffineSubspace([1,0,0], matrix([[1,0,0]]).right_kernel())169sage: b = AffineSubspace([2,0,0], matrix([[1,0,0]]).right_kernel())170sage: c = AffineSubspace([1,1,0], matrix([[1,0,0]]).right_kernel())171sage: a == b172False173sage: a == c174True175"""176V = self._linear_part177W = other._linear_part178return V == W and self._point - other._point in V179180def __ne__(self, other):181r"""182Test whether ``self`` is not equal to ``other``.183184INPUT:185186- ``other`` -- an :class:`AffineSubspace`187188OUTPUT:189190A boolean.191192EXAMPLES::193194sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace195sage: a = AffineSubspace([1,0,0],matrix([[1,0,0]]).right_kernel())196sage: b = AffineSubspace([2,0,0],matrix([[1,0,0]]).right_kernel())197sage: a == b198False199sage: a != b200True201sage: a != a202False203"""204return not self == other205206def __le__(self, other):207r"""208Test whether ``self`` is an affine subspace of ``other``.209210INPUT:211212- ``other`` -- an :class:`AffineSubspace`213214OUTPUT:215216A boolean.217218EXAMPLES::219220sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace221sage: V = VectorSpace(QQ, 3)222sage: W1 = V.subspace([[1,0,0],[0,1,0]])223sage: W2 = V.subspace([[1,0,0]])224sage: a = AffineSubspace([1,2,3], W1)225sage: b = AffineSubspace([1,2,3], W2)226sage: a <= b227False228sage: a <= a229True230sage: b <= a231True232"""233V = self._linear_part234W = other._linear_part235return V.is_subspace(W) and self._point-other._point in W236237def __lt__(self, other):238r"""239Test whether ``self`` is a proper affine subspace of ``other``.240241INPUT:242243- ``other`` -- an :class:`AffineSubspace`244245OUTPUT:246247A boolean.248249EXAMPLES::250251sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace252sage: V = VectorSpace(QQ, 3)253sage: W1 = V.subspace([[1,0,0], [0,1,0]])254sage: W2 = V.subspace([[1,0,0]])255sage: a = AffineSubspace([1,2,3], W1)256sage: b = AffineSubspace([1,2,3], W2)257sage: a < b258False259sage: a < a260False261sage: b < a262True263"""264if self._linear_part == other._linear_part:265return False266return self.__le__(other)267268def __contains__(self, q):269r"""270Test whether the point ``q`` is in the affine space.271272INPUT:273274- ``q`` -- point as a list/tuple/iterable275276OUTPUT:277278A boolean.279280EXAMPLES::281282sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace283sage: a = AffineSubspace([1,0,0], matrix([[1,0,0]]).right_kernel())284sage: (1,1,0) in a285True286sage: (0,0,0) in a287False288"""289q = vector(self._base_ring, q)290return self._point - q in self._linear_part291292def linear_part(self):293r"""294Return the linear part of the affine space.295296OUTPUT:297298A vector subspace of the ambient space.299300EXAMPLES::301302sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace303sage: A = AffineSubspace([2,3,1], matrix(QQ, [[1,2,3]]).right_kernel())304sage: A.linear_part()305Vector space of degree 3 and dimension 2 over Rational Field306Basis matrix:307[ 1 0 -1/3]308[ 0 1 -2/3]309sage: A.linear_part().ambient_vector_space()310Vector space of dimension 3 over Rational Field311"""312return self._linear_part313314def point(self):315r"""316Return a point ``p`` in the affine space.317318OUTPUT:319320A point of the affine space as a vector in the ambient space.321322EXAMPLES::323324sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace325sage: A = AffineSubspace([2,3,1], VectorSpace(QQ,3))326sage: A.point()327(2, 3, 1)328"""329return self._point330331def dimension(self):332r"""333Return the dimension of the affine space.334335OUTPUT:336337An integer.338339EXAMPLES::340341sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace342sage: a = AffineSubspace([1,0,0,0],VectorSpace(QQ,4))343sage: a.dimension()3444345"""346return self.linear_part().dimension()347348def intersection(self, other):349r"""350Return the intersection of ``self`` with ``other``.351352INPUT:353354- ``other`` -- an :class:`AffineSubspace`355356OUTPUT:357358A new affine subspace, (or ``None`` if the intersection is359empty).360361EXAMPLES::362363sage: from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace364sage: V = VectorSpace(QQ,3)365sage: U = V.subspace([(1,0,0), (0,1,0)])366sage: W = V.subspace([(0,1,0), (0,0,1)])367sage: A = AffineSubspace((0,0,0), U)368sage: B = AffineSubspace((1,1,1), W)369sage: A.intersection(B)370Affine space p + W where:371p = (1, 1, 0)372W = Vector space of degree 3 and dimension 1 over Rational Field373Basis matrix:374[0 1 0]375sage: C = AffineSubspace((0,0,1), U)376sage: A.intersection(C)377sage: C = AffineSubspace((7,8,9), U.complement())378sage: A.intersection(C)379Affine space p + W where:380p = (7, 8, 0)381W = Vector space of degree 3 and dimension 0 over Rational Field382Basis matrix:383[]384sage: A.intersection(C).intersection(B)385386sage: D = AffineSubspace([1,2,3], VectorSpace(GF(5),3))387sage: E = AffineSubspace([3,4,5], VectorSpace(GF(5),3))388sage: D.intersection(E)389Affine space p + W where:390p = (3, 4, 0)391W = Vector space of dimension 3 over Finite Field of size 5392"""393if self.linear_part().ambient_vector_space() != \394other.linear_part().ambient_vector_space():395raise ValueError('incompatible ambient vector spaces')396m = self.linear_part().matrix()397n = other.linear_part().matrix()398p = self.point()399q = other.point()400M = m.stack(n)401v = q - p402try:403t = M.solve_left(v)404except ValueError:405return None # empty intersection406new_p = p + t[:m.nrows()]*m407new_V = self.linear_part().intersection(other._linear_part)408return AffineSubspace(new_p, new_V)409410411412