Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
rewrite element_constructor of terms
Browse files Browse the repository at this point in the history
  • Loading branch information
dkrenn committed Aug 26, 2015
1 parent ab05e75 commit 4bb85a5
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 70 deletions.
8 changes: 8 additions & 0 deletions src/sage/rings/asymptotic/asymptotic_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,14 @@ def create_summand(self, type, growth, **kwds):
O(x^2)
sage: R.create_summand('exact', growth=x^456, coefficient=123)
123*x^456
TESTS::
sage: R.create_summand('O', growth=42*x^2)
Traceback (most recent call last):
...
ValueError: Growth 42*x^2 is not in O-Term Monoid x^ZZ.
> *previous* ValueError: 42*x^2 is not in Growth Group x^ZZ.
"""
from sage.rings.asymptotic.term_monoid import TermMonoid
TM = TermMonoid(type, self.growth_group, self.coefficient_ring)
Expand Down
179 changes: 109 additions & 70 deletions src/sage/rings/asymptotic/term_monoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -1110,9 +1110,9 @@ def _element_constructor_(self, data):
EXAMPLES::
sage: import sage.rings.asymptotic.term_monoid as atm
sage: import sage.rings.asymptotic.growth_group as agg
sage: G_ZZ = agg.GrowthGroup('x^ZZ')
sage: G_QQ = agg.GrowthGroup('x^QQ')
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: G_ZZ = GrowthGroup('x^ZZ')
sage: G_QQ = GrowthGroup('x^QQ')
sage: T_ZZ = atm.GenericTermMonoid(growth_group=G_ZZ)
sage: T_QQ = atm.GenericTermMonoid(growth_group=G_QQ)
sage: term1 = T_ZZ(G_ZZ.gen())
Expand All @@ -1138,7 +1138,19 @@ def _element_constructor_(self, data):
sage: T_ZZ(10 * x^2)
Traceback (most recent call last):
...
ValueError: Input is ambiguous: cannot convert 10*x^2 to a generic term.
ValueError: Growth 10*x^2 is not in Generic Term Monoid x^ZZ.
> *previous* ValueError: 10*x^2 is not in Growth Group x^ZZ.
TESTS::
sage: O_ZZ = atm.OTermMonoid(growth_group=G_ZZ)
sage: O_ZZ(x^11)
O(x^11)
sage: O_ZZ(2*x^11)
Traceback (most recent call last):
...
ValueError: Growth 2*x^11 is not in O-Term Monoid x^ZZ.
> *previous* ValueError: 2*x^11 is not in Growth Group x^ZZ.
"""
if type(data) == self.element_class and data.parent() == self:
return data
Expand All @@ -1147,12 +1159,13 @@ def _element_constructor_(self, data):
elif type(data) == int and data == 0:
raise ValueError('No input specified. Cannot continue.')
else:
from growth_group import combine_exceptions
try:
data = self.growth_group(data)
return self.element_class(self, data)
except:
raise ValueError('Input is ambiguous: cannot convert %s to a '
'generic term.' % (data,))
except (ValueError, TypeError) as e:
raise combine_exceptions(
ValueError('Growth %s is not in %s.' % (data, self)), e)


def _an_element_(self):
Expand Down Expand Up @@ -1450,17 +1463,17 @@ class OTermMonoid(GenericTermMonoid):
sage: G_x_ZZ = agg.GrowthGroup('x^ZZ')
sage: G_y_QQ = agg.GrowthGroup('y^QQ')
sage: OT_x_ZZ = atm.OTermMonoid(G_x_ZZ); OT_x_ZZ
Asymptotic O-Term Monoid x^ZZ
O-Term Monoid x^ZZ
sage: OT_y_QQ = atm.OTermMonoid(G_y_QQ); OT_y_QQ
Asymptotic O-Term Monoid y^QQ
O-Term Monoid y^QQ
`O`-term monoids can also be created by using the
:class:`term factory <TermMonoidFactory>`::
sage: atm.TermMonoid('O', G_x_ZZ) is OT_x_ZZ
True
sage: atm.TermMonoid('O', agg.GrowthGroup('x^QQ'))
Asymptotic O-Term Monoid x^QQ
O-Term Monoid x^QQ
"""
# enable the category framework for elements
Element = OTerm
Expand Down Expand Up @@ -1538,9 +1551,9 @@ def _repr_(self):
sage: import sage.rings.asymptotic.growth_group as agg
sage: G = agg.GrowthGroup('x^ZZ'); x = G.gen()
sage: atm.OTermMonoid(G)._repr_()
'Asymptotic O-Term Monoid x^ZZ'
'O-Term Monoid x^ZZ'
"""
return 'Asymptotic O-Term Monoid %s' % (self.growth_group._repr_short_(),)
return 'O-Term Monoid %s' % (self.growth_group._repr_short_(),)


class TermWithCoefficient(GenericTerm):
Expand Down Expand Up @@ -1589,7 +1602,8 @@ def __init__(self, parent, growth, coefficient):
sage: t = CT_ZZ(x, 1/2)
Traceback (most recent call last):
...
ValueError: 1/2 is not in Integer Ring
ValueError: 1/2 is not a coefficient in
Term Monoid x^ZZ with coefficients from Integer Ring.
sage: t = CT_QQ(x, 1/2); t
Asymptotic Term with coefficient 1/2 and growth x
Expand All @@ -1598,7 +1612,8 @@ def __init__(self, parent, growth, coefficient):
sage: t = CT_ZZ(x^42, 0)
Traceback (most recent call last):
...
ValueError: 0 is not a valid coefficient.
ValueError: Zero coefficient 0 is not allowed in
Term Monoid x^ZZ with coefficients from Integer Ring.
The conversion of growth elements also works for the creation
of terms with coefficient::
Expand All @@ -1608,13 +1623,16 @@ def __init__(self, parent, growth, coefficient):
sage: CT_ZZ(x^42, 42)
Asymptotic Term with coefficient 42 and growth x^42
"""
if coefficient not in parent.base_ring:
raise ValueError('%s is not in %s' % (coefficient,
parent.base_ring))
elif coefficient == 0:
raise ValueError('0 is not a valid coefficient')

self.coefficient = parent.base_ring(coefficient)
try:
coefficient = parent.base_ring(coefficient)
except (ValueError, TypeError):
raise ValueError('%s is not a coefficient in %s.' %
(coefficient, parent))
if coefficient == 0:
raise ValueError('Zero coefficient %s is not allowed in %s.' %
(coefficient, parent))

self.coefficient = coefficient
super(TermWithCoefficient, self).__init__(parent=parent, growth=growth)


Expand Down Expand Up @@ -1932,9 +1950,7 @@ def _element_constructor_(self, data, coefficient=None):
sage: T(5 * x^5)
Asymptotic Term with coefficient 5 and growth x^5
sage: T(G.gen()^10)
Traceback (most recent call last):
...
ValueError: Coefficient is not specified. Cannot continue.
Asymptotic Term with coefficient 1 and growth x^10
sage: T(G.gen()^10, coefficient=10)
Asymptotic Term with coefficient 10 and growth x^10
sage: T(x^123)
Expand All @@ -1957,53 +1973,76 @@ def _element_constructor_(self, data, coefficient=None):
elif isinstance(data, TermWithCoefficient):
return self.element_class(self, data.growth, data.coefficient)
elif type(data) == int and data == 0:
raise ValueError('No input specified. Cannot continue.')
raise ValueError('No input specified. Cannot continue '
'creating an element of %s.' % (self,))

try:
if coefficient is not None:
from growth_group import combine_exceptions
if coefficient is not None:
try:
data = self.growth_group(data)
try:
return self.element_class(self, data, coefficient)
except:
raise
except (ValueError, TypeError) as e:
raise combine_exceptions(
ValueError('Growth %s is not in %s.' % (data, self)), e)
return self.element_class(self, data, coefficient)

try:
growth, coefficient = self._split_growth_and_coefficient_(data)
except ValueError as e:
raise combine_exceptions(
ValueError('%s is not in %s.' % (data, self)), e)

return self.element_class(self, growth, coefficient)


def _split_growth_and_coefficient_(self, data):
factors = self._get_factors_(data)

growth_group = self.growth_group
coefficient_ring = self.base_ring

coefficient = coefficient_ring.one()
growth = self.growth_group.one()
for f in factors:
try:
g = growth_group(f)
except (ValueError, TypeError):
pass
else:
growth *= g
continue
try:
c = coefficient_ring(f)
except (ValueError, TypeError):
pass
else:
P = data.parent()
from sage.symbolic.ring import SR
import operator
from sage.symbolic.operators import mul_vararg
if P is SR:
op = data.operator()
if op == mul_vararg:
data, coef_tmp = data.operands()
data = self.growth_group(data)
elif op in (operator.pow, None) or\
isinstance(op, sage.functions.log.Function_log):
coef_tmp = 1
data = self.growth_group(data)
else:
coeffs = data.coefficients()
if type(coeffs) == list:
# (multivariate) polynomial ring
coef_tmp = coeffs[0]
data = self.growth_group(data / coef_tmp)
elif type(coeffs) == dict:
# power series ring
coef_tmp = coeffs.values()[0]
data = self.growth_group(data / coef_tmp)

return self.element_class(self, data, coef_tmp)
except (ValueError, AttributeError):
if coefficient is None:
raise ValueError('Coefficient is not specified. '
'Cannot continue.')
elif coefficient not in self.base_ring:
raise ValueError('%s is not in %s'
% (coefficient, self.base_ring))
elif coefficient == 0:
raise ValueError('0 is not a valid coefficient.')
raise ValueError('Input is ambiguous: cannot convert %s with '
'coefficient %s to a term with coefficient.'
% (data, coefficient))
coefficient *= c
continue
raise ValueError('Factor %s of %s is neither a coefficient (in %s) '
'nor growth (in %s).' %
(f, data, coefficient_ring, growth_group))

return (growth, coefficient)


def _get_factors_(self, data):

if isinstance(data, str):
from growth_group import split_str_by_mul
return split_str_by_mul(data)

try:
P = data.parent()
except AttributeError:
return (data,)

from sage.symbolic.ring import SR
if P is SR:
from sage.symbolic.operators import mul_vararg
op = data.operator()
if op == mul_vararg:
return data.operands()

return (data,)


def _repr_(self):
Expand Down Expand Up @@ -2406,7 +2445,7 @@ class TermMonoidFactory(sage.structure.factory.UniqueFactory):
sage: import sage.rings.asymptotic.term_monoid as atm
sage: G = agg.GrowthGroup('x^ZZ')
sage: OT = atm.TermMonoid('O', G); OT
Asymptotic O-Term Monoid x^ZZ
O-Term Monoid x^ZZ
sage: ET = atm.TermMonoid('exact', G, ZZ); ET
Exact Term Monoid x^ZZ with coefficients from Integer Ring
"""
Expand Down Expand Up @@ -2456,7 +2495,7 @@ def create_object(self, version, key, **kwds):
sage: import sage.rings.asymptotic.term_monoid as atm
sage: G = agg.GrowthGroup('x^ZZ')
sage: atm.TermMonoid('O', G) # indirect doctest
Asymptotic O-Term Monoid x^ZZ
O-Term Monoid x^ZZ
sage: atm.TermMonoid('exact', G, ZZ) # indirect doctest
Exact Term Monoid x^ZZ with coefficients from Integer Ring
"""
Expand Down

0 comments on commit 4bb85a5

Please sign in to comment.