passagemath-symbolics 10.6.40__cp314-cp314t-macosx_13_0_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-symbolics might be problematic. Click here for more details.
- passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.40.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.40.dist-info/RECORD +172 -0
- passagemath_symbolics-10.6.40.dist-info/WHEEL +6 -0
- passagemath_symbolics-10.6.40.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-darwin.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-314t-darwin.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-darwin.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-314t-darwin.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -0,0 +1,1400 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
# sage.doctest: needs sage.graphs
|
|
3
|
+
r"""
|
|
4
|
+
Cartesian Products of Growth Groups
|
|
5
|
+
|
|
6
|
+
See :doc:`growth_group` for a description.
|
|
7
|
+
|
|
8
|
+
AUTHORS:
|
|
9
|
+
|
|
10
|
+
- Benjamin Hackl (2015)
|
|
11
|
+
- Daniel Krenn (2015)
|
|
12
|
+
- Clemens Heuberger (2016)
|
|
13
|
+
|
|
14
|
+
ACKNOWLEDGEMENT:
|
|
15
|
+
|
|
16
|
+
- Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the
|
|
17
|
+
Austrian Science Fund (FWF): P 24644-N26.
|
|
18
|
+
|
|
19
|
+
- Benjamin Hackl is supported by the Google Summer of Code 2015.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
TESTS::
|
|
23
|
+
|
|
24
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
25
|
+
sage: A = GrowthGroup('(QQ_+)^x * x^ZZ'); A
|
|
26
|
+
Growth Group QQ^x * x^ZZ
|
|
27
|
+
sage: A.construction()
|
|
28
|
+
(The cartesian_product functorial construction,
|
|
29
|
+
(Growth Group QQ^x, Growth Group x^ZZ))
|
|
30
|
+
sage: A.construction()[1][0].construction()
|
|
31
|
+
(ExponentialGrowthGroup[x], Rational Field)
|
|
32
|
+
sage: A.construction()[1][1].construction()
|
|
33
|
+
(MonomialGrowthGroup[x], Integer Ring)
|
|
34
|
+
sage: B = GrowthGroup('x^ZZ * y^ZZ'); B
|
|
35
|
+
Growth Group x^ZZ * y^ZZ
|
|
36
|
+
sage: B.construction()
|
|
37
|
+
(The cartesian_product functorial construction,
|
|
38
|
+
(Growth Group x^ZZ, Growth Group y^ZZ))
|
|
39
|
+
sage: C = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ'); C
|
|
40
|
+
Growth Group x^ZZ * log(x)^ZZ * y^ZZ
|
|
41
|
+
sage: C.construction()
|
|
42
|
+
(The cartesian_product functorial construction,
|
|
43
|
+
(Growth Group x^ZZ * log(x)^ZZ, Growth Group y^ZZ))
|
|
44
|
+
sage: C.construction()[1][0].construction()
|
|
45
|
+
(The cartesian_product functorial construction,
|
|
46
|
+
(Growth Group x^ZZ, Growth Group log(x)^ZZ))
|
|
47
|
+
sage: C.construction()[1][1].construction()
|
|
48
|
+
(MonomialGrowthGroup[y], Integer Ring)
|
|
49
|
+
|
|
50
|
+
::
|
|
51
|
+
|
|
52
|
+
sage: cm = sage.structure.element.get_coercion_model()
|
|
53
|
+
sage: D = GrowthGroup('(QQ_+)^x * x^QQ')
|
|
54
|
+
sage: cm.common_parent(A, D)
|
|
55
|
+
Growth Group QQ^x * x^QQ
|
|
56
|
+
sage: E = GrowthGroup('(ZZ_+)^x * x^QQ')
|
|
57
|
+
sage: cm.record_exceptions() # not tested, see #19411
|
|
58
|
+
sage: cm.common_parent(A, E)
|
|
59
|
+
Growth Group QQ^x * x^QQ
|
|
60
|
+
sage: for t in cm.exception_stack(): # not tested, see #19411
|
|
61
|
+
....: print(t)
|
|
62
|
+
|
|
63
|
+
::
|
|
64
|
+
|
|
65
|
+
sage: assume(SR.an_element() > 0)
|
|
66
|
+
sage: F = GrowthGroup('(SR_+)^n * n^ZZ * UU^n'); F
|
|
67
|
+
Growth Group SR^n * n^ZZ * UU^n
|
|
68
|
+
sage: G = GrowthGroup('QQ^n * n^QQ'); G
|
|
69
|
+
Growth Group QQ^n * n^QQ * Signs^n
|
|
70
|
+
sage: cm.common_parent(F, G)
|
|
71
|
+
Growth Group SR^n * n^QQ * UU^n
|
|
72
|
+
sage: forget()
|
|
73
|
+
|
|
74
|
+
::
|
|
75
|
+
|
|
76
|
+
sage: A.an_element()
|
|
77
|
+
(1/2)^x*x
|
|
78
|
+
sage: tuple(E.an_element())
|
|
79
|
+
(1, x^(1/2))
|
|
80
|
+
|
|
81
|
+
Classes and Methods
|
|
82
|
+
===================
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
# ***************************************************************************
|
|
86
|
+
# Copyright (C) 2014--2015 Benjamin Hackl <benjamin.hackl@aau.at>
|
|
87
|
+
# 2014--2015 Daniel Krenn <dev@danielkrenn.at>
|
|
88
|
+
#
|
|
89
|
+
# This program is free software: you can redistribute it and/or modify
|
|
90
|
+
# it under the terms of the GNU General Public License as published by
|
|
91
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
92
|
+
# (at your option) any later version.
|
|
93
|
+
# https://www.gnu.org/licenses/
|
|
94
|
+
# ***************************************************************************
|
|
95
|
+
|
|
96
|
+
from sage.structure.factory import UniqueFactory
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class CartesianProductFactory(UniqueFactory):
|
|
100
|
+
r"""
|
|
101
|
+
Create various types of Cartesian products depending on its input.
|
|
102
|
+
|
|
103
|
+
INPUT:
|
|
104
|
+
|
|
105
|
+
- ``growth_groups`` -- tuple (or other iterable) of growth groups
|
|
106
|
+
|
|
107
|
+
- ``order`` -- (default: ``None``) if specified, then this order
|
|
108
|
+
is taken for comparing two Cartesian product elements. If ``order`` is
|
|
109
|
+
``None`` this is determined automatically.
|
|
110
|
+
|
|
111
|
+
.. NOTE::
|
|
112
|
+
|
|
113
|
+
The Cartesian product of growth groups is again a growth
|
|
114
|
+
group. In particular, the resulting structure is partially
|
|
115
|
+
ordered.
|
|
116
|
+
|
|
117
|
+
The order on the product is determined as follows:
|
|
118
|
+
|
|
119
|
+
- Cartesian factors with respect to the same variable are
|
|
120
|
+
ordered lexicographically. This causes
|
|
121
|
+
``GrowthGroup('x^ZZ * log(x)^ZZ')`` and
|
|
122
|
+
``GrowthGroup('log(x)^ZZ * x^ZZ')`` to produce two
|
|
123
|
+
different growth groups.
|
|
124
|
+
|
|
125
|
+
- Factors over different variables are equipped with the
|
|
126
|
+
product order (i.e. the comparison is component-wise).
|
|
127
|
+
|
|
128
|
+
Also, note that the sets of variables of the Cartesian
|
|
129
|
+
factors have to be either equal or disjoint.
|
|
130
|
+
|
|
131
|
+
EXAMPLES::
|
|
132
|
+
|
|
133
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
134
|
+
sage: A = GrowthGroup('x^ZZ'); A
|
|
135
|
+
Growth Group x^ZZ
|
|
136
|
+
sage: B = GrowthGroup('log(x)^ZZ'); B
|
|
137
|
+
Growth Group log(x)^ZZ
|
|
138
|
+
sage: C = cartesian_product([A, B]); C # indirect doctest
|
|
139
|
+
Growth Group x^ZZ * log(x)^ZZ
|
|
140
|
+
sage: C._le_ == C.le_lex
|
|
141
|
+
True
|
|
142
|
+
sage: D = GrowthGroup('y^ZZ'); D
|
|
143
|
+
Growth Group y^ZZ
|
|
144
|
+
sage: E = cartesian_product([A, D]); E # indirect doctest
|
|
145
|
+
Growth Group x^ZZ * y^ZZ
|
|
146
|
+
sage: E._le_ == E.le_product
|
|
147
|
+
True
|
|
148
|
+
sage: F = cartesian_product([C, D]); F # indirect doctest
|
|
149
|
+
Growth Group x^ZZ * log(x)^ZZ * y^ZZ
|
|
150
|
+
sage: F._le_ == F.le_product
|
|
151
|
+
True
|
|
152
|
+
sage: cartesian_product([A, E]); G # indirect doctest
|
|
153
|
+
Traceback (most recent call last):
|
|
154
|
+
...
|
|
155
|
+
ValueError: The growth groups (Growth Group x^ZZ, Growth Group x^ZZ * y^ZZ)
|
|
156
|
+
need to have pairwise disjoint or equal variables.
|
|
157
|
+
sage: cartesian_product([A, B, D]) # indirect doctest
|
|
158
|
+
Growth Group x^ZZ * log(x)^ZZ * y^ZZ
|
|
159
|
+
|
|
160
|
+
TESTS::
|
|
161
|
+
|
|
162
|
+
sage: from sage.rings.asymptotic.growth_group_cartesian import CartesianProductFactory
|
|
163
|
+
sage: CartesianProductFactory('factory')([A, B], category=Groups() & Posets())
|
|
164
|
+
Growth Group x^ZZ * log(x)^ZZ
|
|
165
|
+
sage: CartesianProductFactory('factory')([], category=Sets())
|
|
166
|
+
Traceback (most recent call last):
|
|
167
|
+
...
|
|
168
|
+
TypeError: Cannot create Cartesian product without factors.
|
|
169
|
+
|
|
170
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
171
|
+
sage: G1 = GrowthGroup('x^QQ')
|
|
172
|
+
sage: G2 = GrowthGroup('log(x)^ZZ')
|
|
173
|
+
sage: G = cartesian_product([G1, G2])
|
|
174
|
+
sage: cartesian_product([G1, G2], category=G.category()) is G
|
|
175
|
+
True
|
|
176
|
+
"""
|
|
177
|
+
def create_key_and_extra_args(self, growth_groups, category, **kwds):
|
|
178
|
+
r"""
|
|
179
|
+
Given the arguments and keywords, create a key that uniquely
|
|
180
|
+
determines this object.
|
|
181
|
+
|
|
182
|
+
TESTS::
|
|
183
|
+
|
|
184
|
+
sage: from sage.rings.asymptotic.growth_group_cartesian import CartesianProductFactory
|
|
185
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
186
|
+
sage: A = GrowthGroup('x^ZZ')
|
|
187
|
+
sage: CartesianProductFactory('factory').create_key_and_extra_args(
|
|
188
|
+
....: [A], category=Sets(), order='blub')
|
|
189
|
+
(((Growth Group x^ZZ,), Category of posets), {'order': 'blub'})
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
# CartesianProductPosets automatically add Posets() to their categories
|
|
193
|
+
from sage.categories.category import Category
|
|
194
|
+
from sage.categories.posets import Posets
|
|
195
|
+
if not isinstance(category, tuple):
|
|
196
|
+
category = (category,)
|
|
197
|
+
category = Category.join(category + (Posets(),))
|
|
198
|
+
|
|
199
|
+
return (tuple(growth_groups), category), kwds
|
|
200
|
+
|
|
201
|
+
def create_object(self, version, args, **kwds):
|
|
202
|
+
r"""
|
|
203
|
+
Create an object from the given arguments.
|
|
204
|
+
|
|
205
|
+
TESTS::
|
|
206
|
+
|
|
207
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
208
|
+
sage: cartesian_product([GrowthGroup('x^ZZ')]) # indirect doctest
|
|
209
|
+
Growth Group x^ZZ
|
|
210
|
+
"""
|
|
211
|
+
growth_groups, category = args
|
|
212
|
+
if not growth_groups:
|
|
213
|
+
raise TypeError('Cannot create Cartesian product without factors.')
|
|
214
|
+
order = kwds.pop('order', None)
|
|
215
|
+
if order is not None:
|
|
216
|
+
return GenericProduct(growth_groups, category, order=order, **kwds)
|
|
217
|
+
|
|
218
|
+
vg = tuple((g.variable_names(), g) for g in growth_groups)
|
|
219
|
+
|
|
220
|
+
# check if all groups have a variable
|
|
221
|
+
if not all(v for v, _ in vg):
|
|
222
|
+
raise NotImplementedError('Growth groups %s have no variable.' %
|
|
223
|
+
tuple(g for g in growth_groups
|
|
224
|
+
if not g.variable_names()))
|
|
225
|
+
|
|
226
|
+
# sort by variables
|
|
227
|
+
from itertools import groupby, product
|
|
228
|
+
vgs = tuple((v, tuple(gs)) for v, gs in
|
|
229
|
+
groupby(sorted(vg, key=lambda k: k[0]), key=lambda k: k[0]))
|
|
230
|
+
|
|
231
|
+
# check whether variables are pairwise disjoint
|
|
232
|
+
for u, w in product(iter(v for v, _ in vgs), repeat=2):
|
|
233
|
+
if u != w and not set(u).isdisjoint(set(w)):
|
|
234
|
+
raise ValueError('The growth groups %s need to have pairwise '
|
|
235
|
+
'disjoint or equal variables.' % (growth_groups,))
|
|
236
|
+
|
|
237
|
+
# build Cartesian products
|
|
238
|
+
u_groups = list()
|
|
239
|
+
for _, gs in vgs:
|
|
240
|
+
gs = tuple(g for _, g in gs)
|
|
241
|
+
if len(gs) > 1:
|
|
242
|
+
u_groups.append(UnivariateProduct(gs, category, **kwds))
|
|
243
|
+
else:
|
|
244
|
+
u_groups.append(gs[0])
|
|
245
|
+
|
|
246
|
+
if len(u_groups) > 1:
|
|
247
|
+
m_group = MultivariateProduct(tuple(u_groups), category, **kwds)
|
|
248
|
+
else:
|
|
249
|
+
m_group = u_groups[0]
|
|
250
|
+
return m_group
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
CartesianProductGrowthGroups = CartesianProductFactory('CartesianProductGrowthGroups')
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
from sage.combinat.posets.cartesian_product import CartesianProductPoset
|
|
257
|
+
from .growth_group import GenericGrowthGroup
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class GenericProduct(CartesianProductPoset, GenericGrowthGroup):
|
|
261
|
+
r"""
|
|
262
|
+
A Cartesian product of growth groups.
|
|
263
|
+
|
|
264
|
+
EXAMPLES::
|
|
265
|
+
|
|
266
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
267
|
+
sage: P = GrowthGroup('x^QQ')
|
|
268
|
+
sage: L = GrowthGroup('log(x)^ZZ')
|
|
269
|
+
sage: C = cartesian_product([P, L], order='lex'); C # indirect doctest
|
|
270
|
+
Growth Group x^QQ * log(x)^ZZ
|
|
271
|
+
sage: C.an_element()
|
|
272
|
+
x^(1/2)*log(x)
|
|
273
|
+
|
|
274
|
+
::
|
|
275
|
+
|
|
276
|
+
sage: Px = GrowthGroup('x^QQ')
|
|
277
|
+
sage: Lx = GrowthGroup('log(x)^ZZ')
|
|
278
|
+
sage: Cx = cartesian_product([Px, Lx], order='lex') # indirect doctest
|
|
279
|
+
sage: Py = GrowthGroup('y^QQ')
|
|
280
|
+
sage: C = cartesian_product([Cx, Py], order='product'); C # indirect doctest
|
|
281
|
+
Growth Group x^QQ * log(x)^ZZ * y^QQ
|
|
282
|
+
sage: C.an_element()
|
|
283
|
+
x^(1/2)*log(x)*y^(1/2)
|
|
284
|
+
|
|
285
|
+
.. SEEALSO::
|
|
286
|
+
|
|
287
|
+
:class:`~sage.sets.cartesian_product.CartesianProduct`,
|
|
288
|
+
:class:`~sage.combinat.posets.cartesian_product.CartesianProductPoset`.
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
__classcall__ = CartesianProductPoset.__classcall__
|
|
292
|
+
|
|
293
|
+
def __init__(self, sets, category, **kwds):
|
|
294
|
+
r"""
|
|
295
|
+
See :class:`GenericProduct` for details.
|
|
296
|
+
|
|
297
|
+
TESTS::
|
|
298
|
+
|
|
299
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
300
|
+
sage: GrowthGroup('x^ZZ * y^ZZ') # indirect doctest
|
|
301
|
+
Growth Group x^ZZ * y^ZZ
|
|
302
|
+
|
|
303
|
+
Check :issue:`26452`::
|
|
304
|
+
|
|
305
|
+
sage: from sage.rings.asymptotic.growth_group import MonomialGrowthGroup
|
|
306
|
+
sage: R = QQ.extension(x^2+1, 'i')
|
|
307
|
+
sage: P = MonomialGrowthGroup(R, 'w')
|
|
308
|
+
sage: L = MonomialGrowthGroup(ZZ, 'log(w)')
|
|
309
|
+
sage: cartesian_product([P, L])
|
|
310
|
+
Growth Group w^(Number Field in i with defining polynomial x^2 + 1) * log(w)^ZZ
|
|
311
|
+
"""
|
|
312
|
+
order = kwds.pop('order')
|
|
313
|
+
CartesianProductPoset.__init__(self, sets, category, order, **kwds)
|
|
314
|
+
|
|
315
|
+
vars = sum(iter(factor.variable_names()
|
|
316
|
+
for factor in self.cartesian_factors()),
|
|
317
|
+
tuple())
|
|
318
|
+
from itertools import groupby
|
|
319
|
+
from .growth_group import Variable
|
|
320
|
+
Vars = Variable(tuple(v for v, _ in groupby(vars)), repr=self._repr_short_())
|
|
321
|
+
|
|
322
|
+
GenericGrowthGroup.__init__(self, sets[0], Vars, self.category(), **kwds)
|
|
323
|
+
|
|
324
|
+
__hash__ = CartesianProductPoset.__hash__
|
|
325
|
+
|
|
326
|
+
def some_elements(self):
|
|
327
|
+
r"""
|
|
328
|
+
Return some elements of this Cartesian product of growth groups.
|
|
329
|
+
|
|
330
|
+
See :class:`TestSuite` for a typical use case.
|
|
331
|
+
|
|
332
|
+
OUTPUT: an iterator
|
|
333
|
+
|
|
334
|
+
EXAMPLES::
|
|
335
|
+
|
|
336
|
+
sage: from itertools import islice
|
|
337
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
338
|
+
sage: G = GrowthGroup('(QQ_+)^y * x^QQ * log(x)^ZZ')
|
|
339
|
+
sage: tuple(islice(G.some_elements(), 10r))
|
|
340
|
+
(x^(1/2)*(1/2)^y,
|
|
341
|
+
x^(-1/2)*log(x)*2^y,
|
|
342
|
+
x^2*log(x)^(-1),
|
|
343
|
+
x^(-2)*log(x)^2*42^y,
|
|
344
|
+
log(x)^(-2)*(2/3)^y,
|
|
345
|
+
x*log(x)^3*(3/2)^y,
|
|
346
|
+
x^(-1)*log(x)^(-3)*(4/5)^y,
|
|
347
|
+
x^42*log(x)^4*(5/4)^y,
|
|
348
|
+
x^(2/3)*log(x)^(-4)*(6/7)^y,
|
|
349
|
+
x^(-2/3)*log(x)^5*(7/6)^y)
|
|
350
|
+
"""
|
|
351
|
+
return iter(
|
|
352
|
+
self(c) for c in
|
|
353
|
+
zip(*tuple(F.some_elements() for F in self.cartesian_factors())))
|
|
354
|
+
|
|
355
|
+
def _create_element_in_extension_(self, element):
|
|
356
|
+
r"""
|
|
357
|
+
Create an element in an extension of this Cartesian product of
|
|
358
|
+
growth groups which is chosen according to the input ``element``.
|
|
359
|
+
|
|
360
|
+
INPUT:
|
|
361
|
+
|
|
362
|
+
- ``element`` -- tuple
|
|
363
|
+
|
|
364
|
+
OUTPUT: an element
|
|
365
|
+
|
|
366
|
+
EXAMPLES::
|
|
367
|
+
|
|
368
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
369
|
+
sage: G = GrowthGroup('z^ZZ * log(z)^ZZ')
|
|
370
|
+
sage: z = G('z')[0]
|
|
371
|
+
sage: lz = G('log(z)')[1]
|
|
372
|
+
sage: G._create_element_in_extension_((z^3, lz)).parent()
|
|
373
|
+
Growth Group z^ZZ * log(z)^ZZ
|
|
374
|
+
sage: G._create_element_in_extension_((z^(1/2), lz)).parent()
|
|
375
|
+
Growth Group z^QQ * log(z)^ZZ
|
|
376
|
+
|
|
377
|
+
::
|
|
378
|
+
|
|
379
|
+
sage: G._create_element_in_extension_((3, 3, 3))
|
|
380
|
+
Traceback (most recent call last):
|
|
381
|
+
...
|
|
382
|
+
ValueError: Cannot create (3, 3, 3) as a Cartesian product like
|
|
383
|
+
Growth Group z^ZZ * log(z)^ZZ.
|
|
384
|
+
"""
|
|
385
|
+
factors = self.cartesian_factors()
|
|
386
|
+
if len(element) != len(factors):
|
|
387
|
+
raise ValueError('Cannot create %s as a Cartesian product like %s.' %
|
|
388
|
+
(element, self))
|
|
389
|
+
|
|
390
|
+
if all(n.parent() is f for n, f in zip(element, factors)):
|
|
391
|
+
parent = self
|
|
392
|
+
else:
|
|
393
|
+
parent = self._underlying_class()(tuple(n.parent() for n in element),
|
|
394
|
+
category=self.category())
|
|
395
|
+
return parent(element)
|
|
396
|
+
|
|
397
|
+
def _element_constructor_(self, data):
|
|
398
|
+
r"""
|
|
399
|
+
Convert the given object to an element of this Cartesian product.
|
|
400
|
+
|
|
401
|
+
EXAMPLES::
|
|
402
|
+
|
|
403
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
404
|
+
sage: G = GrowthGroup('x^ZZ * y^ZZ')
|
|
405
|
+
sage: G_log = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ')
|
|
406
|
+
|
|
407
|
+
Conversion from the symbolic ring works::
|
|
408
|
+
|
|
409
|
+
sage: x,y = var('x y')
|
|
410
|
+
sage: G(x^-3*y^2)
|
|
411
|
+
x^(-3)*y^2
|
|
412
|
+
sage: G(x^4), G(y^2)
|
|
413
|
+
(x^4, y^2)
|
|
414
|
+
sage: G(1)
|
|
415
|
+
1
|
|
416
|
+
|
|
417
|
+
Even more complex expressions can be parsed::
|
|
418
|
+
|
|
419
|
+
sage: G_log(x^42*log(x)^-42*y^42)
|
|
420
|
+
x^42*log(x)^(-42)*y^42
|
|
421
|
+
|
|
422
|
+
TESTS::
|
|
423
|
+
|
|
424
|
+
sage: G = GrowthGroup('x^ZZ * y^ZZ')
|
|
425
|
+
sage: G('x'), G('y')
|
|
426
|
+
(x, y)
|
|
427
|
+
|
|
428
|
+
::
|
|
429
|
+
|
|
430
|
+
sage: G_log(log(x))
|
|
431
|
+
log(x)
|
|
432
|
+
|
|
433
|
+
::
|
|
434
|
+
|
|
435
|
+
sage: G(G.cartesian_factors()[0].gen())
|
|
436
|
+
x
|
|
437
|
+
|
|
438
|
+
::
|
|
439
|
+
|
|
440
|
+
sage: GrowthGroup('QQ^x * x^QQ')(['x^(1/2)'])
|
|
441
|
+
x^(1/2)
|
|
442
|
+
sage: l = GrowthGroup('x^ZZ * log(x)^ZZ')(['x', 'log(x)']); l
|
|
443
|
+
x*log(x)
|
|
444
|
+
sage: type(l)
|
|
445
|
+
<class 'sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct_with_category.element_class'>
|
|
446
|
+
sage: GrowthGroup('(QQ_+)^x * x^QQ')(['2^log(x)'])
|
|
447
|
+
Traceback (most recent call last):
|
|
448
|
+
...
|
|
449
|
+
ValueError: ['2^log(x)'] is not in Growth Group QQ^x * x^QQ.
|
|
450
|
+
> *previous* ValueError: 2^log(x) is not in any of the factors of
|
|
451
|
+
Growth Group QQ^x * x^QQ
|
|
452
|
+
>> *previous* ValueError: 2^log(x) is not in Growth Group QQ^x.
|
|
453
|
+
>> *and* ValueError: 2^log(x) is not in Growth Group x^QQ.
|
|
454
|
+
sage: GrowthGroup('(QQ_+)^x * x^QQ')(['2^log(x)', 'x^55'])
|
|
455
|
+
Traceback (most recent call last):
|
|
456
|
+
...
|
|
457
|
+
ValueError: ['2^log(x)', 'x^55'] is not in Growth Group QQ^x * x^QQ.
|
|
458
|
+
> *previous* ValueError: 2^log(x) is not in any of the factors of
|
|
459
|
+
Growth Group QQ^x * x^QQ
|
|
460
|
+
>> *previous* ValueError: 2^log(x) is not in Growth Group QQ^x.
|
|
461
|
+
>> *and* ValueError: 2^log(x) is not in Growth Group x^QQ.
|
|
462
|
+
|
|
463
|
+
::
|
|
464
|
+
|
|
465
|
+
sage: n = GrowthGroup('n^ZZ * log(n)^ZZ')('n')
|
|
466
|
+
sage: G = GrowthGroup('(QQ_+)^n * n^ZZ * log(n)^ZZ')
|
|
467
|
+
sage: G(n).value
|
|
468
|
+
(1, n, 1)
|
|
469
|
+
"""
|
|
470
|
+
from sage.sets.cartesian_product import CartesianProduct
|
|
471
|
+
from sage.symbolic.ring import SR
|
|
472
|
+
|
|
473
|
+
def convert_factors(data, raw_data):
|
|
474
|
+
try:
|
|
475
|
+
return self._convert_factors_(data)
|
|
476
|
+
except ValueError as e:
|
|
477
|
+
from .misc import combine_exceptions
|
|
478
|
+
raise combine_exceptions(
|
|
479
|
+
ValueError('%s is not in %s.' % (raw_data, self)), e)
|
|
480
|
+
|
|
481
|
+
if data == 1:
|
|
482
|
+
return self.one()
|
|
483
|
+
|
|
484
|
+
elif data is None:
|
|
485
|
+
raise ValueError('%s cannot be converted.' % (data,))
|
|
486
|
+
|
|
487
|
+
elif type(data) is self.element_class and data.parent() == self:
|
|
488
|
+
return data
|
|
489
|
+
|
|
490
|
+
elif isinstance(data, str):
|
|
491
|
+
from .misc import split_str_by_op
|
|
492
|
+
return convert_factors(split_str_by_op(data, '*'), data)
|
|
493
|
+
|
|
494
|
+
elif hasattr(data, 'parent'):
|
|
495
|
+
P = data.parent()
|
|
496
|
+
|
|
497
|
+
if P is self:
|
|
498
|
+
return data
|
|
499
|
+
|
|
500
|
+
elif P is SR:
|
|
501
|
+
from sage.symbolic.operators import mul_vararg
|
|
502
|
+
if data.operator() == mul_vararg:
|
|
503
|
+
return convert_factors(data.operands(), data)
|
|
504
|
+
|
|
505
|
+
# room for other parents (e.g. polynomial ring et al.)
|
|
506
|
+
|
|
507
|
+
try:
|
|
508
|
+
return super()._element_constructor_(data)
|
|
509
|
+
except (TypeError, ValueError):
|
|
510
|
+
pass
|
|
511
|
+
if isinstance(data, (tuple, list, CartesianProduct.Element)):
|
|
512
|
+
return convert_factors(tuple(data), data)
|
|
513
|
+
|
|
514
|
+
return convert_factors((data,), data)
|
|
515
|
+
|
|
516
|
+
_repr_ = GenericGrowthGroup._repr_
|
|
517
|
+
|
|
518
|
+
def _repr_short_(self):
|
|
519
|
+
r"""
|
|
520
|
+
A short (shorter than :meth:`._repr_`) representation string
|
|
521
|
+
for this Cartesian product of growth groups.
|
|
522
|
+
|
|
523
|
+
OUTPUT: string
|
|
524
|
+
|
|
525
|
+
EXAMPLES::
|
|
526
|
+
|
|
527
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
528
|
+
sage: P = GrowthGroup('x^QQ')
|
|
529
|
+
sage: L = GrowthGroup('log(x)^ZZ')
|
|
530
|
+
sage: cartesian_product([P, L], order='lex')._repr_short_()
|
|
531
|
+
'x^QQ * log(x)^ZZ'
|
|
532
|
+
"""
|
|
533
|
+
return ' * '.join(S._repr_short_() for S in self.cartesian_factors())
|
|
534
|
+
|
|
535
|
+
def _convert_factors_(self, factors):
|
|
536
|
+
r"""
|
|
537
|
+
Helper method. Try to convert some ``factors`` to an
|
|
538
|
+
element of one of the Cartesian factors and return the product of
|
|
539
|
+
all these factors.
|
|
540
|
+
|
|
541
|
+
INPUT:
|
|
542
|
+
|
|
543
|
+
- ``factors`` -- tuple or other iterable
|
|
544
|
+
|
|
545
|
+
OUTPUT: an element of this Cartesian product
|
|
546
|
+
|
|
547
|
+
EXAMPLES::
|
|
548
|
+
|
|
549
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
550
|
+
sage: G = GrowthGroup('x^ZZ * log(x)^QQ * y^QQ')
|
|
551
|
+
sage: e1 = G._convert_factors_([x^2])
|
|
552
|
+
sage: (e1, e1.parent())
|
|
553
|
+
(x^2, Growth Group x^ZZ * log(x)^QQ * y^QQ)
|
|
554
|
+
|
|
555
|
+
::
|
|
556
|
+
|
|
557
|
+
sage: G = GrowthGroup('(QQ_+)^n * n^ZZ * UU^n')
|
|
558
|
+
sage: n = SR.var('n')
|
|
559
|
+
sage: G((-2)^n)
|
|
560
|
+
2^n*(-1)^n
|
|
561
|
+
"""
|
|
562
|
+
from sage.misc.misc_c import prod
|
|
563
|
+
from .growth_group import PartialConversionValueError
|
|
564
|
+
from .misc import combine_exceptions
|
|
565
|
+
|
|
566
|
+
def get_factors(data):
|
|
567
|
+
result = []
|
|
568
|
+
errors = []
|
|
569
|
+
for factor in self.cartesian_factors():
|
|
570
|
+
try:
|
|
571
|
+
try:
|
|
572
|
+
result.append((factor, factor(data)))
|
|
573
|
+
break
|
|
574
|
+
except PartialConversionValueError as e:
|
|
575
|
+
try:
|
|
576
|
+
element, todo = e.element.split()
|
|
577
|
+
except NotImplementedError as nie:
|
|
578
|
+
raise combine_exceptions(
|
|
579
|
+
ValueError('cannot split {}: no splitting '
|
|
580
|
+
'implemented'.format(e.element)),
|
|
581
|
+
nie)
|
|
582
|
+
except ValueError as ve:
|
|
583
|
+
raise combine_exceptions(
|
|
584
|
+
ValueError('cannot split {} after failed '
|
|
585
|
+
'conversion into element of '
|
|
586
|
+
'{}'.format(e.element, factor)),
|
|
587
|
+
ve)
|
|
588
|
+
assert todo is not None
|
|
589
|
+
result.append((factor, element))
|
|
590
|
+
data = todo
|
|
591
|
+
except (ValueError, TypeError) as error:
|
|
592
|
+
errors.append(error)
|
|
593
|
+
if not result:
|
|
594
|
+
raise combine_exceptions(
|
|
595
|
+
ValueError('%s is not in any of the factors of %s' % (data, self)),
|
|
596
|
+
*errors)
|
|
597
|
+
return result
|
|
598
|
+
|
|
599
|
+
return prod(self.cartesian_injection(*fs)
|
|
600
|
+
for f in factors for fs in get_factors(f))
|
|
601
|
+
|
|
602
|
+
def cartesian_injection(self, factor, element):
|
|
603
|
+
r"""
|
|
604
|
+
Inject the given element into this Cartesian product at the given factor.
|
|
605
|
+
|
|
606
|
+
INPUT:
|
|
607
|
+
|
|
608
|
+
- ``factor`` -- a growth group (a factor of this Cartesian product)
|
|
609
|
+
|
|
610
|
+
- ``element`` -- an element of ``factor``
|
|
611
|
+
|
|
612
|
+
OUTPUT: an element of this Cartesian product
|
|
613
|
+
|
|
614
|
+
TESTS::
|
|
615
|
+
|
|
616
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
617
|
+
sage: G = GrowthGroup('x^ZZ * y^QQ')
|
|
618
|
+
sage: G.cartesian_injection(G.cartesian_factors()[1], 'y^7')
|
|
619
|
+
y^7
|
|
620
|
+
"""
|
|
621
|
+
return self(tuple((f.one() if f != factor else element)
|
|
622
|
+
for f in self.cartesian_factors()))
|
|
623
|
+
|
|
624
|
+
def _coerce_map_from_(self, S):
|
|
625
|
+
r"""
|
|
626
|
+
Return whether ``S`` coerces into this growth group.
|
|
627
|
+
|
|
628
|
+
INPUT:
|
|
629
|
+
|
|
630
|
+
- ``S`` -- a parent
|
|
631
|
+
|
|
632
|
+
OUTPUT: boolean
|
|
633
|
+
|
|
634
|
+
TESTS::
|
|
635
|
+
|
|
636
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
637
|
+
sage: A = GrowthGroup('QQ^x * x^QQ')
|
|
638
|
+
sage: B = GrowthGroup('QQ^x * x^ZZ')
|
|
639
|
+
sage: A.has_coerce_map_from(B) # indirect doctest
|
|
640
|
+
True
|
|
641
|
+
sage: B.has_coerce_map_from(A) # indirect doctest
|
|
642
|
+
False
|
|
643
|
+
"""
|
|
644
|
+
if CartesianProductPoset.has_coerce_map_from(self, S):
|
|
645
|
+
return True
|
|
646
|
+
|
|
647
|
+
elif isinstance(S, GenericProduct):
|
|
648
|
+
factors = S.cartesian_factors()
|
|
649
|
+
else:
|
|
650
|
+
factors = (S,)
|
|
651
|
+
|
|
652
|
+
if all(any(g.has_coerce_map_from(f) for g in self.cartesian_factors())
|
|
653
|
+
for f in factors):
|
|
654
|
+
return True
|
|
655
|
+
|
|
656
|
+
def _pushout_(self, other):
|
|
657
|
+
r"""
|
|
658
|
+
Construct the pushout of this and the other growth group. This is called by
|
|
659
|
+
:func:`sage.categories.pushout.pushout`.
|
|
660
|
+
|
|
661
|
+
TESTS::
|
|
662
|
+
|
|
663
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
664
|
+
sage: from sage.categories.pushout import pushout
|
|
665
|
+
sage: cm = sage.structure.element.get_coercion_model()
|
|
666
|
+
sage: A = GrowthGroup('(QQ_+)^x * x^ZZ')
|
|
667
|
+
sage: B = GrowthGroup('x^ZZ * log(x)^ZZ')
|
|
668
|
+
sage: A._pushout_(B)
|
|
669
|
+
Growth Group QQ^x * x^ZZ * log(x)^ZZ
|
|
670
|
+
sage: pushout(A, B)
|
|
671
|
+
Growth Group QQ^x * x^ZZ * log(x)^ZZ
|
|
672
|
+
sage: cm.discover_coercion(A, B)
|
|
673
|
+
((map internal to coercion system -- copy before use)
|
|
674
|
+
Coercion map:
|
|
675
|
+
From: Growth Group QQ^x * x^ZZ
|
|
676
|
+
To: Growth Group QQ^x * x^ZZ * log(x)^ZZ,
|
|
677
|
+
(map internal to coercion system -- copy before use)
|
|
678
|
+
Coercion map:
|
|
679
|
+
From: Growth Group x^ZZ * log(x)^ZZ
|
|
680
|
+
To: Growth Group QQ^x * x^ZZ * log(x)^ZZ)
|
|
681
|
+
sage: cm.common_parent(A, B)
|
|
682
|
+
Growth Group QQ^x * x^ZZ * log(x)^ZZ
|
|
683
|
+
|
|
684
|
+
::
|
|
685
|
+
|
|
686
|
+
sage: C = GrowthGroup('(QQ_+)^x * x^QQ * y^ZZ')
|
|
687
|
+
sage: D = GrowthGroup('x^ZZ * log(x)^QQ * (QQ_+)^z')
|
|
688
|
+
sage: C._pushout_(D)
|
|
689
|
+
Growth Group QQ^x * x^QQ * log(x)^QQ * y^ZZ * QQ^z
|
|
690
|
+
sage: cm.common_parent(C, D)
|
|
691
|
+
Growth Group QQ^x * x^QQ * log(x)^QQ * y^ZZ * QQ^z
|
|
692
|
+
sage: A._pushout_(D)
|
|
693
|
+
Growth Group QQ^x * x^ZZ * log(x)^QQ * QQ^z
|
|
694
|
+
sage: cm.common_parent(A, D)
|
|
695
|
+
Growth Group QQ^x * x^ZZ * log(x)^QQ * QQ^z
|
|
696
|
+
sage: cm.common_parent(B, D)
|
|
697
|
+
Growth Group x^ZZ * log(x)^QQ * QQ^z
|
|
698
|
+
sage: cm.common_parent(A, C)
|
|
699
|
+
Growth Group QQ^x * x^QQ * y^ZZ
|
|
700
|
+
sage: E = GrowthGroup('log(x)^ZZ * y^ZZ')
|
|
701
|
+
sage: cm.common_parent(A, E)
|
|
702
|
+
Traceback (most recent call last):
|
|
703
|
+
...
|
|
704
|
+
TypeError: no common canonical parent for objects with parents:
|
|
705
|
+
'Growth Group QQ^x * x^ZZ' and 'Growth Group log(x)^ZZ * y^ZZ'
|
|
706
|
+
|
|
707
|
+
::
|
|
708
|
+
|
|
709
|
+
sage: F = GrowthGroup('z^QQ')
|
|
710
|
+
sage: pushout(C, F)
|
|
711
|
+
Growth Group QQ^x * x^QQ * y^ZZ * z^QQ
|
|
712
|
+
|
|
713
|
+
::
|
|
714
|
+
|
|
715
|
+
sage: pushout(GrowthGroup('(QQ_+)^x * x^ZZ'), GrowthGroup('(ZZ_+)^x * x^QQ'))
|
|
716
|
+
Growth Group QQ^x * x^QQ
|
|
717
|
+
sage: cm.common_parent(GrowthGroup('(QQ_+)^x * x^ZZ'), GrowthGroup('(ZZ_+)^x * x^QQ'))
|
|
718
|
+
Growth Group QQ^x * x^QQ
|
|
719
|
+
|
|
720
|
+
::
|
|
721
|
+
|
|
722
|
+
sage: pushout(GrowthGroup('(QQ_+)^n * n^QQ'), GrowthGroup('(SR_+)^n'))
|
|
723
|
+
Growth Group SR^n * n^QQ
|
|
724
|
+
|
|
725
|
+
::
|
|
726
|
+
|
|
727
|
+
sage: cm.common_parent(GrowthGroup('n^ZZ * log(n)^ZZ * UU^n'),
|
|
728
|
+
....: GrowthGroup('n^QQ * UU^n'))
|
|
729
|
+
Growth Group n^QQ * log(n)^ZZ * UU^n
|
|
730
|
+
"""
|
|
731
|
+
from .growth_group import GenericGrowthGroup, AbstractGrowthGroupFunctor
|
|
732
|
+
from .misc import bidirectional_merge_sorted
|
|
733
|
+
from sage.structure.element import get_coercion_model
|
|
734
|
+
|
|
735
|
+
Sfactors = self.cartesian_factors()
|
|
736
|
+
if isinstance(other, GenericProduct):
|
|
737
|
+
Ofactors = other.cartesian_factors()
|
|
738
|
+
elif isinstance(other, GenericGrowthGroup):
|
|
739
|
+
Ofactors = (other,)
|
|
740
|
+
elif (other.construction() is not None and
|
|
741
|
+
isinstance(other.construction()[0], AbstractGrowthGroupFunctor)):
|
|
742
|
+
Ofactors = (other,)
|
|
743
|
+
else:
|
|
744
|
+
return
|
|
745
|
+
|
|
746
|
+
def pushout_univariate_factors(self, other, var, Sfactors, Ofactors):
|
|
747
|
+
try:
|
|
748
|
+
return bidirectional_merge_sorted(
|
|
749
|
+
Sfactors, Ofactors,
|
|
750
|
+
lambda f: (f._underlying_class(), f._var_.var_repr))
|
|
751
|
+
except RuntimeError:
|
|
752
|
+
pass
|
|
753
|
+
|
|
754
|
+
cm = get_coercion_model()
|
|
755
|
+
try:
|
|
756
|
+
Z = cm.common_parent(*Sfactors+Ofactors)
|
|
757
|
+
return (Z,), (Z,)
|
|
758
|
+
except TypeError:
|
|
759
|
+
pass
|
|
760
|
+
|
|
761
|
+
def subfactors(F):
|
|
762
|
+
for f in F:
|
|
763
|
+
if isinstance(f, GenericProduct):
|
|
764
|
+
yield from subfactors(f.cartesian_factors())
|
|
765
|
+
else:
|
|
766
|
+
yield f
|
|
767
|
+
|
|
768
|
+
try:
|
|
769
|
+
return bidirectional_merge_sorted(
|
|
770
|
+
tuple(subfactors(Sfactors)), tuple(subfactors(Ofactors)),
|
|
771
|
+
lambda f: (f._underlying_class(), f._var_.var_repr))
|
|
772
|
+
except RuntimeError:
|
|
773
|
+
pass
|
|
774
|
+
|
|
775
|
+
from sage.structure.coerce_exceptions import CoercionException
|
|
776
|
+
raise CoercionException(
|
|
777
|
+
'Cannot construct the pushout of %s and %s: The factors '
|
|
778
|
+
'with variables %s are not overlapping, '
|
|
779
|
+
'no common parent was found, and '
|
|
780
|
+
'splitting the factors was unsuccessful.' % (self, other, var))
|
|
781
|
+
|
|
782
|
+
# A wrapper around an iterator that stores additional intermediate data.
|
|
783
|
+
# This deviates slightly from the iterator protocol:
|
|
784
|
+
# At the end of the iteration the data is reset to None instead
|
|
785
|
+
# of raising a StopIteration.
|
|
786
|
+
class it:
|
|
787
|
+
def __init__(self, it):
|
|
788
|
+
self.it = it
|
|
789
|
+
self.var = None
|
|
790
|
+
self.factors = None
|
|
791
|
+
|
|
792
|
+
def next_custom(self):
|
|
793
|
+
try:
|
|
794
|
+
self.var, factors = next(self.it)
|
|
795
|
+
self.factors = tuple(factors)
|
|
796
|
+
except StopIteration:
|
|
797
|
+
self.var = None
|
|
798
|
+
self.factors = tuple()
|
|
799
|
+
|
|
800
|
+
from itertools import groupby
|
|
801
|
+
S = it(groupby(Sfactors, key=lambda k: k.variable_names()))
|
|
802
|
+
O = it(groupby(Ofactors, key=lambda k: k.variable_names()))
|
|
803
|
+
|
|
804
|
+
newS = []
|
|
805
|
+
newO = []
|
|
806
|
+
|
|
807
|
+
S.next_custom()
|
|
808
|
+
O.next_custom()
|
|
809
|
+
while S.var is not None or O.var is not None:
|
|
810
|
+
if S.var is not None and O.var is not None and S.var < O.var:
|
|
811
|
+
newS.extend(S.factors)
|
|
812
|
+
newO.extend(S.factors)
|
|
813
|
+
S.next_custom()
|
|
814
|
+
elif S.var is not None and O.var is not None and S.var > O.var:
|
|
815
|
+
newS.extend(O.factors)
|
|
816
|
+
newO.extend(O.factors)
|
|
817
|
+
O.next_custom()
|
|
818
|
+
else:
|
|
819
|
+
SL, OL = pushout_univariate_factors(self, other, S.var,
|
|
820
|
+
S.factors, O.factors)
|
|
821
|
+
newS.extend(SL)
|
|
822
|
+
newO.extend(OL)
|
|
823
|
+
S.next_custom()
|
|
824
|
+
O.next_custom()
|
|
825
|
+
|
|
826
|
+
assert (len(newS) == len(newO))
|
|
827
|
+
|
|
828
|
+
if (len(Sfactors) == len(newS) and
|
|
829
|
+
len(Ofactors) == len(newO)):
|
|
830
|
+
# We had already all factors in each of self and
|
|
831
|
+
# other, thus splitting it in subproblems (one for
|
|
832
|
+
# each factor) is the strategy to use. If a pushout is
|
|
833
|
+
# possible :func:`sage.categories.pushout.pushout`
|
|
834
|
+
# will manage this by itself.
|
|
835
|
+
return
|
|
836
|
+
|
|
837
|
+
from sage.categories.pushout import pushout
|
|
838
|
+
from sage.categories.cartesian_product import cartesian_product
|
|
839
|
+
return pushout(cartesian_product(newS), cartesian_product(newO))
|
|
840
|
+
|
|
841
|
+
def gens_monomial(self) -> tuple:
|
|
842
|
+
r"""
|
|
843
|
+
Return a tuple containing monomial generators of this growth group.
|
|
844
|
+
|
|
845
|
+
OUTPUT: a tuple containing elements of this growth group
|
|
846
|
+
|
|
847
|
+
.. NOTE::
|
|
848
|
+
|
|
849
|
+
This method calls the ``gens_monomial()`` method on the
|
|
850
|
+
individual factors of this Cartesian product and
|
|
851
|
+
concatenates the respective outputs.
|
|
852
|
+
|
|
853
|
+
EXAMPLES::
|
|
854
|
+
|
|
855
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
856
|
+
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ')
|
|
857
|
+
sage: G.gens_monomial()
|
|
858
|
+
(x, y)
|
|
859
|
+
|
|
860
|
+
TESTS::
|
|
861
|
+
|
|
862
|
+
sage: all(g.parent() == G for g in G.gens_monomial())
|
|
863
|
+
True
|
|
864
|
+
"""
|
|
865
|
+
return sum(iter(
|
|
866
|
+
tuple(self.cartesian_injection(factor, g) for g in factor.gens_monomial())
|
|
867
|
+
for factor in self.cartesian_factors()),
|
|
868
|
+
tuple())
|
|
869
|
+
|
|
870
|
+
def variable_names(self):
|
|
871
|
+
r"""
|
|
872
|
+
Return the names of the variables.
|
|
873
|
+
|
|
874
|
+
OUTPUT: a tuple of strings
|
|
875
|
+
|
|
876
|
+
EXAMPLES::
|
|
877
|
+
|
|
878
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
879
|
+
sage: GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ').variable_names()
|
|
880
|
+
('x', 'y', 'z')
|
|
881
|
+
"""
|
|
882
|
+
vars = sum(iter(factor.variable_names()
|
|
883
|
+
for factor in self.cartesian_factors()),
|
|
884
|
+
tuple())
|
|
885
|
+
from itertools import groupby
|
|
886
|
+
return tuple(v for v, _ in groupby(vars))
|
|
887
|
+
|
|
888
|
+
class Element(CartesianProductPoset.Element):
|
|
889
|
+
|
|
890
|
+
from .growth_group import _is_lt_one_
|
|
891
|
+
is_lt_one = _is_lt_one_
|
|
892
|
+
|
|
893
|
+
def _repr_(self, latex=False):
|
|
894
|
+
r"""
|
|
895
|
+
A representation string for this Cartesian product element.
|
|
896
|
+
|
|
897
|
+
INPUT:
|
|
898
|
+
|
|
899
|
+
- ``latex`` -- boolean (default: ``False``); if set, then
|
|
900
|
+
LaTeX-output is returned
|
|
901
|
+
|
|
902
|
+
OUTPUT: string
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
907
|
+
sage: P = GrowthGroup('x^QQ')
|
|
908
|
+
sage: L = GrowthGroup('log(x)^ZZ')
|
|
909
|
+
sage: cartesian_product([P, L], order='lex').an_element()._repr_()
|
|
910
|
+
'x^(1/2)*log(x)'
|
|
911
|
+
"""
|
|
912
|
+
if latex:
|
|
913
|
+
from sage.misc.latex import latex as latex_repr
|
|
914
|
+
f = latex_repr
|
|
915
|
+
else:
|
|
916
|
+
f = repr
|
|
917
|
+
|
|
918
|
+
mul = ' ' if latex else '*'
|
|
919
|
+
s = mul.join(f(v) for v in self.value if not v.is_one())
|
|
920
|
+
if s == '':
|
|
921
|
+
return '1'
|
|
922
|
+
return s
|
|
923
|
+
|
|
924
|
+
def _latex_(self):
|
|
925
|
+
r"""
|
|
926
|
+
A representation string for this Cartesian product element.
|
|
927
|
+
|
|
928
|
+
OUTPUT: string
|
|
929
|
+
|
|
930
|
+
TESTS::
|
|
931
|
+
|
|
932
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
933
|
+
sage: P = GrowthGroup('x^QQ')
|
|
934
|
+
sage: L = GrowthGroup('log(x)^ZZ')
|
|
935
|
+
sage: latex(cartesian_product([P, L], order='lex').an_element()) # indirect doctest
|
|
936
|
+
x^{\frac{1}{2}} \log\left(x\right)
|
|
937
|
+
sage: latex(GrowthGroup('(QQ_+)^n * n^QQ').an_element()) # indirect doctest
|
|
938
|
+
\left(\frac{1}{2}\right)^{n} n^{\frac{1}{2}}
|
|
939
|
+
"""
|
|
940
|
+
return self._repr_(latex=True)
|
|
941
|
+
|
|
942
|
+
def __pow__(self, exponent):
|
|
943
|
+
r"""
|
|
944
|
+
Calculate the power of this growth element to the given
|
|
945
|
+
``exponent``.
|
|
946
|
+
|
|
947
|
+
INPUT:
|
|
948
|
+
|
|
949
|
+
- ``exponent`` -- a number
|
|
950
|
+
|
|
951
|
+
OUTPUT: a growth element
|
|
952
|
+
|
|
953
|
+
EXAMPLES::
|
|
954
|
+
|
|
955
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
956
|
+
sage: G = GrowthGroup('x^ZZ * y^QQ * z^ZZ')
|
|
957
|
+
sage: x, y, z = G.gens_monomial()
|
|
958
|
+
sage: (x^5 * y * z^5)^(1/5) # indirect doctest
|
|
959
|
+
x*y^(1/5)*z
|
|
960
|
+
|
|
961
|
+
::
|
|
962
|
+
|
|
963
|
+
sage: G = GrowthGroup('x^QQ * log(x)^QQ'); x = G('x')
|
|
964
|
+
sage: (x^(21/5) * log(x)^7)^(1/42) # indirect doctest
|
|
965
|
+
x^(1/10)*log(x)^(1/6)
|
|
966
|
+
"""
|
|
967
|
+
return self.parent()._create_element_in_extension_(
|
|
968
|
+
tuple(x ** exponent for x in self.cartesian_factors()))
|
|
969
|
+
|
|
970
|
+
def factors(self):
|
|
971
|
+
r"""
|
|
972
|
+
Return the atomic factors of this growth element. An atomic factor
|
|
973
|
+
cannot be split further and is not the identity (`1`).
|
|
974
|
+
|
|
975
|
+
OUTPUT: a tuple of growth elements
|
|
976
|
+
|
|
977
|
+
EXAMPLES::
|
|
978
|
+
|
|
979
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
980
|
+
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ')
|
|
981
|
+
sage: x, y = G.gens_monomial()
|
|
982
|
+
sage: x.factors()
|
|
983
|
+
(x,)
|
|
984
|
+
sage: f = (x * y).factors(); f
|
|
985
|
+
(x, y)
|
|
986
|
+
sage: tuple(factor.parent() for factor in f)
|
|
987
|
+
(Growth Group x^ZZ, Growth Group y^ZZ)
|
|
988
|
+
sage: f = (x * log(x)).factors(); f
|
|
989
|
+
(x, log(x))
|
|
990
|
+
sage: tuple(factor.parent() for factor in f)
|
|
991
|
+
(Growth Group x^ZZ, Growth Group log(x)^ZZ)
|
|
992
|
+
|
|
993
|
+
::
|
|
994
|
+
|
|
995
|
+
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ * y^QQ')
|
|
996
|
+
sage: x, y = G.gens_monomial()
|
|
997
|
+
sage: f = (x * log(x) * y).factors(); f
|
|
998
|
+
(x, log(x), y)
|
|
999
|
+
sage: tuple(factor.parent() for factor in f)
|
|
1000
|
+
(Growth Group x^ZZ, Growth Group log(x)^ZZ, Growth Group y^QQ)
|
|
1001
|
+
|
|
1002
|
+
::
|
|
1003
|
+
|
|
1004
|
+
sage: G.one().factors()
|
|
1005
|
+
()
|
|
1006
|
+
"""
|
|
1007
|
+
return sum(iter(f.factors()
|
|
1008
|
+
for f in self.cartesian_factors()
|
|
1009
|
+
if not f.is_one()),
|
|
1010
|
+
tuple())
|
|
1011
|
+
|
|
1012
|
+
from .growth_group import _log_factor_, _log_
|
|
1013
|
+
log = _log_
|
|
1014
|
+
log_factor = _log_factor_
|
|
1015
|
+
|
|
1016
|
+
def _log_factor_(self, base=None, locals=None):
|
|
1017
|
+
r"""
|
|
1018
|
+
Helper method for calculating the logarithm of the factorization
|
|
1019
|
+
of this element.
|
|
1020
|
+
|
|
1021
|
+
INPUT:
|
|
1022
|
+
|
|
1023
|
+
- ``base`` -- the base of the logarithm; if ``None``
|
|
1024
|
+
(default value) is used, the natural logarithm is taken
|
|
1025
|
+
|
|
1026
|
+
- ``locals`` -- dictionary which may contain the following keys and
|
|
1027
|
+
values:
|
|
1028
|
+
|
|
1029
|
+
- ``'log'`` -- value: a function; if not used, then the usual
|
|
1030
|
+
:class:`log <sage.functions.log.Function_log>` is taken
|
|
1031
|
+
|
|
1032
|
+
OUTPUT:
|
|
1033
|
+
|
|
1034
|
+
A tuple of pairs, where the first entry is either a growth
|
|
1035
|
+
element or something out of which we can construct a growth element
|
|
1036
|
+
and the second a multiplicative coefficient.
|
|
1037
|
+
|
|
1038
|
+
TESTS::
|
|
1039
|
+
|
|
1040
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1041
|
+
sage: G = GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ')
|
|
1042
|
+
sage: x, y = G.gens_monomial()
|
|
1043
|
+
sage: (x * y).log_factor() # indirect doctest
|
|
1044
|
+
((log(x), 1), (log(y), 1))
|
|
1045
|
+
"""
|
|
1046
|
+
if self.is_one():
|
|
1047
|
+
return tuple()
|
|
1048
|
+
|
|
1049
|
+
def try_create_growth(g):
|
|
1050
|
+
try:
|
|
1051
|
+
return self.parent()(g)
|
|
1052
|
+
except (TypeError, ValueError):
|
|
1053
|
+
return g
|
|
1054
|
+
|
|
1055
|
+
try:
|
|
1056
|
+
return sum(iter(tuple((try_create_growth(g), c)
|
|
1057
|
+
for g, c in
|
|
1058
|
+
factor._log_factor_(base=base,
|
|
1059
|
+
locals=locals))
|
|
1060
|
+
for factor in self.cartesian_factors()
|
|
1061
|
+
if factor != factor.parent().one()),
|
|
1062
|
+
tuple())
|
|
1063
|
+
except (ArithmeticError, TypeError, ValueError) as e:
|
|
1064
|
+
from .misc import combine_exceptions
|
|
1065
|
+
raise combine_exceptions(
|
|
1066
|
+
ArithmeticError('Cannot build log(%s) in %s.' %
|
|
1067
|
+
(self, self.parent())), e)
|
|
1068
|
+
|
|
1069
|
+
from .growth_group import _rpow_
|
|
1070
|
+
rpow = _rpow_
|
|
1071
|
+
|
|
1072
|
+
def _rpow_element_(self, base):
|
|
1073
|
+
r"""
|
|
1074
|
+
Return an element which is the power of ``base`` to this element.
|
|
1075
|
+
|
|
1076
|
+
INPUT:
|
|
1077
|
+
|
|
1078
|
+
- ``base`` -- an element
|
|
1079
|
+
|
|
1080
|
+
OUTPUT: a growth element
|
|
1081
|
+
|
|
1082
|
+
.. NOTE::
|
|
1083
|
+
|
|
1084
|
+
The parent of the result can be different from the parent
|
|
1085
|
+
of this element.
|
|
1086
|
+
|
|
1087
|
+
A :exc:`ValueError` is raised if the calculation is not possible
|
|
1088
|
+
within this method. (Then the calling method should take care
|
|
1089
|
+
of the calculation.)
|
|
1090
|
+
|
|
1091
|
+
TESTS::
|
|
1092
|
+
|
|
1093
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1094
|
+
sage: G = GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ')
|
|
1095
|
+
sage: lx = log(G('x'))
|
|
1096
|
+
sage: rp = lx._rpow_element_('e'); rp
|
|
1097
|
+
x
|
|
1098
|
+
sage: rp.parent()
|
|
1099
|
+
Growth Group x^ZZ
|
|
1100
|
+
"""
|
|
1101
|
+
factors = self.factors()
|
|
1102
|
+
if len(factors) != 1:
|
|
1103
|
+
raise ValueError # calling method has to deal with it...
|
|
1104
|
+
from .growth_group import MonomialGrowthGroup
|
|
1105
|
+
factor = factors[0]
|
|
1106
|
+
if not isinstance(factor.parent(), MonomialGrowthGroup):
|
|
1107
|
+
raise ValueError # calling method has to deal with it...
|
|
1108
|
+
return factor._rpow_element_(base)
|
|
1109
|
+
|
|
1110
|
+
def exp(self):
|
|
1111
|
+
r"""
|
|
1112
|
+
The exponential of this element.
|
|
1113
|
+
|
|
1114
|
+
OUTPUT: a growth element
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1119
|
+
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ')
|
|
1120
|
+
sage: x = G('x')
|
|
1121
|
+
sage: exp(log(x))
|
|
1122
|
+
x
|
|
1123
|
+
sage: exp(log(log(x)))
|
|
1124
|
+
log(x)
|
|
1125
|
+
|
|
1126
|
+
::
|
|
1127
|
+
|
|
1128
|
+
sage: exp(x)
|
|
1129
|
+
Traceback (most recent call last):
|
|
1130
|
+
...
|
|
1131
|
+
ArithmeticError: Cannot construct e^x in
|
|
1132
|
+
Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ
|
|
1133
|
+
> *previous* TypeError: unsupported operand parent(s) for *:
|
|
1134
|
+
'Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ' and
|
|
1135
|
+
'Growth Group (e^x)^ZZ'
|
|
1136
|
+
|
|
1137
|
+
TESTS::
|
|
1138
|
+
|
|
1139
|
+
sage: E = GrowthGroup("(e^y)^QQ * y^QQ * log(y)^QQ")
|
|
1140
|
+
sage: y = E('y')
|
|
1141
|
+
sage: log(exp(y))
|
|
1142
|
+
y
|
|
1143
|
+
sage: exp(log(y))
|
|
1144
|
+
y
|
|
1145
|
+
"""
|
|
1146
|
+
return self.rpow('e')
|
|
1147
|
+
|
|
1148
|
+
def __invert__(self):
|
|
1149
|
+
r"""
|
|
1150
|
+
Return the multiplicative inverse of this Cartesian product.
|
|
1151
|
+
|
|
1152
|
+
OUTPUT: a growth element
|
|
1153
|
+
|
|
1154
|
+
.. NOTE::
|
|
1155
|
+
|
|
1156
|
+
The result may live in a larger parent than we started with.
|
|
1157
|
+
|
|
1158
|
+
TESTS::
|
|
1159
|
+
|
|
1160
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1161
|
+
sage: G = GrowthGroup('(ZZ_+)^x * x^ZZ')
|
|
1162
|
+
sage: g = G('2^x * x^3')
|
|
1163
|
+
sage: (~g).parent()
|
|
1164
|
+
Growth Group QQ^x * x^ZZ
|
|
1165
|
+
"""
|
|
1166
|
+
return self.parent()._create_element_in_extension_(
|
|
1167
|
+
tuple(~x for x in self.cartesian_factors()))
|
|
1168
|
+
|
|
1169
|
+
def _substitute_(self, rules):
|
|
1170
|
+
r"""
|
|
1171
|
+
Substitute the given ``rules`` in this
|
|
1172
|
+
Cartesian product growth element.
|
|
1173
|
+
|
|
1174
|
+
INPUT:
|
|
1175
|
+
|
|
1176
|
+
- ``rules`` -- dictionary; the neutral element of the group is
|
|
1177
|
+
replaced by the value to key ``'_one_'``
|
|
1178
|
+
|
|
1179
|
+
OUTPUT: an object
|
|
1180
|
+
|
|
1181
|
+
TESTS::
|
|
1182
|
+
|
|
1183
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1184
|
+
sage: G = GrowthGroup('x^QQ * log(x)^QQ')
|
|
1185
|
+
sage: G(x^3 * log(x)^5)._substitute_({'x': SR.var('z')})
|
|
1186
|
+
z^3*log(z)^5
|
|
1187
|
+
sage: _.parent()
|
|
1188
|
+
Symbolic Ring
|
|
1189
|
+
sage: G(x^3 * log(x)^5)._substitute_({'x': 2.2}) # rel tol 1e-6
|
|
1190
|
+
3.24458458945
|
|
1191
|
+
sage: _.parent()
|
|
1192
|
+
Real Field with 53 bits of precision
|
|
1193
|
+
sage: G(1 / x)._substitute_({'x': 0})
|
|
1194
|
+
Traceback (most recent call last):
|
|
1195
|
+
...
|
|
1196
|
+
ZeroDivisionError: Cannot substitute in x^(-1) in
|
|
1197
|
+
Growth Group x^QQ * log(x)^QQ.
|
|
1198
|
+
> *previous* ZeroDivisionError: Cannot substitute in x^(-1) in
|
|
1199
|
+
Growth Group x^QQ.
|
|
1200
|
+
>> *previous* ZeroDivisionError: rational division by zero
|
|
1201
|
+
sage: G(1)._substitute_({'_one_': 'one'})
|
|
1202
|
+
'one'
|
|
1203
|
+
"""
|
|
1204
|
+
if self.is_one():
|
|
1205
|
+
return rules['_one_']
|
|
1206
|
+
from sage.symbolic.operators import mul_vararg
|
|
1207
|
+
try:
|
|
1208
|
+
return mul_vararg(
|
|
1209
|
+
*tuple(x._substitute_(rules)
|
|
1210
|
+
for x in self.cartesian_factors()))
|
|
1211
|
+
except (ArithmeticError, TypeError, ValueError) as e:
|
|
1212
|
+
from .misc import substitute_raise_exception
|
|
1213
|
+
substitute_raise_exception(self, e)
|
|
1214
|
+
|
|
1215
|
+
def _singularity_analysis_(self, var, zeta, precision):
|
|
1216
|
+
r"""
|
|
1217
|
+
Perform singularity analysis on this growth element.
|
|
1218
|
+
|
|
1219
|
+
INPUT:
|
|
1220
|
+
|
|
1221
|
+
- ``var`` -- string denoting the variable
|
|
1222
|
+
|
|
1223
|
+
- ``zeta`` -- a number
|
|
1224
|
+
|
|
1225
|
+
- ``precision`` -- integer
|
|
1226
|
+
|
|
1227
|
+
OUTPUT:
|
|
1228
|
+
|
|
1229
|
+
An asymptotic expansion for `[z^n] f` where `n` is ``var``
|
|
1230
|
+
and `f` has this growth element as a singular expansion
|
|
1231
|
+
in `T=\frac{1}{1-\frac{z}{\zeta}}\to \infty` where this
|
|
1232
|
+
element is a growth element in `T`.
|
|
1233
|
+
|
|
1234
|
+
EXAMPLES::
|
|
1235
|
+
|
|
1236
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1237
|
+
sage: G = GrowthGroup('exp(x)^QQ * x^QQ * log(x)^QQ')
|
|
1238
|
+
sage: G(x^(1/2))._singularity_analysis_('n', 2, precision=2)
|
|
1239
|
+
1/sqrt(pi)*(1/2)^n*n^(-1/2) - 1/8/sqrt(pi)*(1/2)^n*n^(-3/2)
|
|
1240
|
+
+ O((1/2)^n*n^(-5/2))
|
|
1241
|
+
sage: G(log(x))._singularity_analysis_('n', 1, precision=5)
|
|
1242
|
+
n^(-1) + O(n^(-3))
|
|
1243
|
+
sage: G(x*log(x))._singularity_analysis_('n', 1, precision=5)
|
|
1244
|
+
log(n) + euler_gamma + 1/2*n^(-1) + O(n^(-2))
|
|
1245
|
+
|
|
1246
|
+
TESTS::
|
|
1247
|
+
|
|
1248
|
+
sage: G('exp(x)*log(x)')._singularity_analysis_('n', 1, precision=5)
|
|
1249
|
+
Traceback (most recent call last):
|
|
1250
|
+
...
|
|
1251
|
+
NotImplementedError: singularity analysis of exp(x)*log(x)
|
|
1252
|
+
not implemented
|
|
1253
|
+
sage: G('exp(x)*x*log(x)')._singularity_analysis_('n', 1, precision=5)
|
|
1254
|
+
Traceback (most recent call last):
|
|
1255
|
+
...
|
|
1256
|
+
NotImplementedError: singularity analysis of exp(x)*x*log(x)
|
|
1257
|
+
not yet implemented since it has more than two factors
|
|
1258
|
+
sage: G(1)._singularity_analysis_('n', 2, precision=3)
|
|
1259
|
+
Traceback (most recent call last):
|
|
1260
|
+
...
|
|
1261
|
+
NotImplementedOZero: got O(0)
|
|
1262
|
+
The error term O(0) means 0 for sufficiently large n.
|
|
1263
|
+
sage: G('exp(x)')._singularity_analysis_('n', 2, precision=3)
|
|
1264
|
+
Traceback (most recent call last):
|
|
1265
|
+
...
|
|
1266
|
+
NotImplementedError: singularity analysis of exp(x)
|
|
1267
|
+
not implemented
|
|
1268
|
+
"""
|
|
1269
|
+
factors = self.factors()
|
|
1270
|
+
if len(factors) == 0:
|
|
1271
|
+
from .asymptotic_expansion_generators import asymptotic_expansions
|
|
1272
|
+
from .misc import NotImplementedOZero
|
|
1273
|
+
raise NotImplementedOZero(var=var, exact_part=0)
|
|
1274
|
+
elif len(factors) == 1:
|
|
1275
|
+
return factors[0]._singularity_analysis_(
|
|
1276
|
+
var=var, zeta=zeta, precision=precision)
|
|
1277
|
+
elif len(factors) == 2:
|
|
1278
|
+
from .growth_group import MonomialGrowthGroup
|
|
1279
|
+
from sage.rings.integer_ring import ZZ
|
|
1280
|
+
|
|
1281
|
+
a, b = factors
|
|
1282
|
+
if all(isinstance(f.parent(), MonomialGrowthGroup)
|
|
1283
|
+
for f in factors) \
|
|
1284
|
+
and a.parent().gens_monomial() \
|
|
1285
|
+
and b.parent().gens_logarithmic() \
|
|
1286
|
+
and a.parent().variable_name() == \
|
|
1287
|
+
b.parent().variable_name():
|
|
1288
|
+
if b.exponent not in ZZ:
|
|
1289
|
+
raise NotImplementedError(
|
|
1290
|
+
'singularity analysis of {} not implemented '
|
|
1291
|
+
'since exponent {} of {} is not an integer'.format(
|
|
1292
|
+
self, b.exponent, b.parent().gen()))
|
|
1293
|
+
|
|
1294
|
+
from sage.rings.asymptotic.asymptotic_expansion_generators import \
|
|
1295
|
+
asymptotic_expansions
|
|
1296
|
+
return asymptotic_expansions.SingularityAnalysis(
|
|
1297
|
+
var=var, zeta=zeta, alpha=a.exponent,
|
|
1298
|
+
beta=ZZ(b.exponent), delta=0,
|
|
1299
|
+
precision=precision, normalized=False)
|
|
1300
|
+
else:
|
|
1301
|
+
raise NotImplementedError(
|
|
1302
|
+
'singularity analysis of {} not implemented'.format(self))
|
|
1303
|
+
else:
|
|
1304
|
+
raise NotImplementedError(
|
|
1305
|
+
'singularity analysis of {} not yet implemented '
|
|
1306
|
+
'since it has more than two factors'.format(self))
|
|
1307
|
+
|
|
1308
|
+
def variable_names(self):
|
|
1309
|
+
r"""
|
|
1310
|
+
Return the names of the variables of this growth element.
|
|
1311
|
+
|
|
1312
|
+
OUTPUT: a tuple of strings
|
|
1313
|
+
|
|
1314
|
+
EXAMPLES::
|
|
1315
|
+
|
|
1316
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1317
|
+
sage: G = GrowthGroup('QQ^m * m^QQ * log(n)^ZZ')
|
|
1318
|
+
sage: G('2^m * m^4 * log(n)').variable_names()
|
|
1319
|
+
('m', 'n')
|
|
1320
|
+
sage: G('2^m * m^4').variable_names()
|
|
1321
|
+
('m',)
|
|
1322
|
+
sage: G('log(n)').variable_names()
|
|
1323
|
+
('n',)
|
|
1324
|
+
sage: G('m^3').variable_names()
|
|
1325
|
+
('m',)
|
|
1326
|
+
sage: G('m^0').variable_names()
|
|
1327
|
+
()
|
|
1328
|
+
"""
|
|
1329
|
+
vars = sum(iter(factor.variable_names()
|
|
1330
|
+
for factor in self.factors()),
|
|
1331
|
+
tuple())
|
|
1332
|
+
from itertools import groupby
|
|
1333
|
+
return tuple(v for v, _ in groupby(vars))
|
|
1334
|
+
|
|
1335
|
+
CartesianProduct = CartesianProductGrowthGroups
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
class UnivariateProduct(GenericProduct):
|
|
1339
|
+
r"""
|
|
1340
|
+
A Cartesian product of growth groups with the same variables.
|
|
1341
|
+
|
|
1342
|
+
.. NOTE::
|
|
1343
|
+
|
|
1344
|
+
A univariate product of growth groups is ordered
|
|
1345
|
+
lexicographically. This is motivated by the assumption
|
|
1346
|
+
that univariate growth groups can be ordered in a chain
|
|
1347
|
+
with respect to the growth they model (e.g.
|
|
1348
|
+
``x^ZZ * log(x)^ZZ``: polynomial growth dominates
|
|
1349
|
+
logarithmic growth).
|
|
1350
|
+
|
|
1351
|
+
.. SEEALSO::
|
|
1352
|
+
|
|
1353
|
+
:class:`MultivariateProduct`,
|
|
1354
|
+
:class:`GenericProduct`.
|
|
1355
|
+
"""
|
|
1356
|
+
|
|
1357
|
+
def __init__(self, sets, category, **kwargs):
|
|
1358
|
+
r"""
|
|
1359
|
+
See :class:`UnivariateProduct` for details.
|
|
1360
|
+
|
|
1361
|
+
TESTS::
|
|
1362
|
+
|
|
1363
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1364
|
+
sage: type(GrowthGroup('x^ZZ * log(x)^ZZ')) # indirect doctest
|
|
1365
|
+
<class 'sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct_with_category'>
|
|
1366
|
+
"""
|
|
1367
|
+
super().__init__(sets, category, order='lex', **kwargs)
|
|
1368
|
+
|
|
1369
|
+
CartesianProduct = CartesianProductGrowthGroups
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
class MultivariateProduct(GenericProduct):
|
|
1373
|
+
r"""
|
|
1374
|
+
A Cartesian product of growth groups with pairwise disjoint
|
|
1375
|
+
(or equal) variable sets.
|
|
1376
|
+
|
|
1377
|
+
.. NOTE::
|
|
1378
|
+
|
|
1379
|
+
A multivariate product of growth groups is ordered by
|
|
1380
|
+
means of the product order, i.e. component-wise. This is
|
|
1381
|
+
motivated by the assumption that different variables are
|
|
1382
|
+
considered to be independent (e.g. ``x^ZZ * y^ZZ``).
|
|
1383
|
+
|
|
1384
|
+
.. SEEALSO::
|
|
1385
|
+
|
|
1386
|
+
:class:`UnivariateProduct`,
|
|
1387
|
+
:class:`GenericProduct`.
|
|
1388
|
+
"""
|
|
1389
|
+
def __init__(self, sets, category, **kwargs):
|
|
1390
|
+
r"""
|
|
1391
|
+
|
|
1392
|
+
TESTS::
|
|
1393
|
+
|
|
1394
|
+
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
|
|
1395
|
+
sage: type(GrowthGroup('x^ZZ * y^ZZ')) # indirect doctest
|
|
1396
|
+
<class 'sage.rings.asymptotic.growth_group_cartesian.MultivariateProduct_with_category'>
|
|
1397
|
+
"""
|
|
1398
|
+
super().__init__(sets, category, order='product', **kwargs)
|
|
1399
|
+
|
|
1400
|
+
CartesianProduct = CartesianProductGrowthGroups
|