def _multi_variate(base_ring, num_gens=None, names=None,
order='negdeglex', default_prec=None, sparse=False):
"""
Construct multivariate power series ring.
"""
if names is None:
raise TypeError("you must specify a variable name or names")
if num_gens is None:
if isinstance(names,str):
num_gens = len(names.split(','))
elif isinstance(names, (list, tuple)):
num_gens = len(names)
else:
raise TypeError("variable names must be a string, tuple or list")
names = normalize_names(num_gens, names)
num_gens = len(names)
if default_prec is None:
default_prec = 12
if base_ring not in commutative_rings.CommutativeRings():
raise TypeError("base_ring must be a commutative ring")
from sage.rings.multi_power_series_ring import MPowerSeriesRing_generic
R = MPowerSeriesRing_generic(base_ring, num_gens, names,
order=order, default_prec=default_prec, sparse=sparse)
return R
def AffineSpace(n, R=None, names='x'):
r"""
Return affine space of dimension ``n`` over the ring ``R``.
EXAMPLES:
The dimension and ring can be given in either order::
sage: AffineSpace(3, QQ, 'x')
Affine Space of dimension 3 over Rational Field
sage: AffineSpace(5, QQ, 'x')
Affine Space of dimension 5 over Rational Field
sage: A = AffineSpace(2, QQ, names='XY'); A
Affine Space of dimension 2 over Rational Field
sage: A.coordinate_ring()
Multivariate Polynomial Ring in X, Y over Rational Field
Use the divide operator for base extension::
sage: AffineSpace(5, names='x')/GF(17)
Affine Space of dimension 5 over Finite Field of size 17
The default base ring is `\ZZ`::
sage: AffineSpace(5, names='x')
Affine Space of dimension 5 over Integer Ring
There is also an affine space associated to each polynomial ring::
sage: R = GF(7)['x, y, z']
sage: A = AffineSpace(R); A
Affine Space of dimension 3 over Finite Field of size 7
sage: A.coordinate_ring() is R
True
"""
if (is_MPolynomialRing(n) or is_PolynomialRing(n)) and R is None:
R = n
A = AffineSpace(R.ngens(), R.base_ring(), R.variable_names())
A._coordinate_ring = R
return A
if isinstance(R, integer_types + (Integer,)):
n, R = R, n
if R is None:
R = ZZ # default is the integers
if names is None:
if n == 0:
names = ''
else:
raise TypeError("you must specify the variables names of the coordinate ring")
names = normalize_names(n, names)
if R in _Fields:
if is_FiniteField(R):
return AffineSpace_finite_field(n, R, names)
else:
return AffineSpace_field(n, R, names)
return AffineSpace_generic(n, R, names)
def _single_variate(base_ring, name, sparse, implementation):
import sage.rings.polynomial.polynomial_ring as m
name = normalize_names(1, name)
key = (base_ring, name, sparse, implementation if not sparse else None)
R = _get_from_cache(key)
if not R is None:
return R
if isinstance(base_ring, ring.CommutativeRing):
if is_IntegerModRing(base_ring) and not sparse:
n = base_ring.order()
if n.is_prime():
R = m.PolynomialRing_dense_mod_p(base_ring, name, implementation=implementation)
elif n > 1:
R = m.PolynomialRing_dense_mod_n(base_ring, name, implementation=implementation)
else: # n == 1!
R = m.PolynomialRing_integral_domain(base_ring, name) # specialized code breaks in this case.
elif is_FiniteField(base_ring) and not sparse:
R = m.PolynomialRing_dense_finite_field(base_ring, name, implementation=implementation)
elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative):
R = m.PolynomialRing_dense_padic_field_capped_relative(base_ring, name)
elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedRelative):
R = m.PolynomialRing_dense_padic_ring_capped_relative(base_ring, name)
elif isinstance(base_ring, padic_base_leaves.pAdicRingCappedAbsolute):
R = m.PolynomialRing_dense_padic_ring_capped_absolute(base_ring, name)
elif isinstance(base_ring, padic_base_leaves.pAdicRingFixedMod):
R = m.PolynomialRing_dense_padic_ring_fixed_mod(base_ring, name)
elif base_ring in _CompleteDiscreteValuationRings:
R = m.PolynomialRing_cdvr(base_ring, name, sparse)
elif base_ring in _CompleteDiscreteValuationFields:
R = m.PolynomialRing_cdvf(base_ring, name, sparse)
elif base_ring.is_field(proof = False):
R = m.PolynomialRing_field(base_ring, name, sparse)
elif base_ring.is_integral_domain(proof = False):
R = m.PolynomialRing_integral_domain(base_ring, name, sparse, implementation)
else:
R = m.PolynomialRing_commutative(base_ring, name, sparse)
else:
R = m.PolynomialRing_general(base_ring, name, sparse)
if hasattr(R, '_implementation_names'):
for name in R._implementation_names:
real_key = key[0:3] + (name,)
_save_in_cache(real_key, R)
else:
_save_in_cache(key, R)
return R
def __init__(self, n, R=ZZ, names=None):
"""
EXAMPLES::
sage: ProjectiveSpace(3, Zp(5), 'y')
Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20
"""
names = normalize_names(n+1, names)
AmbientSpace.__init__(self, n, R)
self._assign_names(names)
def __init__(self, G, names, base_ring):
"""
The Python constructor
EXAMPLES::
sage: F = AbelianGroup(5,[3,5,7,8,9], names="abcde")
sage: F.dual_group()
Dual of Abelian Group isomorphic to Z/3Z x Z/5Z x Z/7Z x Z/8Z x Z/9Z
over Cyclotomic Field of order 2520 and degree 576
"""
self._base_ring = base_ring
self._group = G
names = normalize_names(G.ngens(), names)
self._assign_names(names)
AbelianGroupBase.__init__(self) # TODO: category=CommutativeGroups()
def FreeAbelianMonoid(index_set=None, names=None, **kwds):
"""
Return a free abelian monoid on `n` generators or with the generators
indexed by a set `I`.
We construct free abelian monoids by specifing either:
- the number of generators and/or the names of the generators
- the indexing set for the generators (this ignores the other two inputs)
INPUT:
- ``index_set`` -- an indexing set for the generators; if an integer,
then this becomes `\{0, 1, \ldots, n-1\}`
- ``names`` -- names of generators
OUTPUT:
A free abelian monoid.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeAbelianMonoid(); F
Free abelian monoid on 5 generators (a, b, c, d, e)
sage: FreeAbelianMonoid(index_set=ZZ)
Free abelian monoid indexed by Integer Ring
"""
if isinstance(index_set, str): # Swap args (this works if names is None as well)
names, index_set = index_set, names
if index_set is None and names is not None:
if isinstance(names, str):
index_set = names.count(',')
else:
index_set = len(names)
if index_set not in ZZ:
if names is not None:
names = normalize_names(len(names), names)
from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid
return IndexedFreeAbelianMonoid(index_set, names=names, **kwds)
if names is None:
raise ValueError("names must be specified")
return FreeAbelianMonoid_factory(index_set, names)
def _multi_variate(base_ring, names, n, sparse, order, implementation):
# if not sparse:
# raise ValueError, "A dense representation of multivariate polynomials is not supported"
sparse = False
# "True" would be correct, since there is no dense implementation of
# multivariate polynomials. However, traditionally, "False" is used in the key,
# even though it is meaningless.
if implementation is not None:
raise ValueError("The %s implementation is not known for multivariate polynomial rings"%implementation)
names = normalize_names(n, names)
n = len(names)
import sage.rings.polynomial.multi_polynomial_ring as m
from sage.rings.polynomial.term_order import TermOrder
order = TermOrder(order, n)
key = (base_ring, names, n, sparse, order)
R = _get_from_cache(key)
if not R is None:
return R
from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
if isinstance(base_ring, ring.IntegralDomain):
if n < 1:
R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order)
else:
try:
R = MPolynomialRing_libsingular(base_ring, n, names, order)
except ( TypeError, NotImplementedError ):
R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order)
else:
if not base_ring.is_zero():
try:
R = MPolynomialRing_libsingular(base_ring, n, names, order)
except ( TypeError, NotImplementedError ):
R = m.MPolynomialRing_polydict(base_ring, n, names, order)
else:
R = m.MPolynomialRing_polydict(base_ring, n, names, order)
_save_in_cache(key, R)
return R
def _multi_variate(base_ring, names, n, sparse, order):
"""
EXAMPLES::
sage: from sage.rings.polynomial.laurent_polynomial_ring import _multi_variate
sage: _multi_variate(QQ, ('x','y'), 2, False, 'degrevlex')
Multivariate Laurent Polynomial Ring in x, y over Rational Field
"""
# We need to come up with a name for the inverse that is easy to search
# for in a string *and* doesn't overlap with the name that we already have.
# For now, I'm going to use a name mangling with checking method.
names = normalize_names(n, names)
from term_order import TermOrder
order = TermOrder(order, n)
if isinstance(names, list):
names = tuple(names)
elif isinstance(names, str):
if ',' in names:
names = tuple(names.split(','))
key = (base_ring, names, n, sparse, order)
P = _get_from_cache(key)
if P is not None:
return P
prepend_string = "qk"
while True:
for a in names:
if prepend_string in a:
prepend_string += 'k'
break
else:
break
R = _multi_variate_poly(base_ring, names, n, sparse, order, None)
P = LaurentPolynomialRing_mpair(R, prepend_string, names)
_save_in_cache(key, P)
return P
def _single_variate(base_ring, names, sparse):
"""
EXAMPLES::
sage: from sage.rings.polynomial.laurent_polynomial_ring import _single_variate
sage: _single_variate(QQ, ('x',), False)
Univariate Laurent Polynomial Ring in x over Rational Field
"""
names = normalize_names(1, names)
key = (base_ring, names, sparse)
P = _get_from_cache(key)
if P is not None:
return P
prepend_string = "qk"
while True:
if prepend_string in names:
prepend_string += 'k'
else:
break
R = _single_variate_poly(base_ring, names, sparse, None)
P = LaurentPolynomialRing_univariate(R, names)
_save_in_cache(key, P)
return P
def FreeGroup(n=None, names='x', index_set=None, abelian=False, **kwds):
"""
Construct a Free Group.
INPUT:
- ``n`` -- integer or ``None`` (default). The nnumber of
generators. If not specified the ``names`` are counted.
- ``names`` -- string or list/tuple/iterable of strings (default:
``'x'``). The generator names or name prefix.
- ``index_set`` -- (optional) an index set for the generators; if
specified then the optional keyword ``abelian`` can be used
- ``abelian`` -- (default: ``False``) whether to construct a free
abelian group or a free group
.. NOTE::
If you want to create a free group, it is currently preferential to
use ``Groups().free(...)`` as that does not load GAP.
EXAMPLES::
sage: G.<a,b> = FreeGroup(); G
Free Group on generators {a, b}
sage: H = FreeGroup('a, b')
sage: G is H
True
sage: FreeGroup(0)
Free Group on generators {}
The entry can be either a string with the names of the generators,
or the number of generators and the prefix of the names to be
given. The default prefix is ``'x'`` ::
sage: FreeGroup(3)
Free Group on generators {x0, x1, x2}
sage: FreeGroup(3, 'g')
Free Group on generators {g0, g1, g2}
sage: FreeGroup()
Free Group on generators {x}
We give two examples using the ``index_set`` option::
sage: FreeGroup(index_set=ZZ)
Free group indexed by Integer Ring
sage: FreeGroup(index_set=ZZ, abelian=True)
Free abelian group indexed by Integer Ring
TESTS::
sage: G1 = FreeGroup(2, 'a,b')
sage: G2 = FreeGroup('a,b')
sage: G3.<a,b> = FreeGroup()
sage: G1 is G2, G2 is G3
(True, True)
"""
# Support Freegroup('a,b') syntax
if n is not None:
try:
n = Integer(n)
except TypeError:
names = n
n = None
# derive n from counting names
if n is None:
if isinstance(names, six.string_types):
n = len(names.split(','))
else:
names = list(names)
n = len(names)
from sage.structure.category_object import normalize_names
names = normalize_names(n, names)
if index_set is not None or abelian:
if abelian:
from sage.groups.indexed_free_group import IndexedFreeAbelianGroup
return IndexedFreeAbelianGroup(index_set, names=names, **kwds)
from sage.groups.indexed_free_group import IndexedFreeGroup
return IndexedFreeGroup(index_set, names=names, **kwds)
return FreeGroup_class(names)
开发者ID:Babyll,项目名称:sage,代码行数:83,代码来源:free_group.py
示例12: create_key
def create_key(self, base_ring, arg1=None, arg2=None,
sparse=None, order='degrevlex',
names=None, name=None,
implementation=None, degrees=None):
"""
Create the key under which a free algebra is stored.
TESTS::
sage: FreeAlgebra.create_key(GF(5),['x','y','z'])
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3)
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),3,'xyz')
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),['x','y','z'], implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace', degrees=[1,2,3])
((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5)
"""
if arg1 is None and arg2 is None and names is None:
# this is used for pickling
if degrees is None:
return (base_ring,)
return tuple(degrees),base_ring
# test if we can use libSingular/letterplace
if implementation == "letterplace":
args = [arg for arg in (arg1, arg2) if arg is not None]
kwds = dict(sparse=sparse, order=order, implementation="singular")
if name is not None:
kwds["name"] = name
if names is not None:
kwds["names"] = names
PolRing = PolynomialRing(base_ring, *args, **kwds)
if degrees is None:
return (PolRing,)
from sage.all import TermOrder
T = PolRing.term_order() + TermOrder('lex',1)
varnames = list(PolRing.variable_names())
newname = 'x'
while newname in varnames:
newname += '_'
varnames.append(newname)
R = PolynomialRing(
PolRing.base(), varnames,
sparse=sparse, order=T)
return tuple(degrees), R
# normalise the generator names
from sage.all import Integer
if isinstance(arg1, (Integer,) + integer_types):
arg1, arg2 = arg2, arg1
if not names is None:
arg1 = names
elif not name is None:
arg1 = name
if arg2 is None:
arg2 = len(arg1)
names = normalize_names(arg2, arg1)
return base_ring, names
#.........这里部分代码省略.........
By :trac:`14084`, a power series ring belongs to the category of integral
domains, if the base ring does::
sage: P = ZZ[['x']]
sage: P.category()
Category of integral domains
sage: TestSuite(P).run()
sage: M = ZZ[['x','y']]
sage: M.category()
Category of integral domains
sage: TestSuite(M).run()
Otherwise, it belongs to the category of commutative rings::
sage: P = Integers(15)[['x']]
sage: P.category()
Category of commutative rings
sage: TestSuite(P).run()
sage: M = Integers(15)[['x','y']]
sage: M.category()
Category of commutative rings
sage: TestSuite(M).run()
.. SEEALSO::
* :func:`sage.misc.defaults.set_series_precision`
"""
#multivariate case:
# examples for first case:
# PowerSeriesRing(QQ,'x,y,z')
# PowerSeriesRing(QQ,['x','y','z'])
# PowerSeriesRing(QQ,['x','y','z'], 3)
if names is None and name is not None:
names = name
if isinstance(names, (tuple, list)) and len(names) > 1 or (isinstance(names, str) and ',' in names):
return _multi_variate(base_ring, num_gens=arg2, names=names,
order=order, default_prec=default_prec, sparse=sparse)
# examples for second case:
# PowerSeriesRing(QQ,3,'t')
if arg2 is None and num_gens is not None:
arg2 = names
names = num_gens
if (isinstance(arg2, str) and
isinstance(names, integer_types + (integer.Integer,))):
return _multi_variate(base_ring, num_gens=names, names=arg2,
order=order, default_prec=default_prec, sparse=sparse)
# univariate case: the arguments to PowerSeriesRing used to be
# (base_ring, name=None, default_prec=20, names=None, sparse=False),
# and thus that is what the code below expects; this behavior is being
# deprecated, and will eventually be removed.
if default_prec is None and arg2 is None:
from sage.misc.defaults import series_precision
default_prec = series_precision()
elif arg2 is not None:
default_prec = arg2
## too many things (padics, elliptic curves) depend on this behavior,
## so no warning for now.
##
# from sage.misc.superseded import deprecation
# if isinstance(name, (int,integer.Integer)) or isinstance(arg2,(int,integer.Integer)):
# deprecation(trac_number, "This behavior of PowerSeriesRing is being deprecated in favor of constructing multivariate power series rings. (See Trac ticket #1956.)")
# the following is the original, univariate-only code
if isinstance(name, integer_types + (integer.Integer,)):
default_prec = name
if not names is None:
name = names
name = normalize_names(1, name)
if name is None:
raise TypeError("You must specify the name of the indeterminate of the Power series ring.")
key = (base_ring, name, default_prec, sparse, implementation)
if PowerSeriesRing_generic.__classcall__.is_in_cache(key):
return PowerSeriesRing_generic(*key)
if isinstance(name, (tuple, list)):
assert len(name) == 1
name = name[0]
if not (name is None or isinstance(name, str)):
raise TypeError("variable name must be a string or None")
if base_ring in _Fields:
R = PowerSeriesRing_over_field(base_ring, name, default_prec,
sparse=sparse, implementation=implementation)
elif base_ring in _IntegralDomains:
R = PowerSeriesRing_domain(base_ring, name, default_prec,
sparse=sparse, implementation=implementation)
elif base_ring in _CommutativeRings:
R = PowerSeriesRing_generic(base_ring, name, default_prec,
sparse=sparse, implementation=implementation)
else:
raise TypeError("base_ring must be a commutative ring")
return R
def create_key(self,base_ring, arg1=None, arg2=None,
sparse=False, order='degrevlex',
names=None, name=None,
implementation=None, degrees=None):
"""
Create the key under which a free algebra is stored.
TESTS::
sage: FreeAlgebra.create_key(GF(5),['x','y','z'])
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3)
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),3,'xyz')
(Finite Field of size 5, ('x', 'y', 'z'))
sage: FreeAlgebra.create_key(GF(5),['x','y','z'], implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace')
(Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,)
sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace', degrees=[1,2,3])
((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5)
"""
if arg1 is None and arg2 is None and names is None:
# this is used for pickling
if degrees is None:
return (base_ring,)
return tuple(degrees),base_ring
PolRing = None
# test if we can use libSingular/letterplace
if implementation is not None and implementation != 'generic':
try:
PolRing = PolynomialRing(base_ring, arg1, arg2,
sparse=sparse, order=order,
names=names, name=name,
implementation=implementation if implementation != 'letterplace' else None)
if not isinstance(PolRing, MPolynomialRing_libsingular):
if PolRing.ngens() == 1:
PolRing = PolynomialRing(base_ring, 1, PolRing.variable_names())
if not isinstance(PolRing, MPolynomialRing_libsingular):
raise TypeError
else:
raise TypeError
except (TypeError, NotImplementedError) as msg:
raise NotImplementedError("The letterplace implementation is not available for the free algebra you requested")
if PolRing is not None:
if degrees is None:
return (PolRing,)
from sage.all import TermOrder
T = PolRing.term_order() + TermOrder('lex',1)
varnames = list(PolRing.variable_names())
newname = 'x'
while newname in varnames:
newname += '_'
varnames.append(newname)
return tuple(degrees),PolynomialRing(PolRing.base(), varnames,
sparse=sparse, order=T,
implementation=implementation if implementation != 'letterplace' else None)
# normalise the generator names
from sage.all import Integer
if isinstance(arg1, (int, long, Integer)):
arg1, arg2 = arg2, arg1
if not names is None:
arg1 = names
elif not name is None:
arg1 = name
if arg2 is None:
arg2 = len(arg1)
names = normalize_names(arg2, arg1)
return base_ring, names
#.........这里部分代码省略.........
sage: T.<c,d> = QuotientRing(S,S.ideal(a))
sage: T
Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1)
sage: R.gens(); S.gens(); T.gens()
(x, y)
(a, b)
(0, d)
sage: for n in range(4): d^n
1
d
-1
-d
TESTS:
By :trac:`11068`, the following does not return a generic
quotient ring but a usual quotient of the integer ring::
sage: R = Integers(8)
sage: I = R.ideal(2)
sage: R.quotient(I)
Ring of integers modulo 2
Here is an example of the quotient of a free algebra by a
twosided homogeneous ideal (see :trac:`7797`)::
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
sage: Q.<a,b,c> = F.quo(I); Q
Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y)
sage: a*b
-b*c
sage: a^3
-b*c*a - b*c*b - b*c*c
sage: J = Q*[a^3-b^3]*Q
sage: R.<i,j,k> = Q.quo(J); R
Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y)
sage: i^3
-j*k*i - j*k*j - j*k*k
sage: j^3
-j*k*i - j*k*j - j*k*k
Check that :trac:`5978` is fixed by if we quotient by the zero ideal `(0)`
then we just return ``R``::
sage: R = QQ['x']
sage: R.quotient(R.zero_ideal())
Univariate Polynomial Ring in x over Rational Field
sage: R.<x> = PolynomialRing(ZZ)
sage: R is R.quotient(R.zero_ideal())
True
sage: I = R.ideal(0)
sage: R is R.quotient(I)
True
"""
# 1. Not all rings inherit from the base class of rings.
# 2. We want to support quotients of free algebras by homogeneous two-sided ideals.
#if not isinstance(R, commutative_ring.CommutativeRing):
# raise TypeError, "R must be a commutative ring."
from sage.all import Integers, ZZ
if not R in Rings():
raise TypeError("R must be a ring.")
try:
is_commutative = R.is_commutative()
except (AttributeError, NotImplementedError):
is_commutative = False
if names is None:
try:
names = tuple([x + 'bar' for x in R.variable_names()])
except ValueError: # no names are assigned
pass
else:
names = normalize_names(R.ngens(), names)
if not isinstance(I, ideal.Ideal_generic) or I.ring() != R:
I = R.ideal(I)
if I.is_zero():
return R
try:
if I.is_principal():
return R.quotient_by_principal_ideal(I.gen(), names)
except (AttributeError, NotImplementedError):
pass
if not is_commutative:
try:
if I.side() != 'twosided':
raise AttributeError
except AttributeError:
raise TypeError("A twosided ideal is required.")
if isinstance(R, QuotientRing_nc):
pi = R.cover()
S = pi.domain()
G = [pi.lift(x) for x in I.gens()]
I_lift = S.ideal(G)
J = R.defining_ideal()
if S == ZZ:
return Integers((I_lift+J).gen())
return R.__class__(S, I_lift + J, names=names)
if isinstance(R, ring.CommutativeRing):
return QuotientRing_generic(R, I, names)
return QuotientRing_nc(R, I, names)
def FreeMonoid(index_set=None, names=None, commutative=False, **kwds):
r"""
Return a free monoid on `n` generators or with the generators indexed by
a set `I`.
We construct free monoids by specifing either:
- the number of generators and/or the names of the generators
- the indexing set for the generators
INPUT:
- ``index_set`` -- an indexing set for the generators; if an integer,
than this becomes `\{0, 1, \ldots, n-1\}`
- ``names`` -- names of generators
- ``commutative`` -- (default: ``False``) whether the free monoid is
commutative or not
OUTPUT:
A free monoid.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeMonoid(); F
Free monoid on 5 generators (a, b, c, d, e)
sage: FreeMonoid(index_set=ZZ)
Free monoid indexed by Integer Ring
sage: F.<x,y,z> = FreeMonoid(abelian=True); F
Free abelian monoid on 3 generators (x, y, z)
sage: FreeMonoid(index_set=ZZ, commutative=True)
Free abelian monoid indexed by Integer Ring
TESTS::
sage: FreeMonoid(index_set=ZZ, names='x,y,z')
Free monoid indexed by Integer Ring
"""
if 'abelian' in kwds:
commutative = kwds.pop('abelian')
if commutative:
from sage.monoids.free_abelian_monoid import FreeAbelianMonoid
return FreeAbelianMonoid(index_set, names, **kwds)
if isinstance(index_set, str): # Swap args (this works if names is None as well)
names, index_set = index_set, names
if index_set is None and names is not None:
if isinstance(names, str):
index_set = names.count(',')
else:
index_set = len(names)
if index_set not in ZZ:
if names is not None:
names = normalize_names(-1, names)
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return IndexedFreeMonoid(index_set, names=names, **kwds)
if names is None:
raise ValueError("names must be specified")
return FreeMonoid_factory(index_set, names)
def __classcall_private__(cls, k, table, names='e', assume_associative=False,
category=None):
"""
Normalize input.
TESTS::
sage: table = [Matrix([[1, 0], [0, 1]]), Matrix([[0, 1], [0, 0]])]
sage: A1 = FiniteDimensionalAlgebra(GF(3), table)
sage: A2 = FiniteDimensionalAlgebra(GF(3), table, names='e')
sage: A3 = FiniteDimensionalAlgebra(GF(3), table, names=['e0', 'e1'])
sage: A1 is A2 and A2 is A3
True
The ``assume_associative`` keyword is built into the category::
sage: from sage.categories.magmatic_algebras import MagmaticAlgebras
sage: cat = MagmaticAlgebras(GF(3)).FiniteDimensional().WithBasis()
sage: A1 = FiniteDimensionalAlgebra(GF(3), table, category=cat.Associative())
sage: A2 = FiniteDimensionalAlgebra(GF(3), table, assume_associative=True)
sage: A1 is A2
True
Uniqueness depends on the category::
sage: cat = Algebras(GF(3)).FiniteDimensional().WithBasis()
sage: A1 = FiniteDimensionalAlgebra(GF(3), table)
sage: A2 = FiniteDimensionalAlgebra(GF(3), table, category=cat)
sage: A1 == A2
False
sage: A1 is A2
False
Checking that equality is still as expected::
sage: A = FiniteDimensionalAlgebra(GF(3), table)
sage: B = FiniteDimensionalAlgebra(GF(5), [Matrix([0])])
sage: A == A
True
sage: B == B
True
sage: A == B
False
sage: A != A
False
sage: B != B
False
sage: A != B
True
"""
n = len(table)
table = [b.base_extend(k) for b in table]
for b in table:
b.set_immutable()
if not (is_Matrix(b) and b.dimensions() == (n, n)):
raise ValueError("input is not a multiplication table")
table = tuple(table)
cat = MagmaticAlgebras(k).FiniteDimensional().WithBasis()
cat = cat.or_subcategory(category)
if assume_associative:
cat = cat.Associative()
names = normalize_names(n, names)
return super(FiniteDimensionalAlgebra, cls).__classcall__(cls, k, table,
names, category=cat)
#.........这里部分代码省略.........
Univariate Polynomial Ring in t over Integer Ring
and the twisting map::
sage: base_ring_automorphism = R.hom([t+1]); base_ring_automorphism
Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring
Defn: t |--> t + 1
Now, we are ready to define the skew polynomial ring::
sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x'); S
Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
twisted by t |--> t + 1
Use the diamond brackets notation to make the variable ready
for use after you define the ring::
sage: S.<x> = SkewPolynomialRing(R, base_ring_automorphism)
sage: (x + t)^2
x^2 + (2*t + 1)*x + t^2
Here is an example with the square bracket notations::
sage: S.<x> = R['x', base_ring_automorphism]; S
Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
twisted by t |--> t + 1
Rings with different variables names are different::
sage: R['x', base_ring_automorphism] == R['y', base_ring_automorphism]
False
TESTS:
You must specify a variable name::
sage: SkewPolynomialRing(R, base_ring_automorphism)
Traceback (most recent call last):
...
TypeError: you must specify the name of the variable
With this syntax, it is not possible to omit the name of the
variable neither in LHS nor in RHS. If we omit it in LHS, the
variable is not created::
sage: Sy = R['y', base_ring_automorphism]; Sy
Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring
twisted by t |--> t + 1
sage: y.parent()
Traceback (most recent call last):
...
NameError: name 'y' is not defined
If we omit it in RHS, sage tries to create a polynomial ring and fails::
sage: Sz.<z> = R[base_ring_automorphism]
Traceback (most recent call last):
...
ValueError: variable name 'Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring\n Defn: t |--> t + 1' is not alphanumeric
Multivariate skew polynomial rings are not supported::
sage: S = SkewPolynomialRing(R, base_ring_automorphism,names=['x','y'])
Traceback (most recent call last):
...
NotImplementedError: multivariate skew polynomials rings not supported
Sparse skew polynomial rings are not implemented::
sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x', sparse=True)
Traceback (most recent call last):
...
NotImplementedError: sparse skew polynomial rings are not implemented
.. TODO::
- Sparse Skew Polynomial Ring
- Multivariate Skew Polynomial Ring
- Add derivations.
"""
if base_ring not in categories.rings.Rings().Commutative():
raise TypeError("base_ring must be a commutative ring")
if base_ring_automorphism is None:
base_ring_automorphism = IdentityMorphism(base_ring)
else:
if (not isinstance(base_ring_automorphism,Morphism)
or base_ring_automorphism.domain() != base_ring
or base_ring_automorphism.codomain() != base_ring):
raise TypeError("base_ring_automorphism must be a ring automorphism of base_ring (=%s)" % base_ring)
if sparse:
raise NotImplementedError("sparse skew polynomial rings are not implemented")
if names is None:
raise TypeError("you must specify the name of the variable")
try:
names = normalize_names(1, names)[0]
except IndexError:
raise NotImplementedError("multivariate skew polynomials rings not supported")
from sage.rings.polynomial.skew_polynomial_ring import SkewPolynomialRing_general
return SkewPolynomialRing_general(base_ring, base_ring_automorphism, names, sparse)
请发表评论