Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Formal sums
AUTHORS:
- David Harvey (2006-09-20): changed FormalSum not to derive from "list" anymore, because that breaks new Element interface
- Nick Alexander (2006-12-06): added test cases.
- William Stein (2006, 2009): wrote the first version in 2006, documented it in 2009.
- Volker Braun (2010-07-19): new-style coercions, documentation added. FormalSums now derives from UniqueRepresentation.
FUNCTIONS: - ``FormalSums(ring)`` -- create the module of formal finite sums with coefficients in the given ring.
- ``FormalSum(list of pairs (coeff, number))`` -- create a formal sum
EXAMPLES::
sage: A = FormalSum([(1, 2/3)]); A 2/3 sage: B = FormalSum([(3, 1/5)]); B 3*1/5 sage: -B -3*1/5 sage: A + B 3*1/5 + 2/3 sage: A - B -3*1/5 + 2/3 sage: B*3 9*1/5 sage: 2*A 2*2/3 sage: list(2*A + A) [(3, 2/3)]
TESTS::
sage: R = FormalSums(QQ) sage: loads(dumps(R)) == R True sage: a = R(2/3) + R(-5/7); a -5/7 + 2/3 sage: loads(dumps(a)) == a True """
#***************************************************************************** # Copyright (C) 2004 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function
import sage.misc.misc import operator import sage.misc.latex
from sage.modules.module import Module from sage.structure.element import ModuleElement from sage.structure.richcmp import richcmp from sage.rings.integer_ring import ZZ from sage.structure.parent import Parent from sage.structure.coerce import LeftModuleAction, RightModuleAction from sage.categories.action import PrecomposedAction from sage.structure.unique_representation import UniqueRepresentation
class FormalSum(ModuleElement): """ A formal sum over a ring. """ def __init__(self, x, parent=None, check=True, reduce=True): """ INPUT: - ``x`` -- object - ``parent`` -- FormalSums(R) module (default: FormalSums(ZZ)) - ``check`` -- bool (default: True) if False, might not coerce coefficients into base ring, which can speed up constructing a formal sum. - ``reduce`` -- reduce (default: True) if False, do not combine common terms
EXAMPLES::
sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)]) 4*2/3 - 5*7 sage: a = FormalSum([(1,2/3), (3,2/3), (-5, 7)], reduce=False); a 2/3 + 3*2/3 - 5*7 sage: a.reduce() sage: a 4*2/3 - 5*7 sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5))) 4*2/3
Notice below that the coefficient 5 doesn't get reduced modulo 5::
sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) 4*2/3 - 5*7
Make sure we first reduce before checking coefficient types::
sage: x,y = var('x, y') sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) 1/2*x + 2*y sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) x + 2*y """ raise TypeError("%s\nInvalid formal sum"%msg)
def __iter__(self): """ EXAMPLES::
sage: for z in FormalSum([(1,2), (5, 1000), (-3, 7)]): print(z) (1, 2) (-3, 7) (5, 1000) """
def __getitem__(self, n): """ EXAMPLES::
sage: v = FormalSum([(1,2), (5, 1000), (-3, 7)]); v 2 - 3*7 + 5*1000 sage: v[0] (1, 2) sage: v[1] (-3, 7) sage: v[2] (5, 1000) sage: list(v) [(1, 2), (-3, 7), (5, 1000)] """
def __len__(self): """ EXAMPLES::
sage: v = FormalSum([(1,2), (5, 1000), (-3, 7)]); v 2 - 3*7 + 5*1000 sage: len(v) 3 """
def _repr_(self): """ EXAMPLES::
sage: a = FormalSum([(1,2/3), (-3,4/5), (7,Mod(2,3))]) sage: a # random, since comparing Mod(2,3) and rationals ill-defined sage: a._repr_() # random '2/3 - 3*4/5 + 7*2' """
def _latex_(self): """ EXAMPLES::
sage: latex(FormalSum([(1,2), (5, 8/9), (-3, 7)])) 5\cdot \frac{8}{9} + 2 - 3\cdot 7 """ # TODO: finish merging sage.misc.latex.repr_lincomb and # sage.misc.misc.repr_lincomb and use instead: # return sage.misc.misc.repr_lincomb([[t,c] for c,t in self], is_latex=True)
def _richcmp_(left, right, op): """ Compare ``left`` and ``right``.
INPUT:
- ``right`` -- a :class:`FormalSum` with the same parent
- ``op`` -- a comparison operator
EXAMPLES::
sage: a = FormalSum([(1,3),(2,5)]); a 3 + 2*5 sage: b = FormalSum([(1,3),(2,7)]); b 3 + 2*7 sage: a != b True sage: a_QQ = FormalSum([(1,3),(2,5)],parent=FormalSums(QQ)) sage: a == a_QQ # a is coerced into FormalSums(QQ) True sage: a == 0 # 0 is coerced into a.parent()(0) False """
def _neg_(self): """ EXAMPLES::
sage: -FormalSum([(1,3),(2,5)]) -3 - 2*5 """
def _add_(self, other): """ EXAMPLES::
sage: FormalSum([(1,3/7),(2,5/8)]) + FormalSum([(1,3/7),(-2,5)]) # indirect doctest 2*3/7 + 2*5/8 - 2*5 """
def _lmul_(self, s): """ EXAMPLES::
sage: FormalSum([(1,3/7),(-2,5)])*(-3) -3*3/7 + 6*5 """
def _rmul_(self, s): """ EXAMPLES::
sage: -3*FormalSum([(1,3/7),(-2,5)]) -3*3/7 + 6*5 """
def __bool__(self): """ EXAMPLES::
sage: bool(FormalSum([(1,3/7),(-2,5)])) True sage: bool(FormalSums(QQ)(0)) False sage: bool(FormalSums(QQ)(1)) True """ return False
__nonzero__ = __bool__
def reduce(self): """ EXAMPLES::
sage: a = FormalSum([(-2,3), (2,3)], reduce=False); a -2*3 + 2*3 sage: a.reduce() sage: a 0 """ else:
class FormalSums(UniqueRepresentation, Module): """ The R-module of finite formal sums with coefficients in some ring R.
EXAMPLES::
sage: FormalSums() Abelian Group of all Formal Finite Sums over Integer Ring sage: FormalSums(ZZ) Abelian Group of all Formal Finite Sums over Integer Ring sage: FormalSums(GF(7)) Abelian Group of all Formal Finite Sums over Finite Field of size 7 sage: FormalSums(ZZ[sqrt(2)]) Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 with defining polynomial x^2 - 2 sage: FormalSums(GF(9,'a')) Abelian Group of all Formal Finite Sums over Finite Field in a of size 3^2
TESTS::
sage: TestSuite(FormalSums(QQ)).run()
""" Element = FormalSum @staticmethod def __classcall__(cls, base_ring = ZZ): """ Set the default value for the base ring.
EXAMPLES::
sage: FormalSums(ZZ) == FormalSums() # indirect test True """
def _repr_(self): """ EXAMPLES::
sage: FormalSums(GF(7)) Abelian Group of all Formal Finite Sums over Finite Field of size 7 sage: FormalSums(GF(7))._repr_() 'Abelian Group of all Formal Finite Sums over Finite Field of size 7' """
def _element_constructor_(self, x, check=True, reduce=True): """ Make a formal sum in self from x.
INPUT:
- ``x`` -- formal sum, list or number
- ``check`` -- bool (default: True)
- ``reduce`` -- bool (default: True); whether to combine terms
EXAMPLES::
sage: P = FormalSum([(1,2/3)]).parent() sage: P([(1,2/3), (5,-2/9)]) # indirect test 5*-2/9 + 2/3 """ return x else: else:
def _coerce_map_from_(self, X): r""" Return whether there is a coercion from ``X``
EXAMPLES::
sage: FormalSums(QQ).has_coerce_map_from( FormalSums(ZZ) ) # indirect test True
sage: FormalSums(ZZ).get_action(QQ) # indirect test Right scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field with precomposition on left by Coercion map: From: Abelian Group of all Formal Finite Sums over Integer Ring To: Abelian Group of all Formal Finite Sums over Rational Field """
def base_extend(self, R): """ EXAMPLES::
sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 Abelian Group of all Formal Finite Sums over Finite Field of size 7
The following tests against a bug that was fixed at :trac:`18795`::
sage: isinstance(F7, F7.category().parent_class) True """
def _get_action_(self, other, op, self_is_left): """ EXAMPLES::
sage: A = FormalSums(RR); A.get_action(RR) # indirect doctest Right scalar multiplication by Real Field with 53 bits of precision on Abelian Group of all Formal Finite Sums over Real Field with 53 bits of precision
sage: A = FormalSums(ZZ); A.get_action(QQ) Right scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field with precomposition on left by Coercion map: From: Abelian Group of all Formal Finite Sums over Integer Ring To: Abelian Group of all Formal Finite Sums over Rational Field sage: A = FormalSums(QQ); A.get_action(ZZ) Right scalar multiplication by Integer Ring on Abelian Group of all Formal Finite Sums over Rational Field """ else:
def _an_element_(self, check=False, reduce=False): """ EXAMPLES::
sage: FormalSums(ZZ).an_element() # indirect test 1 sage: FormalSums(QQ).an_element() 1/2*1 sage: QQ.an_element() 1/2 """ check=check, reduce=reduce, parent=self)
formal_sums = FormalSums()
# Formal sums now derives from UniqueRepresentation, which makes the # factory function unnecessary. This is why the name was changed from # class FormalSums_generic to class FormalSums. from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.structure.formal_sum', 'FormalSums_generic', FormalSums) |