Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 32 additions & 55 deletions src/sage/algebras/free_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,28 +160,25 @@
# ***************************************************************************


from sage.categories.rings import Rings

from sage.monoids.free_monoid import FreeMonoid
from sage.monoids.free_monoid_element import FreeMonoidElement

from sage.algebras.free_algebra_element import FreeAlgebraElement

from sage.structure.factory import UniqueFactory
from sage.misc.cachefunc import cached_method
from sage.misc.lazy_import import lazy_import
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.integer_ring import ZZ
from sage.categories.algebras_with_basis import AlgebrasWithBasis
from sage.categories.rings import Rings
from sage.combinat.free_module import CombinatorialFreeModule
from sage.combinat.words.word import Word
from sage.misc.cachefunc import cached_method
from sage.misc.lazy_import import lazy_import
from sage.monoids.free_monoid import FreeMonoid
from sage.monoids.free_monoid_element import FreeMonoidElement
from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.structure.category_object import normalize_names
from sage.structure.unique_representation import UniqueRepresentation


lazy_import('sage.algebras.letterplace.free_algebra_letterplace', 'FreeAlgebra_letterplace')


class FreeAlgebraFactory(UniqueFactory):
class FreeAlgebra(UniqueRepresentation):
"""
A constructor of free algebras.

Expand Down Expand Up @@ -269,10 +266,12 @@ class FreeAlgebraFactory(UniqueFactory):
sage: c^3 * a * b^2
a*b^2*c^3
"""
def create_key(self, base_ring, arg1=None, arg2=None,
sparse=None, order=None,
names=None, name=None,
implementation=None, degrees=None):

@staticmethod
def __classcall_private__(cls, base_ring, arg1=None, arg2=None,
sparse=None, order=None,
names=None, name=None,
implementation=None, degrees=None):
"""
Create the key under which a free algebra is stored.

Expand All @@ -298,12 +297,18 @@ def create_key(self, base_ring, arg1=None, arg2=None,
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)

sage: FreeAlgebra.create_object('4.7.1', (QQ['x','y'],))
Free Associative Unital Algebra on 2 generators (x, y) over Rational Field
sage: FreeAlgebra.create_object('4.7.1', (QQ['x','y'],)) is FreeAlgebra(QQ,['x','y'])
False
"""
if arg1 is None and arg2 is None and names is None:
# this is used for pickling
from sage.algebras.letterplace.free_algebra_letterplace import FreeAlgebra_letterplace
if degrees is None:
return (base_ring,)
return tuple(degrees), base_ring
return FreeAlgebra_letterplace(base_ring)
return FreeAlgebra_letterplace(base_ring, tuple(degrees))
# test if we can use libSingular/letterplace
if implementation == "letterplace":
if order is None:
Expand All @@ -316,7 +321,8 @@ def create_key(self, base_ring, arg1=None, arg2=None,
kwds["names"] = names
PolRing = PolynomialRing(base_ring, *args, **kwds)
if degrees is None:
return (PolRing,)
from sage.algebras.letterplace.free_algebra_letterplace import FreeAlgebra_letterplace
return FreeAlgebra_letterplace(PolRing)
from sage.rings.polynomial.term_order import TermOrder
T = TermOrder(PolRing.term_order(), PolRing.ngens() + 1)
varnames = list(PolRing.variable_names())
Expand All @@ -327,7 +333,7 @@ def create_key(self, base_ring, arg1=None, arg2=None,
R = PolynomialRing(
PolRing.base(), varnames,
sparse=sparse, order=T)
return tuple(degrees), R
return FreeAlgebra_letterplace(R, tuple(degrees))
# normalise the generator names
from sage.rings.integer import Integer
if isinstance(arg1, (Integer, int)):
Expand All @@ -340,39 +346,10 @@ def create_key(self, base_ring, arg1=None, arg2=None,
arg2 = len(arg1)
names = normalize_names(arg2, arg1)
if degrees is None:
return base_ring, names
return FreeAlgebra_generic(base_ring, len(names), names, None)
if degrees in ZZ:
return base_ring, names, (degrees,) * len(names)
return base_ring, names, tuple(degrees)

def create_object(self, version, key):
"""
Construct the free algebra that belongs to a unique key.

NOTE:

Of course, that method should not be called directly,
since it does not use the cache of free algebras.

TESTS::

sage: FreeAlgebra.create_object('4.7.1', (QQ['x','y'],))
Free Associative Unital Algebra on 2 generators (x, y) over Rational Field
sage: FreeAlgebra.create_object('4.7.1', (QQ['x','y'],)) is FreeAlgebra(QQ,['x','y'])
False
"""
if len(key) == 1:
from sage.algebras.letterplace.free_algebra_letterplace import FreeAlgebra_letterplace
return FreeAlgebra_letterplace(key[0])
if isinstance(key[0], tuple):
from sage.algebras.letterplace.free_algebra_letterplace import FreeAlgebra_letterplace
return FreeAlgebra_letterplace(key[1], degrees=key[0])
if len(key) == 2:
return FreeAlgebra_generic(key[0], len(key[1]), key[1])
return FreeAlgebra_generic(key[0], len(key[1]), key[1], key[2])


FreeAlgebra = FreeAlgebraFactory('FreeAlgebra')
return FreeAlgebra_generic(base_ring, len(names), names, (degrees,) * len(names))
return FreeAlgebra_generic(base_ring, len(names), names, tuple(degrees))


def is_FreeAlgebra(x) -> bool:
Expand All @@ -399,11 +376,11 @@ def is_FreeAlgebra(x) -> bool:
True
"""
from sage.misc.superseded import deprecation
deprecation(37896, "the function is_FreeAlgebra is deprecated; use 'isinstance(..., (FreeAlgebra_generic, FreeAlgebra_letterplace))' instead")
return isinstance(x, (FreeAlgebra_generic, FreeAlgebra_letterplace))
deprecation(37896, "the function is_FreeAlgebra is deprecated; use 'isinstance(..., FreeAlgebra)' instead")
return isinstance(x, FreeAlgebra)


class FreeAlgebra_generic(CombinatorialFreeModule):
class FreeAlgebra_generic(CombinatorialFreeModule, FreeAlgebra):
"""
The free algebra on `n` generators over a base ring.

Expand Down
11 changes: 6 additions & 5 deletions src/sage/algebras/letterplace/free_algebra_letterplace.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,15 @@ TESTS::
We also do not support coercion from a subalgebra, or between free
algebras with different term orderings, yet.
"""
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.libs.singular.function import lib, singular_function
from sage.algebras.free_algebra import FreeAlgebra
from sage.categories.algebras import Algebras
from sage.libs.singular.function cimport RingWrap
from sage.libs.singular.function import lib, singular_function
from sage.libs.singular.ring cimport singular_ring_delete, singular_ring_reference
from sage.categories.algebras import Algebras
from sage.misc.cachefunc import cached_method
from sage.rings.noncommutative_ideals import IdealMonoid_nc
from sage.rings.polynomial.plural cimport new_CRing
from sage.misc.cachefunc import cached_method
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing

#####################
# Define some singular functions
Expand Down Expand Up @@ -197,7 +198,7 @@ cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring, blocks):
#####################
# The free algebra

cdef class FreeAlgebra_letterplace(Parent):
cdef class FreeAlgebra_letterplace(Parent, FreeAlgebra):
"""
Finitely generated free algebra, with arithmetic restricted to weighted homogeneous elements.

Expand Down