From 254b1a84d6edacc914bb783be0e8f567a711c044 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 22 Jun 2021 10:59:25 -0400 Subject: [PATCH 001/350] working on number fields --- .../arithmetic_dynamics/projective_ds.py | 101 +++++++++++++----- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 2aa725e2f93..99fc9ef2f70 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4467,43 +4467,83 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur raise ValueError("period must be a positive integer") if not is_ProjectiveSpace(PS): raise NotImplementedError("not implemented for subschemes") - if (PS.dimension_relative() > 1): - raise NotImplementedError("only implemented for dimension 1") K = FractionField(self.codomain().base_ring()) - if use_algebraic_closure: - Kbar = K.algebraic_closure() - if Kbar.has_coerce_map_from(K): - f = self.change_ring(Kbar) + if True: + K = FractionField(self.codomain().base_ring()) + X = self.periodic_points(n, minimal=False, formal=formal, return_scheme=True) + if use_algebraic_closure: + Kbar = K.algebraic_closure() + if Kbar.has_coerce_map_from(K): + f = self.change_ring(Kbar) + rat_points = X.rational_points(F=Kbar) + embedding = Kbar + else: + embeds = K.embeddings(Kbar) + embedding = embeds[0] + if embeds: + X2 = X.change_ring(embedding) + rat_points = X2.rational_points() + f = self.change_ring(embedding) + else: + raise ValueError("no embeddings of base field to algebraic closure") else: - embeds = K.embeddings(Kbar) - if embeds: - f = self.change_ring(embeds[0]) + if PS.dimension_relative() == 1: + embedding = self.field_of_definition_periodic(n, formal=formal, return_embedding=True)[1] + X = X.change_ring(embedding) + rat_points = X.rational_points() + f = self.change_ring(embedding) else: - raise ValueError("no embeddings of base field to algebraic closure") - else: - embedding = self.field_of_definition_periodic(n, formal=formal, return_embedding=True)[1] - f = self.change_ring(embedding) - - PS = f.domain() - if not formal: - G = f.nth_iterate_map(n) - F = G[0]*PS.gens()[1] - G[1]*PS.gens()[0] + rat_points = X.rational_points() + f = self + embedding = f.base_ring() + PS = f.domain() + points = [] + for point in rat_points: + if use_algebraic_closure: + K_prime, pnt_lst, embd = number_field_elements_from_algebraics(list(point) + [embedding(tup[0]) for poly in X.defining_polynomials() for tup in list(poly)]) + K_embeds = K.embeddings(K_prime) + X_k = X.change_ring(K_embeds[0]) + new_point = X_k.ambient_space()(pnt_lst[:PS.dimension_relative()+1]) + for i in range(X_k.multiplicity(new_point)): + points.append(PS(point)) + else: + for i in range(X.multiplicity(point)): + points.append(point) else: - # periodic points of formal period n are the roots of the nth dynatomic polynomial - F = f.dynatomic_polynomial(n) + if use_algebraic_closure: + Kbar = K.algebraic_closure() + if Kbar.has_coerce_map_from(K): + f = self.change_ring(Kbar) + else: + embeds = K.embeddings(Kbar) + if embeds: + f = self.change_ring(embeds[0]) + else: + raise ValueError("no embeddings of base field to algebraic closure") + elif PS.dimension_relative() == 1: + embedding = self.field_of_definition_periodic(n, formal=formal, return_embedding=True)[1] + f = self.change_ring(embedding) + + PS = f.domain() + if not formal: + G = f.nth_iterate_map(n) + F = G[0]*PS.gens()[1] - G[1]*PS.gens()[0] + else: + # periodic points of formal period n are the roots of the nth dynatomic polynomial + F = f.dynatomic_polynomial(n) - other_roots = F.parent()(F([(f.domain().gens()[0]),1])).univariate_polynomial().roots(ring=f.base_ring()) + other_roots = F.parent()(F([(f.domain().gens()[0]),1])).univariate_polynomial().roots(ring=f.base_ring()) - points = [] + points = [] - minfty = min(ex[1] for ex in F.exponents()) # include the point at infinity with the right multiplicity - for i in range(minfty): - points.append(PS([1,0])) + minfty = min(ex[1] for ex in F.exponents()) # include the point at infinity with the right multiplicity + for i in range(minfty): + points.append(PS([1,0])) - for R in other_roots: - for i in range(R[1]): - points.append(PS([R[0],1])) # include copies of higher multiplicity roots + for R in other_roots: + for i in range(R[1]): + points.append(PS([R[0],1])) # include copies of higher multiplicity roots if type == 'cycle': # should include one representative point per cycle, included with the right multiplicity @@ -4522,7 +4562,10 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur Q = f(Q) points = newpoints - multipliers = [f.multiplier(pt,n)[0,0] for pt in points] + if PS.dimension_relative() > 1: + multipliers = [f.multiplier(pt,n) for pt in points] + else: + multipliers = [f.multiplier(pt,n)[0,0] for pt in points] return multipliers From d23769a9663ec111b63dc014b7957977b5097db6 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 22 Jun 2021 16:30:54 -0400 Subject: [PATCH 002/350] 32035: added tests, functionality for QQbar and algebraic closures of finite fields --- .../arithmetic_dynamics/projective_ds.py | 192 ++++++++++++++---- 1 file changed, 156 insertions(+), 36 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 99fc9ef2f70..4bddb862037 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -52,6 +52,7 @@ class initialization directly. # https://www.gnu.org/licenses/ # **************************************************************************** +from typing_extensions import final from sage.arith.misc import is_prime from sage.categories.fields import Fields from sage.categories.function_fields import FunctionFields @@ -69,6 +70,7 @@ class initialization directly. from sage.rings.all import Integer from sage.arith.all import gcd, lcm, next_prime, binomial, primes, moebius from sage.categories.finite_fields import FiniteFields +from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic from sage.rings.complex_mpfr import ComplexField from sage.rings.finite_rings.finite_field_constructor import (is_FiniteField, GF, is_PrimeFiniteField) @@ -4351,29 +4353,45 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur EXAMPLES:: - sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([4608*x^10 - 2910096*x^9*y + 325988068*x^8*y^2 + 31825198932*x^7*y^3 - 4139806626613*x^6*y^4\ - - 44439736715486*x^5*y^5 + 2317935971590902*x^4*y^6 - 15344764859590852*x^3*y^7 + 2561851642765275*x^2*y^8\ - + 113578270285012470*x*y^9 - 150049940203963800*y^10, 4608*y^10]) - sage: sorted(f.multiplier_spectra(1)) - [-119820502365680843999, - -7198147681176255644585/256, - -3086380435599991/9, - -3323781962860268721722583135/35184372088832, - -4290991994944936653/2097152, - 0, - 529278480109921/256, - 1061953534167447403/19683, - 848446157556848459363/19683, - 82911372672808161930567/8192, - 3553497751559301575157261317/8192] + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = DynamicalSystem_projective([x^2 - 3/4*y^2, y^2]) + sage: sorted(f.multiplier_spectra(2, type='point')) + [0, 1, 1, 1, 9] + sage: sorted(f.multiplier_spectra(2, type='cycle')) + [0, 1, 1, 9] + + :: + + sage: P. = ProjectiveSpace(QQ, 2) + sage: f = DynamicalSystem_projective([x^2, z^2, y^2]) + sage: f.multiplier_spectra(1) + [ + [ 2 1 - 1.732050807568878?*I] + [ 0 -2], + [ 2 1 + 1.732050807568878?*I] [ 0 0] [ 0 0] + [ 0 -2], [ 0 -2], [ 0 -2], + [ 0 0] [0 0] [ 2 -2] + [ 0 -2], [0 0], [ 0 -2] + ] + + :: + + sage: P. = ProjectiveSpace(QQ, 2) + sage: f = DynamicalSystem_projective([x^2, z^2, y^2]) + sage: f.multiplier_spectra(2, formal=True) + [ + [4 0] [4 0] [4 0] [4 0] [4 0] [4 0] [4 0] [4 0] [0 0] [0 0] + [0 4], [0 0], [0 0], [0 4], [0 4], [0 0], [0 0], [0 4], [0 0], [0 0], + [4 0] [4 0] [4 0] [4 0] + [0 4], [0 4], [0 0], [0 0] + ] :: sage: set_verbose(None) sage: z = QQ['z'].0 sage: K. = NumberField(z^4 - 4*z^2 + 1,'z') - sage: P. = ProjectiveSpace(K,1) + sage: P. = ProjectiveSpace(K, 1) sage: f = DynamicalSystem_projective([x^2 - w/4*y^2, y^2]) sage: sorted(f.multiplier_spectra(2, formal=False, type='cycle')) [0, @@ -4383,16 +4401,26 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: - sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2 - 3/4*y^2, y^2]) - sage: sorted(f.multiplier_spectra(2, formal=False, type='cycle')) - [0, 1, 1, 9] - sage: sorted(f.multiplier_spectra(2, formal=False, type='point')) - [0, 1, 1, 1, 9] + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = DynamicalSystem_projective([4608*x^10 - 2910096*x^9*y + 325988068*x^8*y^2 + 31825198932*x^7*y^3 - 4139806626613*x^6*y^4\ + - 44439736715486*x^5*y^5 + 2317935971590902*x^4*y^6 - 15344764859590852*x^3*y^7 + 2561851642765275*x^2*y^8\ + + 113578270285012470*x*y^9 - 150049940203963800*y^10, 4608*y^10]) + sage: sorted(f.multiplier_spectra(1)) + [-119820502365680843999, + -7198147681176255644585/256, + -3086380435599991/9, + -3323781962860268721722583135/35184372088832, + -4290991994944936653/2097152, + 0, + 529278480109921/256, + 1061953534167447403/19683, + 848446157556848459363/19683, + 82911372672808161930567/8192, + 3553497751559301575157261317/8192] :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([x^2 - 7/4*y^2, y^2]) sage: f.multiplier_spectra(3, formal=True, type='cycle') [1, 1] @@ -4401,7 +4429,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([x^4 + 3*y^4, 4*x^2*y^2]) sage: f.multiplier_spectra(1, use_algebraic_closure=False) [0, @@ -4418,7 +4446,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: - sage: P. = ProjectiveSpace(GF(5),1) + sage: P. = ProjectiveSpace(GF(5), 1) sage: f = DynamicalSystem_projective([x^4 + 2*y^4, 4*x^2*y^2]) sage: f.multiplier_spectra(1, use_algebraic_closure=False) [0, 3*a + 3, 2*a + 1, 1, 1] @@ -4459,6 +4487,27 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: sorted(f.multiplier_spectra(1)) [0, 3, 6] + + :: + + sage: P. = ProjectiveSpace(QQ, 2) + sage: f = DynamicalSystem_projective([x^2, z^2, y^2]) + sage: g = f.change_ring(QQbar) + sage: f.multiplier_spectra(1) == g.multiplier_spectra(1) + True + + :: + + sage: K. = QuadraticField(5) + sage: P. = ProjectiveSpace(K, 2) + sage: f = DynamicalSystem_projective([x^2 + w*x*y + y^2, y^2, z^2]) + sage: f.multiplier_spectra(1) + [ + [1.000000000000000? - 1.572302755514847?*I 0] [1.000000000000000? - 1.572302755514847?*I 0.618033988749895? - 1.757887921270715?*I] [1.000000000000000? + 1.572302755514847?*I 0] [1.000000000000000? + 1.572302755514847?*I 0.618033988749895? + 1.757887921270715?*I] + [ 0 0], [ 0 2], [ 0 0], [ 0 2], + [0 0] [0 0] [ 2 2.236067977499790?] + [0 0], [0 0], [ 0 0] + ] """ PS = self.domain() n = Integer(n) @@ -4469,13 +4518,62 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur raise NotImplementedError("not implemented for subschemes") K = FractionField(self.codomain().base_ring()) - if True: - K = FractionField(self.codomain().base_ring()) - X = self.periodic_points(n, minimal=False, formal=formal, return_scheme=True) + if PS.dimension_relative() > 1: + K = self.domain().base_ring() + number_field = False + finite_field = False + + # if we are already using an algebraic closure, we move the + # map into a finite extension and set use_algebraic_closure to True + # in order to get a scheme defined over a finite extension + if K is QQbar: + K, pnts, embd = number_field_elements_from_algebraics([tup[0] for poly in self.defining_polynomials() for tup in list(poly)]) + CR = self.domain().coordinate_ring().change_ring(K) + new_polys = [] + counter = 0 + for poly in self.defining_polynomials(): + new_poly = CR(0) + for tup in poly: + new_poly += pnts[counter]*CR(tup[1]) + counter += 1 + new_polys.append(new_poly) + f = DynamicalSystem_projective(new_polys) + use_algebraic_closure = True + number_field = True + elif isinstance(K, AlgebraicClosureFiniteField_generic): + final_degree = ZZ(1) + for poly in self.defining_polynomials(): + for tup in list(poly): + final_degree = final_degree.lcm(tup[0]._level) + K = GF(K.characteristic()**final_degree) + CR = self.domain().coordinate_ring().change_ring(K) + new_polys = [] + for poly in self.defining_polynomials(): + new_poly = CR(0) + for tup in poly: + deg = tup[1].degrees() + var = CR(1) + for i in range(len(deg)): + var *= CR.gens()[i]**deg[i] + coeff = tup[0].as_finite_field_element()[1] + new_poly += coeff*var + new_polys.append(new_poly) + f = DynamicalSystem_projective(new_polys) + use_algebraic_closure = True + finite_field = True + else: + f = self + X = f.periodic_points(n, minimal=False, formal=formal, return_scheme=True) if use_algebraic_closure: + if K in NumberFields(): + number_field = True + if K in FiniteFields(): + finite_field = True + if not(number_field or finite_field): + raise NotImplementedError('Only implemented for number fields, QQbar, finite fields, and algebraic closures of finite fields') Kbar = K.algebraic_closure() if Kbar.has_coerce_map_from(K): - f = self.change_ring(Kbar) + f = f.change_ring(Kbar) rat_points = X.rational_points(F=Kbar) embedding = Kbar else: @@ -4501,12 +4599,34 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur points = [] for point in rat_points: if use_algebraic_closure: - K_prime, pnt_lst, embd = number_field_elements_from_algebraics(list(point) + [embedding(tup[0]) for poly in X.defining_polynomials() for tup in list(poly)]) - K_embeds = K.embeddings(K_prime) - X_k = X.change_ring(K_embeds[0]) - new_point = X_k.ambient_space()(pnt_lst[:PS.dimension_relative()+1]) - for i in range(X_k.multiplicity(new_point)): - points.append(PS(point)) + if number_field: + K2, pnt_lst, embd = number_field_elements_from_algebraics(list(point)) + if K2 is QQ: + for i in range(X.multiplicity(pnt_lst)): + points.append(PS(point)) + elif K is QQ: + X_k = X.change_ring(K2) + for i in range(X_k.multiplicity(pnt_lst)): + points.append(PS(point)) + else: + _, K_embed, K2_embed, _ = K.composite_fields(K2, both_maps=True)[0] + X_k = X.change_ring(K_embed) + pnt_lst = [K2_embed(pnt) for pnt in pnt_lst] + new_point = X_k.ambient_space()(pnt_lst) + for i in range(X_k.multiplicity(new_point)): + points.append(PS(point)) + else: + final_degree = K.degree() + new_point = [] + for num in list(point): + ff_num = num.as_finite_field_element()[1] + new_point.append(ff_num) + degree = ff_num.parent().degree() + final_degree = final_degree.lcm(degree) + K_prime = GF(K.characteristic()**final_degree) + X_k = X.change_ring(K_prime) + for i in range(X_k.multiplicity(new_point)): + points.append(PS(point)) else: for i in range(X.multiplicity(point)): points.append(point) From 558c25598eeff389c34efda768b64842ea1a74e6 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 23 Jun 2021 10:46:05 -0400 Subject: [PATCH 003/350] 32035: cleaned up code, added documentation --- .../arithmetic_dynamics/projective_ds.py | 67 ++++++------------- 1 file changed, 20 insertions(+), 47 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 4bddb862037..76780164535 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4327,11 +4327,13 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur User can also specify to compute the ``n`` multiplier spectra instead which includes the multipliers of all periodic points of period ``n``. The map must be defined over - projective space of dimension 1 over a number field or finite field. + projective space over a number field or finite field. - The computations can be done either over the algebraic closure of the - base field or over the minimal extension of the base field that - contains the critical points. + By default, the computations are done over the algebraic closure of the + base field. If the map is defined over projective space of dimension 1, + the computation can be done over the minimal extension of the base field that + contains the critical points. Otherwise, it will be done over the base ring + of the map. INPUT: @@ -4346,8 +4348,10 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur per point or one per cycle - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the - algebraic closure. If False, uses the smallest extension of the base field - containing all the critical points. + algebraic closure. If False, and he map is defined over projective space of + dimension 1, uses the smallest extension of the base field + containing all the critical points. If the map is defined over projective space + of dimension greater than 1, then the base ring of the map is used. OUTPUT: a list of field elements @@ -4455,7 +4459,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: - sage: P. = ProjectiveSpace(QQbar,1) + sage: P. = ProjectiveSpace(QQbar, 1) sage: f = DynamicalSystem_projective([x^5 + 3*y^5, 4*x^3*y^2]) sage: f.multiplier_spectra(1) [0, @@ -4468,14 +4472,14 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: sage: K = GF(3).algebraic_closure() - sage: P. = ProjectiveSpace(K,1) + sage: P. = ProjectiveSpace(K, 1) sage: f = DynamicalSystem_projective([x^5 + 2*y^5, 4*x^3*y^2]) sage: f.multiplier_spectra(1) [0, z3 + 2, z3 + 1, z3, 1, 1] TESTS:: - sage: P. = ProjectiveSpace(QQ,1) + sage: P. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([x^2 + y^2, x*y]) sage: f.multiplier_spectra(1) [1, 1, 1] @@ -4483,7 +4487,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: sage: F. = GF(7) - sage: P.=ProjectiveSpace(F,1) + sage: P.=ProjectiveSpace(F, 1) sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: sorted(f.multiplier_spectra(1)) [0, 3, 6] @@ -4517,54 +4521,22 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur if not is_ProjectiveSpace(PS): raise NotImplementedError("not implemented for subschemes") - K = FractionField(self.codomain().base_ring()) if PS.dimension_relative() > 1: K = self.domain().base_ring() - number_field = False - finite_field = False # if we are already using an algebraic closure, we move the # map into a finite extension and set use_algebraic_closure to True # in order to get a scheme defined over a finite extension - if K is QQbar: - K, pnts, embd = number_field_elements_from_algebraics([tup[0] for poly in self.defining_polynomials() for tup in list(poly)]) - CR = self.domain().coordinate_ring().change_ring(K) - new_polys = [] - counter = 0 - for poly in self.defining_polynomials(): - new_poly = CR(0) - for tup in poly: - new_poly += pnts[counter]*CR(tup[1]) - counter += 1 - new_polys.append(new_poly) - f = DynamicalSystem_projective(new_polys) - use_algebraic_closure = True - number_field = True - elif isinstance(K, AlgebraicClosureFiniteField_generic): - final_degree = ZZ(1) - for poly in self.defining_polynomials(): - for tup in list(poly): - final_degree = final_degree.lcm(tup[0]._level) - K = GF(K.characteristic()**final_degree) - CR = self.domain().coordinate_ring().change_ring(K) - new_polys = [] - for poly in self.defining_polynomials(): - new_poly = CR(0) - for tup in poly: - deg = tup[1].degrees() - var = CR(1) - for i in range(len(deg)): - var *= CR.gens()[i]**deg[i] - coeff = tup[0].as_finite_field_element()[1] - new_poly += coeff*var - new_polys.append(new_poly) - f = DynamicalSystem_projective(new_polys) + if K is QQbar or isinstance(K, AlgebraicClosureFiniteField_generic): + f = self.reduce_base_field() + K = f.base_ring() use_algebraic_closure = True - finite_field = True else: f = self X = f.periodic_points(n, minimal=False, formal=formal, return_scheme=True) if use_algebraic_closure: + number_field = False + finite_field = False if K in NumberFields(): number_field = True if K in FiniteFields(): @@ -4631,6 +4603,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur for i in range(X.multiplicity(point)): points.append(point) else: + K = FractionField(self.codomain().base_ring()) if use_algebraic_closure: Kbar = K.algebraic_closure() if Kbar.has_coerce_map_from(K): From dbbd3dc4e63ce1dc22665359b19acf4ab844e55e Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 23 Jun 2021 10:49:36 -0400 Subject: [PATCH 004/350] 32035: added test for algebraic closure --- .../dynamics/arithmetic_dynamics/projective_ds.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 76780164535..e1c5f5a617f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4484,6 +4484,17 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur sage: f.multiplier_spectra(1) [1, 1, 1] + :: + + sage: K = GF(3).algebraic_closure() + sage: P. = ProjectiveSpace(K, 2) + sage: f = DynamicalSystem_projective([x^2 + 2*y^2, 4*x*y, z^2]) + sage: f.multiplier_spectra(1) + [ + [0 0] [1 0] [1 0] [1 0] [2 0] [2 0] [2 0] + [0 0], [0 0], [0 0], [0 0], [0 1], [0 1], [0 1] + ] + :: sage: F. = GF(7) From 083b6faaf58770b2502c34fe8486aa9fb92f367e Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 24 Jun 2021 11:25:12 -0400 Subject: [PATCH 005/350] 32035: minor code cleanup --- .../dynamics/arithmetic_dynamics/projective_ds.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index e1c5f5a617f..62f4ce81ca2 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4558,7 +4558,6 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur if Kbar.has_coerce_map_from(K): f = f.change_ring(Kbar) rat_points = X.rational_points(F=Kbar) - embedding = Kbar else: embeds = K.embeddings(Kbar) embedding = embeds[0] @@ -4569,15 +4568,8 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur else: raise ValueError("no embeddings of base field to algebraic closure") else: - if PS.dimension_relative() == 1: - embedding = self.field_of_definition_periodic(n, formal=formal, return_embedding=True)[1] - X = X.change_ring(embedding) - rat_points = X.rational_points() - f = self.change_ring(embedding) - else: - rat_points = X.rational_points() - f = self - embedding = f.base_ring() + rat_points = X.rational_points() + f = self PS = f.domain() points = [] for point in rat_points: From 2f064fd15867ac92d5775f3af39d740a4a8ee07a Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 24 Jun 2021 13:06:59 -0400 Subject: [PATCH 006/350] 32035: added comments, fixed output documentation --- .../arithmetic_dynamics/projective_ds.py | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 62f4ce81ca2..426d54954ed 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4348,12 +4348,18 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur per point or one per cycle - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the - algebraic closure. If False, and he map is defined over projective space of + algebraic closure. Using the algebraic closure can sometimes lead to numerical instability + and extraneous errors. For most accurate results, set to ``False``. + If False, and he map is defined over projective space of dimension 1, uses the smallest extension of the base field containing all the critical points. If the map is defined over projective space of dimension greater than 1, then the base ring of the map is used. - OUTPUT: a list of field elements + OUTPUT: + + A list of field elements if the domain of the map is projective space of + dimension 1. If the domain of the map is projective space of dimension + greater than 1, a list of matrices EXAMPLES:: @@ -4544,6 +4550,9 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur use_algebraic_closure = True else: f = self + + # in order to calculate multiplicity, we need to have a scheme defined + # over a finite extension, not an algebraic closure X = f.periodic_points(n, minimal=False, formal=formal, return_scheme=True) if use_algebraic_closure: number_field = False @@ -4560,11 +4569,10 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur rat_points = X.rational_points(F=Kbar) else: embeds = K.embeddings(Kbar) - embedding = embeds[0] if embeds: - X2 = X.change_ring(embedding) + X2 = X.change_ring(embeds[0]) rat_points = X2.rational_points() - f = self.change_ring(embedding) + f = self.change_ring(embeds[0]) else: raise ValueError("no embeddings of base field to algebraic closure") else: @@ -4575,14 +4583,17 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur for point in rat_points: if use_algebraic_closure: if number_field: - K2, pnt_lst, embd = number_field_elements_from_algebraics(list(point)) - if K2 is QQ: + # in order to calculate multiplicity, the point must be defined over a finite extension + K2, pnt_lst, _ = number_field_elements_from_algebraics(list(point)) + # we coerce if we can + if K.has_coerce_map_from(K2): for i in range(X.multiplicity(pnt_lst)): points.append(PS(point)) - elif K is QQ: + elif K2.has_coerce_map_from(K): X_k = X.change_ring(K2) for i in range(X_k.multiplicity(pnt_lst)): points.append(PS(point)) + # otherwise, we need to calculate a composite field else: _, K_embed, K2_embed, _ = K.composite_fields(K2, both_maps=True)[0] X_k = X.change_ring(K_embed) @@ -4591,6 +4602,8 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur for i in range(X_k.multiplicity(new_point)): points.append(PS(point)) else: + # we find a finite extension which point the point + # and X coerce into final_degree = K.degree() new_point = [] for num in list(point): From 2ab4ac647430e2d4b0d0d71a5f360a7b823268dd Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 20 Jul 2021 12:29:21 -0400 Subject: [PATCH 007/350] 32035: doc fixes --- .../arithmetic_dynamics/projective_ds.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index d8173264ac9..52bcb7e83ed 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4539,17 +4539,17 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur r""" Computes the ``n`` multiplier spectra of this dynamical system. - This is the set of multipliers of the periodic points of formal + This is the set of multipliers of all peroidic points of period ``n`` included with the appropriate multiplicity. - User can also specify to compute the ``n`` multiplier spectra - instead which includes the multipliers of all periodic points - of period ``n``. The map must be defined over + User can also specify to compute the formal ``n`` multiplier spectra + instead which includes the multipliers of all formal periodic points + of period ``n`` with appropriate multiplicity. The map must be defined over projective space over a number field or finite field. By default, the computations are done over the algebraic closure of the base field. If the map is defined over projective space of dimension 1, the computation can be done over the minimal extension of the base field that - contains the critical points. Otherwise, it will be done over the base ring + contains the periodic points. Otherwise, it will be done over the base ring of the map. INPUT: @@ -4741,8 +4741,14 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur sage: f = DynamicalSystem_projective([x^2 + w*x*y + y^2, y^2, z^2]) sage: f.multiplier_spectra(1) [ - [1.000000000000000? - 1.572302755514847?*I 0] [1.000000000000000? - 1.572302755514847?*I 0.618033988749895? - 1.757887921270715?*I] [1.000000000000000? + 1.572302755514847?*I 0] [1.000000000000000? + 1.572302755514847?*I 0.618033988749895? + 1.757887921270715?*I] - [ 0 0], [ 0 2], [ 0 0], [ 0 2], + [1.000000000000000? - 1.572302755514847?*I 0] + [1.000000000000000? - 1.572302755514847?*I 0.618033988749895? - 1.757887921270715?*I] + [1.000000000000000? + 1.572302755514847?*I 0] + [1.000000000000000? + 1.572302755514847?*I 0.618033988749895? + 1.757887921270715?*I] + [ 0 0], + [ 0 2], + [ 0 0], + [ 0 2], [0 0] [0 0] [ 2 2.236067977499790?] [0 0], [0 0], [ 0 0] ] @@ -4819,7 +4825,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur for i in range(X_k.multiplicity(new_point)): points.append(PS(point)) else: - # we find a finite extension which point the point + # we find a finite extension which the current point # and X coerce into final_degree = K.degree() new_point = [] @@ -4847,7 +4853,7 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur f = self.change_ring(embeds[0]) else: raise ValueError("no embeddings of base field to algebraic closure") - elif PS.dimension_relative() == 1: + else: embedding = self.field_of_definition_periodic(n, formal=formal, return_embedding=True)[1] f = self.change_ring(embedding) From 25b19e23bff5e69d0f282b7810e1b42c5e29450d Mon Sep 17 00:00:00 2001 From: bhutz Date: Thu, 22 Jul 2021 09:13:17 -0500 Subject: [PATCH 008/350] 32035: minor doc fixes --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 52bcb7e83ed..97d5a3d005f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4567,9 +4567,9 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the algebraic closure. Using the algebraic closure can sometimes lead to numerical instability and extraneous errors. For most accurate results, set to ``False``. - If False, and he map is defined over projective space of + If False, and the map is defined over projective space of dimension 1, uses the smallest extension of the base field - containing all the critical points. If the map is defined over projective space + containing all the periodic points. If the map is defined over projective space of dimension greater than 1, then the base ring of the map is used. OUTPUT: From 5fcf96d531c13d011d23143dd594240ed6e70f0b Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 23 Jul 2021 10:55:11 -0400 Subject: [PATCH 009/350] 32035: added check for if the full spectra was computed --- .../arithmetic_dynamics/projective_ds.py | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 97d5a3d005f..eeabbf93ff2 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4535,7 +4535,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari else: raise ValueError("algorithm must be either 'variety' or 'cyclegraph'") - def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closure=True): + def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closure=True, check=True): r""" Computes the ``n`` multiplier spectra of this dynamical system. @@ -4564,14 +4564,20 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur or ``'cycle'`` depending on whether you compute one multiplier per point or one per cycle - - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the + - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True`` uses the algebraic closure. Using the algebraic closure can sometimes lead to numerical instability - and extraneous errors. For most accurate results, set to ``False``. - If False, and the map is defined over projective space of + and extraneous errors. For most accurate results in dimension 1, set to ``False``. + If ``False``, and the map is defined over projective space of dimension 1, uses the smallest extension of the base field containing all the periodic points. If the map is defined over projective space of dimension greater than 1, then the base ring of the map is used. + - ``check`` -- (defualt: ``True``) whether to check if the + full multiplier spectra was computed. If ``False``, can lead to + mathematically incorrect answers in dimension greater than 1. Ignored + if ``use_algebraic_closure`` is ``True`` or if this dynamical system is defined + over projective space of dimension 1. + OUTPUT: A list of field elements if the domain of the map is projective space of @@ -4752,6 +4758,16 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur [0 0] [0 0] [ 2 2.236067977499790?] [0 0], [0 0], [ 0 0] ] + + :: + + sage: P. = ProjectiveSpace(QQ, 2) + sage: f = DynamicalSystem_projective([x^2, z^2, y^2]) + sage: f.multiplier_spectra(1, use_algebraic_closure=False) + Traceback (most recent call last): + ... + ValueError: failed to compute the full multiplier spectra. Try use_algebraic_closure=True + or extend the base ring of this dynamical system """ PS = self.domain() n = Integer(n) @@ -4841,6 +4857,22 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur else: for i in range(X.multiplicity(point)): points.append(point) + if not use_algebraic_closure: + if check: + # we check if we computed the full multiplier spectra + d = self.degree() + N = self.domain().ambient_space().dimension_relative() + if not formal: + expected_number = sum(d**(n*i) for i in range(N+1)) + else: + expected_number = 0 + for D in n.divisors(): + u = moebius(n/D) + inner_sum = sum(d**(D*j) for j in range(N+1)) + expected_number += u*inner_sum + if len(points) != expected_number: + raise ValueError('failed to compute the full multiplier spectra. Try use_algebraic_closure=True' + + ' or extend the base ring of this dynamical system') else: K = FractionField(self.codomain().base_ring()) if use_algebraic_closure: From c7d6a7a079ab50e145bd7e39a107a2f79af2f99b Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 11 Aug 2021 21:51:06 +0530 Subject: [PATCH 010/350] Created a new file new_generating_series.py and merged the taylor series code. --- .../combinat/species/new_generating_series.py | 1366 +++++++++++++++++ 1 file changed, 1366 insertions(+) create mode 100644 src/sage/combinat/species/new_generating_series.py diff --git a/src/sage/combinat/species/new_generating_series.py b/src/sage/combinat/species/new_generating_series.py new file mode 100644 index 00000000000..f87d3c07613 --- /dev/null +++ b/src/sage/combinat/species/new_generating_series.py @@ -0,0 +1,1366 @@ +r""" +Generating Series + +This file makes a number of extensions to lazy power series by +endowing them with some semantic content for how they're to be +interpreted. + +This code is based on the work of Ralf Hemmecke and Martin Rubey's +Aldor-Combinat, which can be found at +http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html. +In particular, the relevant section for this file can be found at +http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse10.html. +One notable difference is that we use power-sum symmetric functions +as the coefficients of our cycle index series. + +TESTS:: + + sage: from sage.combinat.species.stream import Stream, _integers_from + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + +:: + + sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) + sage: geo2 = CIS((p([2])^i for i in _integers_from(0))) + sage: s = geo1 * geo2 + sage: s[0] + p[] + sage: s[1] + p[1] + p[2] + sage: s[2] + p[1, 1] + p[2, 1] + p[2, 2] + sage: s[3] + p[1, 1, 1] + p[2, 1, 1] + p[2, 2, 1] + p[2, 2, 2] + +Whereas the coefficients of the above test are homogeneous with +respect to total degree, the following test groups with respect to +weighted degree where each variable x_i has weight i. + +:: + + sage: def g(): + ....: for i in _integers_from(0): + ....: yield p([2])^i + ....: yield p(0) + sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) + sage: geo2 = CIS(g()) + sage: s = geo1 * geo2 + sage: s[0] + p[] + sage: s[1] + p[1] + sage: s[2] + p[1, 1] + p[2] + sage: s[3] + p[1, 1, 1] + p[2, 1] + sage: s[4] + p[1, 1, 1, 1] + p[2, 1, 1] + p[2, 2] + +REFERENCES: + +.. [BLL] \F. Bergeron, G. Labelle, and P. Leroux. + "Combinatorial species and tree-like structures". + Encyclopedia of Mathematics and its Applications, vol. 67, Cambridge Univ. Press. 1998. +.. [BLL-Intro] Francois Bergeron, Gilbert Labelle, and Pierre Leroux. + "Introduction to the Theory of Species of Structures", March 14, 2008. +""" + +#***************************************************************************** +# Copyright (C) 2008 Mike Hansen +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from .series import LazyPowerSeriesRing, LazyPowerSeries +from .stream import Stream, _integers_from +from sage.rings.all import Integer, RationalField +from sage.arith.all import moebius, gcd, lcm, divisors +from sage.combinat.partition import Partition, Partitions +from functools import partial +from sage.combinat.sf.sf import SymmetricFunctions +from sage.misc.cachefunc import cached_function +from sage.functions.other import factorial + + +@cached_function +def OrdinaryGeneratingSeriesRing(R): + """ + Return the ring of ordinary generating series over ``R``. + + Note that it is just a + :class:`LazyPowerSeriesRing` whose elements have + some extra methods. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ); R + Lazy Power Series Ring over Rational Field + sage: R([1]).coefficients(4) + [1, 1, 1, 1] + sage: R([1]).counts(4) + [1, 1, 1, 1] + + TESTS: + + We test to make sure that caching works. + + :: + + sage: R is OrdinaryGeneratingSeriesRing(QQ) + True + """ + return OrdinaryGeneratingSeriesRing_class(R) + + +class OrdinaryGeneratingSeriesRing_class(LazyPowerSeriesRing): + def __init__(self, R): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: R == loads(dumps(R)) + True + """ + LazyPowerSeriesRing.__init__(self, R, element_class=OrdinaryGeneratingSeries) + + +class OrdinaryGeneratingSeries(LazyPowerSeries): + def count(self, n): + """ + Return the number of structures on a set of size ``n``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: f = R(range(20)) + sage: f.count(10) + 10 + """ + return self.coefficient(n) + + def counts(self, n): + """ + Return the number of structures on a set for size ``i`` for + each ``i`` in ``range(n)``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: f = R(range(20)) + sage: f.counts(10) + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + """ + return [self.count(i) for i in range(n)] + + +@cached_function +def ExponentialGeneratingSeriesRing(R): + """ + Return the ring of exponential generating series over ``R``. + + Note that it is just a + :class:`LazyPowerSeriesRing` whose elements have + some extra methods. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ); R + Lazy Power Series Ring over Rational Field + sage: R([1]).coefficients(4) + [1, 1, 1, 1] + sage: R([1]).counts(4) + [1, 1, 2, 6] + + TESTS: + + We test to make sure that caching works. + + :: + + sage: R is ExponentialGeneratingSeriesRing(QQ) + True + """ + return ExponentialGeneratingSeriesRing_class(R) + + +class ExponentialGeneratingSeriesRing_class(LazyPowerSeriesRing): + def __init__(self, R): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: R == loads(dumps(R)) + True + """ + LazyPowerSeriesRing.__init__(self, R, element_class=ExponentialGeneratingSeries) + +class ExponentialGeneratingSeries(LazyPowerSeries): + def count(self, n): + """ + Return the number of structures of size ``n``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: f = R([1]) + sage: [f.count(i) for i in range(7)] + [1, 1, 2, 6, 24, 120, 720] + """ + return factorial(n) * self.coefficient(n) + + def counts(self, n): + """ + Return the number of structures on a set for size ``i`` for + each ``i`` in ``range(n)``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: f = R(range(20)) + sage: f.counts(5) + [0, 1, 4, 18, 96] + """ + return [self.count(i) for i in range(n)] + + def functorial_composition(self, y): + r""" + Return the exponential generating series which is the functorial + composition of ``self`` with ``y``. + + If `f = \sum_{n=0}^{\infty} f_n \frac{x^n}{n!}` and + `g = \sum_{n=0}^{\infty} g_n \frac{x^n}{n!}`, then + functorial composition `f \Box g` is defined as + + .. MATH:: + + f \Box g = \sum_{n=0}^{\infty} f_{g_n} \frac{x^n}{n!} + + REFERENCES: + + - Section 2.2 of [BLL]_. + + EXAMPLES:: + + sage: G = species.SimpleGraphSpecies() + sage: g = G.generating_series() + sage: g.coefficients(10) + [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] + """ + return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) + + def _functorial_compose_gen(self, y, ao): + """ + Returns a generator for the coefficients of the functorial + composition of self with y. + + EXAMPLES:: + + sage: E = species.SetSpecies() + sage: E2 = E.restricted(min=2, max=3) + sage: WP = species.SubsetSpecies() + sage: P2 = E2*E + sage: g1 = WP.generating_series() + sage: g2 = P2.generating_series() + sage: g = g1._functorial_compose_gen(g2, 0) + sage: [next(g) for i in range(10)] + [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] + """ + n = 0 + while True: + yield self.count(y.count(n)) / factorial(n) + n += 1 + + +def factorial_gen(): + """ + A generator for the factorials starting at 0. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import factorial_gen + sage: g = factorial_gen() + sage: [next(g) for i in range(5)] + [1, 1, 2, 6, 24] + """ + z = Integer(1) + yield z + yield z + n = Integer(2) + while True: + z *= n + yield z + n += 1 + + +@cached_function +def CycleIndexSeriesRing(R): + r""" + Return the ring of cycle index series over ``R``. + + This is the ring of formal power series `\Lambda[x]`, where + `\Lambda` is the ring of symmetric functions over ``R`` in the + `p`-basis. Its purpose is to house the cycle index series of + species (in a somewhat nonstandard notation tailored to Sage): + If `F` is a species, then the *cycle index series* of `F` is + defined to be the formal power series + + .. MATH:: + + \sum_{n \geq 0} \frac{1}{n!} (\sum_{\sigma \in S_n} + \operatorname{fix} F[\sigma] + \prod_{z \text{ is a cycle of } \sigma} + p_{\text{length of } z}) x^n + \in \Lambda_\QQ [x], + + where `\operatorname{fix} F[\sigma]` denotes the number of + fixed points of the permutation `F[\sigma]` of `F[n]`. We + notice that this power series is "equigraded" (meaning that + its `x^n`-coefficient is homogeneous of degree `n`). A more + standard convention in combinatorics would be to use + `x_i` instead of `p_i`, and drop the `x` (that is, evaluate + the above power series at `x = 1`); but this would be more + difficult to implement in Sage, as it would be an element + of a power series ring in infinitely many variables. + + Note that it is just a :class:`LazyPowerSeriesRing` (whose base + ring is `\Lambda`) whose elements have some extra methods. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: R = CycleIndexSeriesRing(QQ); R + Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis + sage: R([1]).coefficients(4) # This is not combinatorially + ....: # meaningful. + [1, 1, 1, 1] + + TESTS: + + We test to make sure that caching works. + + :: + + sage: R is CycleIndexSeriesRing(QQ) + True + """ + return CycleIndexSeriesRing_class(R) + + +class CycleIndexSeriesRing_class(LazyPowerSeriesRing): + def __init__(self, R): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: R = CycleIndexSeriesRing(QQ); R + Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis + sage: R == loads(dumps(R)) + True + """ + R = SymmetricFunctions(R).power() + LazyPowerSeriesRing.__init__(self, R, element_class=CycleIndexSeries) + + def __repr__(self): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: CycleIndexSeriesRing(QQ) + Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis + """ + return "Cycle Index Series Ring over %s"%self.base_ring() + + +class CycleIndexSeries(LazyPowerSeries): + def count(self, t): + """ + Return the number of structures corresponding to a certain cycle + type ``t``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) + sage: f.count([1]) + 1 + sage: f.count([1,1]) + 4 + sage: f.count([2,1]) + 6 + """ + t = Partition(t) + return t.aut() * self.coefficient_cycle_type(t) + + def coefficient_cycle_type(self, t): + """ + Returns the coefficient of a cycle type ``t`` in ``self``. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) + sage: f.coefficient_cycle_type([1]) + 1 + sage: f.coefficient_cycle_type([1,1]) + 2 + sage: f.coefficient_cycle_type([2,1]) + 3 + """ + t = Partition(t) + p = self.coefficient(t.size()) + return p.coefficient(t) + + + def stretch(self, k): + r""" + Return the stretch of the cycle index series ``self`` by a positive + integer `k`. + + If + + .. MATH:: + + f = \sum_{n=0}^{\infty} f_n(p_1, p_2, p_3, \ldots ), + + then the stretch `g` of `f` by `k` is + + .. MATH:: + + g = \sum_{n=0}^{\infty} f_n(p_k, p_{2k}, p_{3k}, \ldots ). + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) + sage: f.stretch(3).coefficients(10) + [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] + """ + return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) + + def _stretch_gen(self, k, ao): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([p([1])]) # This is the power series whose all coefficients + ....: # are p[1]. Not combinatorially meaningful! + sage: g = f._stretch_gen(2,0) + sage: [next(g) for i in range(10)] + [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] + """ + from sage.combinat.partition import Partition + BR = self.base_ring() + zero = BR.zero() + + stretch_k = lambda p: Partition([k*i for i in p]) + + yield self.coefficient(0).map_support(stretch_k) + + n = 1 + while True: + for i in range(k-1): + yield zero + yield self.coefficient(n).map_support(stretch_k) + n += 1 + + def isotype_generating_series(self): + """ + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: f = cis.isotype_generating_series() + sage: f.coefficients(10) + [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] + """ + R = self.base_ring().base_ring() + OGS = OrdinaryGeneratingSeriesRing(R)() + return OGS._new(self._ogs_gen, lambda ao: ao, self) + + def expand_as_sf(self, n, alphabet='x'): + """ + Returns the expansion of a cycle index series as a symmetric function in + ``n`` variables. + + Specifically, this returns a :class:`~sage.combinat.species.series.LazyPowerSeries` whose + ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` + on the ith term of ``self``. + + This relies on the (standard) interpretation of a cycle index series as a symmetric function + in the power sum basis. + + INPUT: + + - ``self`` -- a cycle index series + + - ``n`` -- a positive integer + + - ``alphabet`` -- a variable for the expansion (default: `x`) + + EXAMPLES:: + + sage: from sage.combinat.species.set_species import SetSpecies + sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4) + [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] + + """ + expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() + LPSR = LazyPowerSeriesRing(expanded_poly_ring) + + expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) + + return LPSR.sum_generator(expander_gen) + + def _ogs_gen(self, ao): + """ + Returns a generator for the coefficients of the ordinary generating + series obtained from a cycle index series. + + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: g = cis._ogs_gen(0) + sage: [next(g) for i in range(10)] + [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] + """ + for i in range(ao): + yield 0 + for i in _integers_from(ao): + yield sum( self.coefficient(i).coefficients() ) + + def generating_series(self): + """ + EXAMPLES:: + + sage: P = species.PartitionSpecies() + sage: cis = P.cycle_index_series() + sage: f = cis.generating_series() + sage: f.coefficients(5) + [1, 1, 1, 5/6, 5/8] + """ + R = self.base_ring().base_ring() + EGS = ExponentialGeneratingSeriesRing(R)() + return EGS._new(self._egs_gen, lambda ao: ao, self) + + def _egs_gen(self, ao): + """ + Returns a generator for the coefficients of the exponential + generating series obtained from a cycle index series. + + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: g = cis._egs_gen(0) + sage: [next(g) for i in range(10)] + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + """ + for i in range(ao): + yield 0 + for i in _integers_from(ao): + yield self.coefficient(i).coefficient([1]*i) + + def __invert__(self): + r""" + Return the multiplicative inverse of ``self``. + + This algorithm is derived from [BLL]_. + + EXAMPLES:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: E.__invert__().coefficients(4) + [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] + + The defining characteristic of the multiplicative inverse `F^{-1}` of + a cycle index series `F` is that `F \cdot F^{-1} = F^{-1} \cdot F = 1` + (that is, both products with `F` yield the multiplicative identity `1`):: + + sage: E = species.SetSpecies().cycle_index_series() + sage: (E * ~E).coefficients(6) + [p[], 0, 0, 0, 0, 0] + + REFERENCES: + + - [BLL]_ + - [BLL-Intro]_ + - http://bergeron.math.uqam.ca/Site/bergeron_anglais_files/livre_combinatoire.pdf + + AUTHORS: + + - Andrew Gainer-Dewar + """ + if self.coefficient(0) == 0: + raise ValueError("constant term must be non-zero") + + def multinv_builder(i): + return self.coefficient(0)**(-i-1) * (self.coefficient(0) + (-1)*self)**i + + return self.parent().sum_generator(multinv_builder(i) for i in _integers_from(0)) + + def _div_(self, y): + """ + TESTS:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: (E / E).coefficients(6) + [p[], 0, 0, 0, 0, 0] + """ + return self*(~y) + + def functorial_composition(self, g): + r""" + Returns the functorial composition of ``self`` and ``g``. + + If `F` and `G` are species, their functorial composition is the species + `F \Box G` obtained by setting `(F \Box G) [A] = F[ G[A] ]`. + In other words, an `(F \Box G)`-structure on a set `A` of labels is an + `F`-structure whose labels are the set of all `G`-structures on `A`. + + It can be shown (as in section 2.2 of [BLL]_) that there is a + corresponding operation on cycle indices: + + .. MATH:: + + Z_{F} \Box Z_{G} = \sum_{n \geq 0} \frac{1}{n!} + \sum_{\sigma \in \mathfrak{S}_{n}} + \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] + \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots. + + This method implements that operation on cycle index series. + + EXAMPLES: + + The species `G` of simple graphs can be expressed in terms of a functorial + composition: `G = \mathfrak{p} \Box \mathfrak{p}_{2}`, where + `\mathfrak{p}` is the :class:`~sage.combinat.species.subset_species.SubsetSpecies`. + This is how it is implemented in + :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: + + sage: S = species.SimpleGraphSpecies() + sage: S.cycle_index_series().coefficients(5) + [p[], + p[1], + p[1, 1] + p[2], + 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], + 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] + """ + return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) + + def _functorial_compose_gen(self, g, ao): + """ + Return a generator for the coefficients of the functorial + composition of ``self`` with ``g``. + + EXAMPLES:: + + sage: E = species.SetSpecies() + sage: E2 = species.SetSpecies(size=2) + sage: WP = species.SubsetSpecies() + sage: P2 = E2*E + sage: P2_cis = P2.cycle_index_series() + sage: WP_cis = WP.cycle_index_series() + sage: g = WP_cis._functorial_compose_gen(P2_cis,0) + sage: [next(g) for i in range(5)] + [p[], + p[1], + p[1, 1] + p[2], + 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], + 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] + """ + p = self.parent().base_ring() + n = 0 + while True: + res = p(0) + for s in Partitions(n): + t = g._cycle_type(s) + q = self.count(t) / s.aut() + res += q*p(s) + yield res + n += 1 + + def arithmetic_product(self, g, check_input = True): + r""" + Return the arithmetic product of ``self`` with ``g``. + + For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`, + their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures". + This operation is defined and several examples are given in [MM]_. + + The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`, + as implemented in this method. + + INPUT: + + - ``g`` -- a cycle index series having the same parent as ``self``. + + - ``check_input`` -- (default: ``True``) a Boolean which, when set + to ``False``, will cause input checks to be skipped. + + OUTPUT: + + The arithmetic product of ``self`` with ``g``. This is a cycle + index series defined in terms of ``self`` and ``g`` such that + if ``self`` and ``g`` are the cycle index series of two species + `M` and `N`, their arithmetic product is the cycle index series + of the species `M \\boxdot N`. + + EXAMPLES: + + For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds + to the species of "regular octopuses"; a `(C \\boxdot L_{+})`-structure is a cycle of some length, each of whose elements + is an ordered list of a length which is consistent for all the lists in the structure. :: + + sage: C = species.CycleSpecies().cycle_index_series() + sage: Lplus = species.LinearOrderSpecies(min=1).cycle_index_series() + sage: RegularOctopuses = C.arithmetic_product(Lplus) + sage: RegOctSpeciesSeq = RegularOctopuses.generating_series().counts(8) + sage: RegOctSpeciesSeq + [0, 1, 3, 8, 42, 144, 1440, 5760] + + It is shown in [MM]_ that the exponential generating function for regular octopuses satisfies + `(C \\boxdot L_{+}) (x) = \\sum_{n \geq 1} \\sigma (n) (n - 1)! \\frac{x^{n}}{n!}` (where `\\sigma (n)` is + the sum of the divisors of `n`). :: + + sage: RegOctDirectSeq = [0] + [sum(divisors(i))*factorial(i-1) for i in range(1,8)] + sage: RegOctDirectSeq == RegOctSpeciesSeq + True + + AUTHORS: + + - Andrew Gainer-Dewar (2013) + + REFERENCES: + + .. [MM] \M. Maia and M. Mendez. "On the arithmetic product of combinatorial species". + Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427. + :arxiv:`math/0503436v2`. + + """ + from itertools import product, repeat, chain + + p = self.base_ring() + + if check_input: + assert self.coefficient(0) == p.zero() + assert g.coefficient(0) == p.zero() + + # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_. + def arith_prod_of_partitions(l1, l2): + # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by + # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes + # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2` + # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a + # partition of `nm`. + term_iterable = chain.from_iterable(repeat(lcm(pair), gcd(pair)) + for pair in product(l1, l2)) + return Partition(sorted(term_iterable, reverse=True)) + + # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_. + # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric + # functions, but this boils down to the same: Their x_i corresponds to the i-th power + # sum symmetric function.) + def arith_prod_sf(x, y): + ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2)) + return p._apply_multi_module_morphism(x, y, ap_sf_wrapper) + + # Sage stores cycle index series by degree. + # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful + # to compute all terms of a given degree `n` at once. + def arith_prod_coeff(n): + if n == 0: + res = p.zero() + else: + index_set = ((d, n // d) for d in divisors(n)) + res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set) + + # Build a list which has res in the `n`th slot and 0's before and after + # to feed to sum_generator + res_in_seq = [p.zero()]*n + [res, p.zero()] + + return self.parent(res_in_seq) + + # Finally, we use the sum_generator method to assemble these results into a single + # LazyPowerSeries object. + return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) + + def _cycle_type(self, s): + """ + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[3, 1, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] + sage: cis = species.PermutationSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[3, 1, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1]] + sage: cis = species.SetSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[1], [1], [1]] + """ + if s == []: + return self._card(0) + res = [] + for k in range(1, self._upper_bound_for_longest_cycle(s)+1): + e = 0 + for d in divisors(k): + m = moebius(d) + if m == 0: + continue + u = s.power(k/d) + e += m*self.count(u) + res.extend([k]*int(e/k)) + res.reverse() + return Partition(res) + + + def _upper_bound_for_longest_cycle(self, s): + """ + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: cis._upper_bound_for_longest_cycle([4]) + 4 + sage: cis._upper_bound_for_longest_cycle([3,1]) + 3 + sage: cis._upper_bound_for_longest_cycle([2,2]) + 2 + sage: cis._upper_bound_for_longest_cycle([2,1,1]) + 2 + sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) + 1 + """ + if s == []: + return 1 + return min(self._card(sum(s)), lcm(list(s))) + + def _card(self, n): + r""" + Return the number of structures on an underlying set of size ``n`` for + the species associated with ``self``. + + This is just ``n!`` times the coefficient of ``p[1]n`` in ``self``. + + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: cis._card(4) + 15 + """ + p = self.coefficient(n) + return factorial(n) * p.coefficient([1] * n) + + def _compose_gen(self, y, ao): + """ + Return a generator for the coefficients of the composition of this + cycle index series and the cycle index series ``y``. This overrides + the method defined in ``LazyPowerSeries``. + + The notion "composition" means plethystic substitution here, as + defined in Section 2.2 of [BLL-Intro]_. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: g = E_cis._compose_gen(C.cycle_index_series(),0) + sage: [next(g) for i in range(4)] + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + assert y.coefficient(0) == 0 + y_powers = Stream(y._power_gen()) + + parent = self.parent() + res = parent.sum_generator(self._compose_term(self.coefficient(i), y_powers) + for i in _integers_from(0)) + + for i in _integers_from(0): + yield res.coefficient(i) + + def _compose_term(self, p, y_powers): + r""" + Return the composition of one term in ``self`` with `y`. + + INPUT: + + - ``p`` - a term in ``self`` + - ``y_powers`` - a stream for the powers of `y` + starting with `y` + + EXAMPLES:: + + sage: from sage.combinat.species.stream import Stream + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: C_cis = C.cycle_index_series() + sage: c_powers = Stream(C_cis._power_gen()) + sage: p2 = E_cis.coefficient(2); p2 + 1/2*p[1, 1] + 1/2*p[2] + sage: E_cis._compose_term(p2, c_powers).coefficients(4) + [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] + """ + parent = self.parent() + if p == 0: + return parent(0) + + res = [] + #Go through all the partition, coefficient pairs in the term p + for m, c in p: + res_t = parent.term(c, 0) + + for e,v in enumerate(m.to_exp()): + if v == 0: + continue + res_t = res_t * y_powers[v-1].stretch(e+1) + res.append(res_t) + + return parent.sum(res) + + def weighted_composition(self, y_species): + r""" + Return the composition of this cycle index series with the cycle + index series of the weighted species ``y_species``. + + Note that this is basically the same algorithm as composition + except we can not use the optimization that the powering of cycle + index series commutes with 'stretching'. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: E_cis.weighted_composition(C).coefficients(4) + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + sage: E(C).cycle_index_series().coefficients(4) + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + base_ring = self.base_ring() + y = y_species.cycle_index_series(base_ring) + assert y.coefficient(0) == 0 + return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) + + + def _weighted_compose_gen(self, y_species, ao): + r""" + Return an iterator for the composition of this cycle index series + and the cycle index series of the weighted species ``y_species``. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: g = E_cis._weighted_compose_gen(C,0) + sage: [next(g) for i in range(4)] + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + parent = self.parent() + res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) + for i in _integers_from(0)) + + for i in _integers_from(0): + yield res.coefficient(i) + + def _weighted_compose_term(self, p, y_species): + r""" + Return the weighted composition of one term in ``self`` with ``y``. + + INPUT: + + - ``p`` -- a term in ``self`` + - ``y_species`` -- a species + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: p2 = E_cis.coefficient(2); p2 + 1/2*p[1, 1] + 1/2*p[2] + sage: E_cis._weighted_compose_term(p2, C).coefficients(4) + [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] + """ + parent = self.parent() + if p == 0: + return parent(0) + + base_ring = self.base_ring().base_ring() + + res = [] + #Go through all the partition, coefficient pairs in the term p + for m, c in p: + res_t = parent.term(c, 0) + + for e,v in enumerate(m.to_exp()): + if v == 0: + continue + res_t = res_t * (y_species.weighted(y_species._weight**(e+1)).cycle_index_series(base_ring)**v).stretch(e+1) + res.append(res_t) + + return parent.sum(res) + + def compositional_inverse(self): + r""" + Return the compositional inverse of ``self`` if possible. + + (Specifically, if ``self`` is of the form `0 + p_{1} + \cdots`.) + + The compositional inverse is the inverse with respect to + plethystic substitution. This is the operation on cycle index + series which corresponds to substitution, a.k.a. partitional + composition, on the level of species. See Section 2.2 of + [BLL]_ for a definition of this operation. + + EXAMPLES:: + + sage: Eplus = species.SetSpecies(min=1).cycle_index_series() + sage: Eplus(Eplus.compositional_inverse()).coefficients(8) + [0, p[1], 0, 0, 0, 0, 0, 0] + + TESTS:: + + sage: Eplus = species.SetSpecies(min=2).cycle_index_series() + sage: Eplus.compositional_inverse() + Traceback (most recent call last): + ... + ValueError: not an invertible series + + ALGORITHM: + + Let `F` be a species satisfying `F = 0 + X + F_2 + F_3 + \cdots` for + `X` the species of singletons. (Equivalently, `\lvert F[\varnothing] + \rvert = 0` and `\lvert F[\{1\}] \rvert = 1`.) Then there exists a + (virtual) species `G` satisfying `F \circ G = G \circ F = X`. + + It follows that `(F - X) \circ G = F \circ G - X \circ G = X - G`. + Rearranging, we obtain the recursive equation `G = X - (F - X) \circ G`, + which can be solved using iterative methods. + + .. WARNING:: + + This algorithm is functional but can be very slow. + Use with caution! + + .. SEEALSO:: + + The compositional inverse `\Omega` of the species `E_{+}` + of nonempty sets can be handled much more efficiently + using specialized methods. See + :func:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries` + + AUTHORS: + + - Andrew Gainer-Dewar + """ + cisr = self.parent() + sfa = cisr._base + + X = cisr([0, sfa([1]), 0]) + + if self.coefficients(2) != X.coefficients(2): + raise ValueError('not an invertible series') + + res = cisr() + res.define(X - (self - X).compose(res)) + + return res + + def derivative(self, order=1): + r""" + Return the species-theoretic `n`-th derivative of ``self``, + where `n` is ``order``. + + For a cycle index series `F (p_{1}, p_{2}, p_{3}, \ldots)`, its + derivative is the cycle index series `F' = D_{p_{1}} F` (that is, + the formal derivative of `F` with respect to the variable `p_{1}`). + + If `F` is the cycle index series of a species `S` then `F'` is the + cycle index series of an associated species `S'` of `S`-structures + with a "hole". + + EXAMPLES: + + The species `E` of sets satisfies the relationship `E' = E`:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: E.coefficients(8) == E.derivative().coefficients(8) + True + + The species `C` of cyclic orderings and the species `L` of linear + orderings satisfy the relationship `C' = L`:: + + sage: C = species.CycleSpecies().cycle_index_series() + sage: L = species.LinearOrderSpecies().cycle_index_series() + sage: L.coefficients(8) == C.derivative().coefficients(8) + True + """ + # Make sure that order is integral + order = Integer(order) + + if order < 0: + raise ValueError("Order must be a non-negative integer") + + elif order == 0: + return self + + elif order == 1: + parent = self.parent() + derivative_term = lambda n: parent.term(self.coefficient(n+1).derivative_with_respect_to_p1(), n) + return parent.sum_generator(derivative_term(i) for i in _integers_from(0)) + + else: + return self.derivative(order-1) + + def pointing(self): + r""" + Return the species-theoretic pointing of ``self``. + + For a cycle index `F`, its pointing is the cycle index series + `F^{\bullet} = p_{1} \cdot F'`. + + If `F` is the cycle index series of a species `S` then `F^{\bullet}` + is the cycle index series of an associated species `S^{\bullet}` + of `S`-structures with a marked "root". + + EXAMPLES: + + The species `E^{\bullet}` of "pointed sets" satisfies + `E^{\bullet} = X \cdot E`:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: X = species.SingletonSpecies().cycle_index_series() + sage: E.pointing().coefficients(8) == (X*E).coefficients(8) + True + + """ + p1 = self.base_ring()([1]) + X = self.parent()([0, p1, 0]) + + return X*self.derivative() + + def integral(self, *args): + r""" + Given a cycle index `G`, it is not in general possible to recover a + single cycle index `F` such that `F' = G` (even up to addition of a + constant term). + + More broadly, it may be the case that there are many non-isomorphic + species `S` such that `S' = T` for a given species `T`. + For example, the species `3 C_{3}` of 3-cycles from three distinct + classes and the species `X^{3}` of 3-sets are not isomorphic, but + `(3 C_{3})' = (X^{3})' = 3 X^{2}`. + + EXAMPLES:: + + sage: C3 = species.CycleSpecies(size=3).cycle_index_series() + sage: X = species.SingletonSpecies().cycle_index_series() + sage: (3*C3).derivative().coefficients(8) == (3*X^2).coefficients(8) + True + sage: (X^3).derivative().coefficients(8) == (3*X^2).coefficients(8) + True + + .. WARNING:: + + This method has no implementation and exists only to prevent you from + doing something strange. Calling it raises a ``NotImplementedError``! + """ + raise NotImplementedError + + def exponential(self): + r""" + Return the species-theoretic exponential of ``self``. + + For a cycle index `Z_{F}` of a species `F`, its exponential is the + cycle index series `Z_{E} \circ Z_{F}`, where `Z_{E}` is the + :meth:`~sage.combinat.species.generating_series.ExponentialCycleIndexSeries`. + + The exponential `Z_{E} \circ Z_{F}` is then the cycle index series + of the species `E \circ F` of "sets of `F`-structures". + + EXAMPLES: + + Let `BT` be the species of binary trees, `BF` the species of binary + forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: + + sage: BT = species.BinaryTreeSpecies().cycle_index_series() + sage: BF = species.BinaryForestSpecies().cycle_index_series() + sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) + True + """ + base_ring = self.parent().base_ring().base_ring() + E = ExponentialCycleIndexSeries(base_ring) + return E.compose(self) + + def logarithm(self): + r""" + Return the combinatorial logarithm of ``self``. + + For a cycle index `Z_{F}` of a species `F`, its logarithm is the + cycle index series `Z_{\Omega} \circ Z_{F}`, where `Z_{\Omega}` is the + :meth:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries`. + + The logarithm `Z_{\Omega} \circ Z_{F}` is then the cycle index series + of the (virtual) species `\Omega \circ F` of "connected `F`-structures". + In particular, if `F = E^{+} \circ G` for `E^{+}` the species of + nonempty sets and `G` some other species, then `\Omega \circ F = G`. + + EXAMPLES: + + Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected + graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: + + sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 + sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries + sage: CG = LogarithmCycleIndexSeries().compose(G) + sage: CG.isotype_generating_series().coefficients(8) + [0, 1, 1, 2, 6, 21, 112, 853] + """ + base_ring = self.parent().base_ring().base_ring() + Omega = LogarithmCycleIndexSeries(base_ring) + return Omega.compose(self) + +@cached_function +def _exp_term(n, R = RationalField()): + """ + Compute the order-n term of the cycle index series of the species `E` of sets. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import _exp_term + sage: [_exp_term(i) for i in range(4)] + [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] + """ + p = SymmetricFunctions(R).power() + return sum(p(part) / part.aut() for part in Partitions(n)) + + +def _exp_gen(R = RationalField()): + r""" + Produce a generator which yields the terms of the cycle index + series of the species `E` of sets. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import _exp_gen + sage: g = _exp_gen() + sage: [next(g) for i in range(4)] + [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] + """ + return (_exp_term(i, R) for i in _integers_from(0)) + +@cached_function +def ExponentialCycleIndexSeries(R = RationalField()): + r""" + Return the cycle index series of the species `E` of sets. + + This cycle index satisfies + + .. MATH:: + + Z_{E} = \sum_{n \geq 0} \sum_{\lambda \vdash n} + \frac{p_{\lambda}}{z_{\lambda}}. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries + sage: ExponentialCycleIndexSeries().coefficients(5) + [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + + 1/3*p[3, 1] + 1/4*p[4]] + """ + CIS = CycleIndexSeriesRing(R) + return CIS(_exp_gen(R)) + + +@cached_function +def _cl_term(n, R = RationalField()): + r""" + Compute the order-n term of the cycle index series of the virtual species + `\Omega`, the compositional inverse of the species `E^{+}` of nonempty sets. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import _cl_term + sage: [_cl_term(i) for i in range(4)] + [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] + """ + n = Integer(n) # check that n is an integer + + p = SymmetricFunctions(R).power() + + res = p.zero() + if n == 1: + res = p([1]) + elif n > 1: + res = 1/n * ((-1)**(n-1) * p([1])**n - sum(d * p([n // d]).plethysm(_cl_term(d, R)) for d in divisors(n)[:-1])) + + return res + + +def _cl_gen (R = RationalField()): + r""" + Produce a generator which yields the terms of the cycle index series + of the virtual species `\Omega`, the compositional inverse of the + species `E^{+}` of nonempty sets. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import _cl_gen + sage: g = _cl_gen() + sage: [next(g) for i in range(4)] + [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] + """ + return (_cl_term(i, R) for i in _integers_from(0)) + + +@cached_function +def LogarithmCycleIndexSeries(R = RationalField()): + r""" + Return the cycle index series of the virtual species `\Omega`, the + compositional inverse of the species `E^{+}` of nonempty sets. + + The notion of virtual species is treated thoroughly in [BLL]_. + The specific algorithm used here to compute the cycle index of + `\Omega` is found in [Labelle2008]_. + + EXAMPLES: + + The virtual species `\Omega` is 'properly virtual', in the sense that + its cycle index has negative coefficients:: + + sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries + sage: LogarithmCycleIndexSeries().coefficients(4) + [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] + + Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` + (that is, that composition with `E^{+}` in both directions yields the + multiplicative identity `X`):: + + sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() + sage: LogarithmCycleIndexSeries().compose(Eplus).coefficients(4) + [0, p[1], 0, 0] + """ + CIS = CycleIndexSeriesRing(R) + return CIS(_cl_gen(R)) + From b59c21ddd5e47e2c22f84eea66da133846de1d60 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 11 Aug 2021 23:39:49 +0530 Subject: [PATCH 011/350] Created Ordinary Generating Series Ring and Exponential Generating Series Ring --- .../combinat/species/new_generating_series.py | 1255 +---------------- 1 file changed, 50 insertions(+), 1205 deletions(-) diff --git a/src/sage/combinat/species/new_generating_series.py b/src/sage/combinat/species/new_generating_series.py index f87d3c07613..2c271aa6d6e 100644 --- a/src/sage/combinat/species/new_generating_series.py +++ b/src/sage/combinat/species/new_generating_series.py @@ -13,51 +13,6 @@ One notable difference is that we use power-sum symmetric functions as the coefficients of our cycle index series. -TESTS:: - - sage: from sage.combinat.species.stream import Stream, _integers_from - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - -:: - - sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) - sage: geo2 = CIS((p([2])^i for i in _integers_from(0))) - sage: s = geo1 * geo2 - sage: s[0] - p[] - sage: s[1] - p[1] + p[2] - sage: s[2] - p[1, 1] + p[2, 1] + p[2, 2] - sage: s[3] - p[1, 1, 1] + p[2, 1, 1] + p[2, 2, 1] + p[2, 2, 2] - -Whereas the coefficients of the above test are homogeneous with -respect to total degree, the following test groups with respect to -weighted degree where each variable x_i has weight i. - -:: - - sage: def g(): - ....: for i in _integers_from(0): - ....: yield p([2])^i - ....: yield p(0) - sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) - sage: geo2 = CIS(g()) - sage: s = geo1 * geo2 - sage: s[0] - p[] - sage: s[1] - p[1] - sage: s[2] - p[1, 1] + p[2] - sage: s[3] - p[1, 1, 1] + p[2, 1] - sage: s[4] - p[1, 1, 1, 1] + p[2, 1, 1] + p[2, 2] - REFERENCES: .. [BLL] \F. Bergeron, G. Labelle, and P. Leroux. @@ -77,8 +32,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from .series import LazyPowerSeriesRing, LazyPowerSeries -from .stream import Stream, _integers_from +from sage.rings.lazy_laurent_series import LazyTaylorSeries +from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing from sage.rings.all import Integer, RationalField from sage.arith.all import moebius, gcd, lcm, divisors from sage.combinat.partition import Partition, Partitions @@ -87,59 +42,44 @@ from sage.misc.cachefunc import cached_function from sage.functions.other import factorial - -@cached_function -def OrdinaryGeneratingSeriesRing(R): - """ - Return the ring of ordinary generating series over ``R``. - - Note that it is just a - :class:`LazyPowerSeriesRing` whose elements have - some extra methods. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ); R - Lazy Power Series Ring over Rational Field - sage: R([1]).coefficients(4) - [1, 1, 1, 1] - sage: R([1]).counts(4) - [1, 1, 1, 1] - - TESTS: - - We test to make sure that caching works. - - :: - - sage: R is OrdinaryGeneratingSeriesRing(QQ) - True - """ - return OrdinaryGeneratingSeriesRing_class(R) - - -class OrdinaryGeneratingSeriesRing_class(LazyPowerSeriesRing): +class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): def __init__(self, R): """ EXAMPLES:: - sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: R = OrdinaryGeneratingSeriesRing(QQ); R + Lazy Taylor Series Ring in z over Rational Field + sage: [R(lambda n: 1)[i] for i in range(4)] + [1, 1, 1, 1] + sage: R(lambda n: 1).counts(4) + [1, 1, 1, 1] sage: R == loads(dumps(R)) True + + TESTS: + + We test to make sure that caching works. + + :: + + sage: R is OrdinaryGeneratingSeriesRing(QQ) + True + """ - LazyPowerSeriesRing.__init__(self, R, element_class=OrdinaryGeneratingSeries) + LazyTaylorSeriesRing.Element = OrdinaryGeneratingSeries + LazyTaylorSeriesRing.__init__(self, R, 'z') -class OrdinaryGeneratingSeries(LazyPowerSeries): +class OrdinaryGeneratingSeries(LazyTaylorSeries): def count(self, n): """ Return the number of structures on a set of size ``n``. EXAMPLES:: - sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.count(10) @@ -154,7 +94,7 @@ def counts(self, n): EXAMPLES:: - sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.counts(10) @@ -163,59 +103,45 @@ def counts(self, n): return [self.count(i) for i in range(n)] -@cached_function -def ExponentialGeneratingSeriesRing(R): - """ - Return the ring of exponential generating series over ``R``. - - Note that it is just a - :class:`LazyPowerSeriesRing` whose elements have - some extra methods. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ); R - Lazy Power Series Ring over Rational Field - sage: R([1]).coefficients(4) - [1, 1, 1, 1] - sage: R([1]).counts(4) - [1, 1, 2, 6] +class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): + def __init__(self, R): + """ + EXAMPLES:: - TESTS: + sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ); R + Lazy Taylor Series Ring in z over Rational Field + sage: R == loads(dumps(R)) + True + sage: [R(lambda n: 1).coefficient(i) for i in range(4)] + [1, 1, 1, 1] + sage: R(lambda n: 1).counts(4) + [1, 1, 2, 6] - We test to make sure that caching works. + TESTS: - :: + We test to make sure that caching works. - sage: R is ExponentialGeneratingSeriesRing(QQ) - True - """ - return ExponentialGeneratingSeriesRing_class(R) + :: + sage: R is ExponentialGeneratingSeriesRing(QQ) + True -class ExponentialGeneratingSeriesRing_class(LazyPowerSeriesRing): - def __init__(self, R): """ - EXAMPLES:: + LazyTaylorSeriesRing.Element = ExponentialGeneratingSeries + LazyTaylorSeriesRing.__init__(self, R, 'z') - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: R == loads(dumps(R)) - True - """ - LazyPowerSeriesRing.__init__(self, R, element_class=ExponentialGeneratingSeries) -class ExponentialGeneratingSeries(LazyPowerSeries): +class ExponentialGeneratingSeries(LazyTaylorSeries): def count(self, n): """ Return the number of structures of size ``n``. EXAMPLES:: - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: f = R([1]) + sage: f = R(lambda n: 1) sage: [f.count(i) for i in range(7)] [1, 1, 2, 6, 24, 120, 720] """ @@ -228,7 +154,7 @@ def counts(self, n): EXAMPLES:: - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing sage: R = ExponentialGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.counts(5) @@ -282,1085 +208,4 @@ def _functorial_compose_gen(self, y, ao): n = 0 while True: yield self.count(y.count(n)) / factorial(n) - n += 1 - - -def factorial_gen(): - """ - A generator for the factorials starting at 0. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import factorial_gen - sage: g = factorial_gen() - sage: [next(g) for i in range(5)] - [1, 1, 2, 6, 24] - """ - z = Integer(1) - yield z - yield z - n = Integer(2) - while True: - z *= n - yield z - n += 1 - - -@cached_function -def CycleIndexSeriesRing(R): - r""" - Return the ring of cycle index series over ``R``. - - This is the ring of formal power series `\Lambda[x]`, where - `\Lambda` is the ring of symmetric functions over ``R`` in the - `p`-basis. Its purpose is to house the cycle index series of - species (in a somewhat nonstandard notation tailored to Sage): - If `F` is a species, then the *cycle index series* of `F` is - defined to be the formal power series - - .. MATH:: - - \sum_{n \geq 0} \frac{1}{n!} (\sum_{\sigma \in S_n} - \operatorname{fix} F[\sigma] - \prod_{z \text{ is a cycle of } \sigma} - p_{\text{length of } z}) x^n - \in \Lambda_\QQ [x], - - where `\operatorname{fix} F[\sigma]` denotes the number of - fixed points of the permutation `F[\sigma]` of `F[n]`. We - notice that this power series is "equigraded" (meaning that - its `x^n`-coefficient is homogeneous of degree `n`). A more - standard convention in combinatorics would be to use - `x_i` instead of `p_i`, and drop the `x` (that is, evaluate - the above power series at `x = 1`); but this would be more - difficult to implement in Sage, as it would be an element - of a power series ring in infinitely many variables. - - Note that it is just a :class:`LazyPowerSeriesRing` (whose base - ring is `\Lambda`) whose elements have some extra methods. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - sage: R([1]).coefficients(4) # This is not combinatorially - ....: # meaningful. - [1, 1, 1, 1] - - TESTS: - - We test to make sure that caching works. - - :: - - sage: R is CycleIndexSeriesRing(QQ) - True - """ - return CycleIndexSeriesRing_class(R) - - -class CycleIndexSeriesRing_class(LazyPowerSeriesRing): - def __init__(self, R): - """ - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - sage: R == loads(dumps(R)) - True - """ - R = SymmetricFunctions(R).power() - LazyPowerSeriesRing.__init__(self, R, element_class=CycleIndexSeries) - - def __repr__(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ) - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - """ - return "Cycle Index Series Ring over %s"%self.base_ring() - - -class CycleIndexSeries(LazyPowerSeries): - def count(self, t): - """ - Return the number of structures corresponding to a certain cycle - type ``t``. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) - sage: f.count([1]) - 1 - sage: f.count([1,1]) - 4 - sage: f.count([2,1]) - 6 - """ - t = Partition(t) - return t.aut() * self.coefficient_cycle_type(t) - - def coefficient_cycle_type(self, t): - """ - Returns the coefficient of a cycle type ``t`` in ``self``. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) - sage: f.coefficient_cycle_type([1]) - 1 - sage: f.coefficient_cycle_type([1,1]) - 2 - sage: f.coefficient_cycle_type([2,1]) - 3 - """ - t = Partition(t) - p = self.coefficient(t.size()) - return p.coefficient(t) - - - def stretch(self, k): - r""" - Return the stretch of the cycle index series ``self`` by a positive - integer `k`. - - If - - .. MATH:: - - f = \sum_{n=0}^{\infty} f_n(p_1, p_2, p_3, \ldots ), - - then the stretch `g` of `f` by `k` is - - .. MATH:: - - g = \sum_{n=0}^{\infty} f_n(p_k, p_{2k}, p_{3k}, \ldots ). - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) - sage: f.stretch(3).coefficients(10) - [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] - """ - return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) - - def _stretch_gen(self, k, ao): - """ - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([p([1])]) # This is the power series whose all coefficients - ....: # are p[1]. Not combinatorially meaningful! - sage: g = f._stretch_gen(2,0) - sage: [next(g) for i in range(10)] - [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] - """ - from sage.combinat.partition import Partition - BR = self.base_ring() - zero = BR.zero() - - stretch_k = lambda p: Partition([k*i for i in p]) - - yield self.coefficient(0).map_support(stretch_k) - - n = 1 - while True: - for i in range(k-1): - yield zero - yield self.coefficient(n).map_support(stretch_k) - n += 1 - - def isotype_generating_series(self): - """ - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.isotype_generating_series() - sage: f.coefficients(10) - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - """ - R = self.base_ring().base_ring() - OGS = OrdinaryGeneratingSeriesRing(R)() - return OGS._new(self._ogs_gen, lambda ao: ao, self) - - def expand_as_sf(self, n, alphabet='x'): - """ - Returns the expansion of a cycle index series as a symmetric function in - ``n`` variables. - - Specifically, this returns a :class:`~sage.combinat.species.series.LazyPowerSeries` whose - ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` - on the ith term of ``self``. - - This relies on the (standard) interpretation of a cycle index series as a symmetric function - in the power sum basis. - - INPUT: - - - ``self`` -- a cycle index series - - - ``n`` -- a positive integer - - - ``alphabet`` -- a variable for the expansion (default: `x`) - - EXAMPLES:: - - sage: from sage.combinat.species.set_species import SetSpecies - sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4) - [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] - - """ - expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() - LPSR = LazyPowerSeriesRing(expanded_poly_ring) - - expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) - - return LPSR.sum_generator(expander_gen) - - def _ogs_gen(self, ao): - """ - Returns a generator for the coefficients of the ordinary generating - series obtained from a cycle index series. - - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: g = cis._ogs_gen(0) - sage: [next(g) for i in range(10)] - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield sum( self.coefficient(i).coefficients() ) - - def generating_series(self): - """ - EXAMPLES:: - - sage: P = species.PartitionSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.generating_series() - sage: f.coefficients(5) - [1, 1, 1, 5/6, 5/8] - """ - R = self.base_ring().base_ring() - EGS = ExponentialGeneratingSeriesRing(R)() - return EGS._new(self._egs_gen, lambda ao: ao, self) - - def _egs_gen(self, ao): - """ - Returns a generator for the coefficients of the exponential - generating series obtained from a cycle index series. - - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: g = cis._egs_gen(0) - sage: [next(g) for i in range(10)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield self.coefficient(i).coefficient([1]*i) - - def __invert__(self): - r""" - Return the multiplicative inverse of ``self``. - - This algorithm is derived from [BLL]_. - - EXAMPLES:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: E.__invert__().coefficients(4) - [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] - - The defining characteristic of the multiplicative inverse `F^{-1}` of - a cycle index series `F` is that `F \cdot F^{-1} = F^{-1} \cdot F = 1` - (that is, both products with `F` yield the multiplicative identity `1`):: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E * ~E).coefficients(6) - [p[], 0, 0, 0, 0, 0] - - REFERENCES: - - - [BLL]_ - - [BLL-Intro]_ - - http://bergeron.math.uqam.ca/Site/bergeron_anglais_files/livre_combinatoire.pdf - - AUTHORS: - - - Andrew Gainer-Dewar - """ - if self.coefficient(0) == 0: - raise ValueError("constant term must be non-zero") - - def multinv_builder(i): - return self.coefficient(0)**(-i-1) * (self.coefficient(0) + (-1)*self)**i - - return self.parent().sum_generator(multinv_builder(i) for i in _integers_from(0)) - - def _div_(self, y): - """ - TESTS:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E / E).coefficients(6) - [p[], 0, 0, 0, 0, 0] - """ - return self*(~y) - - def functorial_composition(self, g): - r""" - Returns the functorial composition of ``self`` and ``g``. - - If `F` and `G` are species, their functorial composition is the species - `F \Box G` obtained by setting `(F \Box G) [A] = F[ G[A] ]`. - In other words, an `(F \Box G)`-structure on a set `A` of labels is an - `F`-structure whose labels are the set of all `G`-structures on `A`. - - It can be shown (as in section 2.2 of [BLL]_) that there is a - corresponding operation on cycle indices: - - .. MATH:: - - Z_{F} \Box Z_{G} = \sum_{n \geq 0} \frac{1}{n!} - \sum_{\sigma \in \mathfrak{S}_{n}} - \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] - \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots. - - This method implements that operation on cycle index series. - - EXAMPLES: - - The species `G` of simple graphs can be expressed in terms of a functorial - composition: `G = \mathfrak{p} \Box \mathfrak{p}_{2}`, where - `\mathfrak{p}` is the :class:`~sage.combinat.species.subset_species.SubsetSpecies`. - This is how it is implemented in - :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: - - sage: S = species.SimpleGraphSpecies() - sage: S.cycle_index_series().coefficients(5) - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) - - def _functorial_compose_gen(self, g, ao): - """ - Return a generator for the coefficients of the functorial - composition of ``self`` with ``g``. - - EXAMPLES:: - - sage: E = species.SetSpecies() - sage: E2 = species.SetSpecies(size=2) - sage: WP = species.SubsetSpecies() - sage: P2 = E2*E - sage: P2_cis = P2.cycle_index_series() - sage: WP_cis = WP.cycle_index_series() - sage: g = WP_cis._functorial_compose_gen(P2_cis,0) - sage: [next(g) for i in range(5)] - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - p = self.parent().base_ring() - n = 0 - while True: - res = p(0) - for s in Partitions(n): - t = g._cycle_type(s) - q = self.count(t) / s.aut() - res += q*p(s) - yield res - n += 1 - - def arithmetic_product(self, g, check_input = True): - r""" - Return the arithmetic product of ``self`` with ``g``. - - For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`, - their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures". - This operation is defined and several examples are given in [MM]_. - - The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`, - as implemented in this method. - - INPUT: - - - ``g`` -- a cycle index series having the same parent as ``self``. - - - ``check_input`` -- (default: ``True``) a Boolean which, when set - to ``False``, will cause input checks to be skipped. - - OUTPUT: - - The arithmetic product of ``self`` with ``g``. This is a cycle - index series defined in terms of ``self`` and ``g`` such that - if ``self`` and ``g`` are the cycle index series of two species - `M` and `N`, their arithmetic product is the cycle index series - of the species `M \\boxdot N`. - - EXAMPLES: - - For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds - to the species of "regular octopuses"; a `(C \\boxdot L_{+})`-structure is a cycle of some length, each of whose elements - is an ordered list of a length which is consistent for all the lists in the structure. :: - - sage: C = species.CycleSpecies().cycle_index_series() - sage: Lplus = species.LinearOrderSpecies(min=1).cycle_index_series() - sage: RegularOctopuses = C.arithmetic_product(Lplus) - sage: RegOctSpeciesSeq = RegularOctopuses.generating_series().counts(8) - sage: RegOctSpeciesSeq - [0, 1, 3, 8, 42, 144, 1440, 5760] - - It is shown in [MM]_ that the exponential generating function for regular octopuses satisfies - `(C \\boxdot L_{+}) (x) = \\sum_{n \geq 1} \\sigma (n) (n - 1)! \\frac{x^{n}}{n!}` (where `\\sigma (n)` is - the sum of the divisors of `n`). :: - - sage: RegOctDirectSeq = [0] + [sum(divisors(i))*factorial(i-1) for i in range(1,8)] - sage: RegOctDirectSeq == RegOctSpeciesSeq - True - - AUTHORS: - - - Andrew Gainer-Dewar (2013) - - REFERENCES: - - .. [MM] \M. Maia and M. Mendez. "On the arithmetic product of combinatorial species". - Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427. - :arxiv:`math/0503436v2`. - - """ - from itertools import product, repeat, chain - - p = self.base_ring() - - if check_input: - assert self.coefficient(0) == p.zero() - assert g.coefficient(0) == p.zero() - - # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_. - def arith_prod_of_partitions(l1, l2): - # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by - # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes - # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2` - # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a - # partition of `nm`. - term_iterable = chain.from_iterable(repeat(lcm(pair), gcd(pair)) - for pair in product(l1, l2)) - return Partition(sorted(term_iterable, reverse=True)) - - # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_. - # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric - # functions, but this boils down to the same: Their x_i corresponds to the i-th power - # sum symmetric function.) - def arith_prod_sf(x, y): - ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2)) - return p._apply_multi_module_morphism(x, y, ap_sf_wrapper) - - # Sage stores cycle index series by degree. - # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful - # to compute all terms of a given degree `n` at once. - def arith_prod_coeff(n): - if n == 0: - res = p.zero() - else: - index_set = ((d, n // d) for d in divisors(n)) - res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set) - - # Build a list which has res in the `n`th slot and 0's before and after - # to feed to sum_generator - res_in_seq = [p.zero()]*n + [res, p.zero()] - - return self.parent(res_in_seq) - - # Finally, we use the sum_generator method to assemble these results into a single - # LazyPowerSeries object. - return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) - - def _cycle_type(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] - sage: cis = species.PermutationSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1]] - sage: cis = species.SetSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[1], [1], [1]] - """ - if s == []: - return self._card(0) - res = [] - for k in range(1, self._upper_bound_for_longest_cycle(s)+1): - e = 0 - for d in divisors(k): - m = moebius(d) - if m == 0: - continue - u = s.power(k/d) - e += m*self.count(u) - res.extend([k]*int(e/k)) - res.reverse() - return Partition(res) - - - def _upper_bound_for_longest_cycle(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._upper_bound_for_longest_cycle([4]) - 4 - sage: cis._upper_bound_for_longest_cycle([3,1]) - 3 - sage: cis._upper_bound_for_longest_cycle([2,2]) - 2 - sage: cis._upper_bound_for_longest_cycle([2,1,1]) - 2 - sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) - 1 - """ - if s == []: - return 1 - return min(self._card(sum(s)), lcm(list(s))) - - def _card(self, n): - r""" - Return the number of structures on an underlying set of size ``n`` for - the species associated with ``self``. - - This is just ``n!`` times the coefficient of ``p[1]n`` in ``self``. - - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._card(4) - 15 - """ - p = self.coefficient(n) - return factorial(n) * p.coefficient([1] * n) - - def _compose_gen(self, y, ao): - """ - Return a generator for the coefficients of the composition of this - cycle index series and the cycle index series ``y``. This overrides - the method defined in ``LazyPowerSeries``. - - The notion "composition" means plethystic substitution here, as - defined in Section 2.2 of [BLL-Intro]_. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._compose_gen(C.cycle_index_series(),0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - assert y.coefficient(0) == 0 - y_powers = Stream(y._power_gen()) - - parent = self.parent() - res = parent.sum_generator(self._compose_term(self.coefficient(i), y_powers) - for i in _integers_from(0)) - - for i in _integers_from(0): - yield res.coefficient(i) - - def _compose_term(self, p, y_powers): - r""" - Return the composition of one term in ``self`` with `y`. - - INPUT: - - - ``p`` - a term in ``self`` - - ``y_powers`` - a stream for the powers of `y` - starting with `y` - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: C_cis = C.cycle_index_series() - sage: c_powers = Stream(C_cis._power_gen()) - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._compose_term(p2, c_powers).coefficients(4) - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - parent = self.parent() - if p == 0: - return parent(0) - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent.term(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * y_powers[v-1].stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def weighted_composition(self, y_species): - r""" - Return the composition of this cycle index series with the cycle - index series of the weighted species ``y_species``. - - Note that this is basically the same algorithm as composition - except we can not use the optimization that the powering of cycle - index series commutes with 'stretching'. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: E_cis.weighted_composition(C).coefficients(4) - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - sage: E(C).cycle_index_series().coefficients(4) - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - base_ring = self.base_ring() - y = y_species.cycle_index_series(base_ring) - assert y.coefficient(0) == 0 - return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) - - - def _weighted_compose_gen(self, y_species, ao): - r""" - Return an iterator for the composition of this cycle index series - and the cycle index series of the weighted species ``y_species``. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._weighted_compose_gen(C,0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - parent = self.parent() - res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) - for i in _integers_from(0)) - - for i in _integers_from(0): - yield res.coefficient(i) - - def _weighted_compose_term(self, p, y_species): - r""" - Return the weighted composition of one term in ``self`` with ``y``. - - INPUT: - - - ``p`` -- a term in ``self`` - - ``y_species`` -- a species - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._weighted_compose_term(p2, C).coefficients(4) - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - parent = self.parent() - if p == 0: - return parent(0) - - base_ring = self.base_ring().base_ring() - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent.term(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * (y_species.weighted(y_species._weight**(e+1)).cycle_index_series(base_ring)**v).stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def compositional_inverse(self): - r""" - Return the compositional inverse of ``self`` if possible. - - (Specifically, if ``self`` is of the form `0 + p_{1} + \cdots`.) - - The compositional inverse is the inverse with respect to - plethystic substitution. This is the operation on cycle index - series which corresponds to substitution, a.k.a. partitional - composition, on the level of species. See Section 2.2 of - [BLL]_ for a definition of this operation. - - EXAMPLES:: - - sage: Eplus = species.SetSpecies(min=1).cycle_index_series() - sage: Eplus(Eplus.compositional_inverse()).coefficients(8) - [0, p[1], 0, 0, 0, 0, 0, 0] - - TESTS:: - - sage: Eplus = species.SetSpecies(min=2).cycle_index_series() - sage: Eplus.compositional_inverse() - Traceback (most recent call last): - ... - ValueError: not an invertible series - - ALGORITHM: - - Let `F` be a species satisfying `F = 0 + X + F_2 + F_3 + \cdots` for - `X` the species of singletons. (Equivalently, `\lvert F[\varnothing] - \rvert = 0` and `\lvert F[\{1\}] \rvert = 1`.) Then there exists a - (virtual) species `G` satisfying `F \circ G = G \circ F = X`. - - It follows that `(F - X) \circ G = F \circ G - X \circ G = X - G`. - Rearranging, we obtain the recursive equation `G = X - (F - X) \circ G`, - which can be solved using iterative methods. - - .. WARNING:: - - This algorithm is functional but can be very slow. - Use with caution! - - .. SEEALSO:: - - The compositional inverse `\Omega` of the species `E_{+}` - of nonempty sets can be handled much more efficiently - using specialized methods. See - :func:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries` - - AUTHORS: - - - Andrew Gainer-Dewar - """ - cisr = self.parent() - sfa = cisr._base - - X = cisr([0, sfa([1]), 0]) - - if self.coefficients(2) != X.coefficients(2): - raise ValueError('not an invertible series') - - res = cisr() - res.define(X - (self - X).compose(res)) - - return res - - def derivative(self, order=1): - r""" - Return the species-theoretic `n`-th derivative of ``self``, - where `n` is ``order``. - - For a cycle index series `F (p_{1}, p_{2}, p_{3}, \ldots)`, its - derivative is the cycle index series `F' = D_{p_{1}} F` (that is, - the formal derivative of `F` with respect to the variable `p_{1}`). - - If `F` is the cycle index series of a species `S` then `F'` is the - cycle index series of an associated species `S'` of `S`-structures - with a "hole". - - EXAMPLES: - - The species `E` of sets satisfies the relationship `E' = E`:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: E.coefficients(8) == E.derivative().coefficients(8) - True - - The species `C` of cyclic orderings and the species `L` of linear - orderings satisfy the relationship `C' = L`:: - - sage: C = species.CycleSpecies().cycle_index_series() - sage: L = species.LinearOrderSpecies().cycle_index_series() - sage: L.coefficients(8) == C.derivative().coefficients(8) - True - """ - # Make sure that order is integral - order = Integer(order) - - if order < 0: - raise ValueError("Order must be a non-negative integer") - - elif order == 0: - return self - - elif order == 1: - parent = self.parent() - derivative_term = lambda n: parent.term(self.coefficient(n+1).derivative_with_respect_to_p1(), n) - return parent.sum_generator(derivative_term(i) for i in _integers_from(0)) - - else: - return self.derivative(order-1) - - def pointing(self): - r""" - Return the species-theoretic pointing of ``self``. - - For a cycle index `F`, its pointing is the cycle index series - `F^{\bullet} = p_{1} \cdot F'`. - - If `F` is the cycle index series of a species `S` then `F^{\bullet}` - is the cycle index series of an associated species `S^{\bullet}` - of `S`-structures with a marked "root". - - EXAMPLES: - - The species `E^{\bullet}` of "pointed sets" satisfies - `E^{\bullet} = X \cdot E`:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: E.pointing().coefficients(8) == (X*E).coefficients(8) - True - - """ - p1 = self.base_ring()([1]) - X = self.parent()([0, p1, 0]) - - return X*self.derivative() - - def integral(self, *args): - r""" - Given a cycle index `G`, it is not in general possible to recover a - single cycle index `F` such that `F' = G` (even up to addition of a - constant term). - - More broadly, it may be the case that there are many non-isomorphic - species `S` such that `S' = T` for a given species `T`. - For example, the species `3 C_{3}` of 3-cycles from three distinct - classes and the species `X^{3}` of 3-sets are not isomorphic, but - `(3 C_{3})' = (X^{3})' = 3 X^{2}`. - - EXAMPLES:: - - sage: C3 = species.CycleSpecies(size=3).cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: (3*C3).derivative().coefficients(8) == (3*X^2).coefficients(8) - True - sage: (X^3).derivative().coefficients(8) == (3*X^2).coefficients(8) - True - - .. WARNING:: - - This method has no implementation and exists only to prevent you from - doing something strange. Calling it raises a ``NotImplementedError``! - """ - raise NotImplementedError - - def exponential(self): - r""" - Return the species-theoretic exponential of ``self``. - - For a cycle index `Z_{F}` of a species `F`, its exponential is the - cycle index series `Z_{E} \circ Z_{F}`, where `Z_{E}` is the - :meth:`~sage.combinat.species.generating_series.ExponentialCycleIndexSeries`. - - The exponential `Z_{E} \circ Z_{F}` is then the cycle index series - of the species `E \circ F` of "sets of `F`-structures". - - EXAMPLES: - - Let `BT` be the species of binary trees, `BF` the species of binary - forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: - - sage: BT = species.BinaryTreeSpecies().cycle_index_series() - sage: BF = species.BinaryForestSpecies().cycle_index_series() - sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) - True - """ - base_ring = self.parent().base_ring().base_ring() - E = ExponentialCycleIndexSeries(base_ring) - return E.compose(self) - - def logarithm(self): - r""" - Return the combinatorial logarithm of ``self``. - - For a cycle index `Z_{F}` of a species `F`, its logarithm is the - cycle index series `Z_{\Omega} \circ Z_{F}`, where `Z_{\Omega}` is the - :meth:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries`. - - The logarithm `Z_{\Omega} \circ Z_{F}` is then the cycle index series - of the (virtual) species `\Omega \circ F` of "connected `F`-structures". - In particular, if `F = E^{+} \circ G` for `E^{+}` the species of - nonempty sets and `G` some other species, then `\Omega \circ F = G`. - - EXAMPLES: - - Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected - graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: - - sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 - sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: CG = LogarithmCycleIndexSeries().compose(G) - sage: CG.isotype_generating_series().coefficients(8) - [0, 1, 1, 2, 6, 21, 112, 853] - """ - base_ring = self.parent().base_ring().base_ring() - Omega = LogarithmCycleIndexSeries(base_ring) - return Omega.compose(self) - -@cached_function -def _exp_term(n, R = RationalField()): - """ - Compute the order-n term of the cycle index series of the species `E` of sets. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import _exp_term - sage: [_exp_term(i) for i in range(4)] - [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] - """ - p = SymmetricFunctions(R).power() - return sum(p(part) / part.aut() for part in Partitions(n)) - - -def _exp_gen(R = RationalField()): - r""" - Produce a generator which yields the terms of the cycle index - series of the species `E` of sets. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import _exp_gen - sage: g = _exp_gen() - sage: [next(g) for i in range(4)] - [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] - """ - return (_exp_term(i, R) for i in _integers_from(0)) - -@cached_function -def ExponentialCycleIndexSeries(R = RationalField()): - r""" - Return the cycle index series of the species `E` of sets. - - This cycle index satisfies - - .. MATH:: - - Z_{E} = \sum_{n \geq 0} \sum_{\lambda \vdash n} - \frac{p_{\lambda}}{z_{\lambda}}. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries - sage: ExponentialCycleIndexSeries().coefficients(5) - [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] - + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] - + 1/3*p[3, 1] + 1/4*p[4]] - """ - CIS = CycleIndexSeriesRing(R) - return CIS(_exp_gen(R)) - - -@cached_function -def _cl_term(n, R = RationalField()): - r""" - Compute the order-n term of the cycle index series of the virtual species - `\Omega`, the compositional inverse of the species `E^{+}` of nonempty sets. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import _cl_term - sage: [_cl_term(i) for i in range(4)] - [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] - """ - n = Integer(n) # check that n is an integer - - p = SymmetricFunctions(R).power() - - res = p.zero() - if n == 1: - res = p([1]) - elif n > 1: - res = 1/n * ((-1)**(n-1) * p([1])**n - sum(d * p([n // d]).plethysm(_cl_term(d, R)) for d in divisors(n)[:-1])) - - return res - - -def _cl_gen (R = RationalField()): - r""" - Produce a generator which yields the terms of the cycle index series - of the virtual species `\Omega`, the compositional inverse of the - species `E^{+}` of nonempty sets. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import _cl_gen - sage: g = _cl_gen() - sage: [next(g) for i in range(4)] - [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] - """ - return (_cl_term(i, R) for i in _integers_from(0)) - - -@cached_function -def LogarithmCycleIndexSeries(R = RationalField()): - r""" - Return the cycle index series of the virtual species `\Omega`, the - compositional inverse of the species `E^{+}` of nonempty sets. - - The notion of virtual species is treated thoroughly in [BLL]_. - The specific algorithm used here to compute the cycle index of - `\Omega` is found in [Labelle2008]_. - - EXAMPLES: - - The virtual species `\Omega` is 'properly virtual', in the sense that - its cycle index has negative coefficients:: - - sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: LogarithmCycleIndexSeries().coefficients(4) - [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] - - Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` - (that is, that composition with `E^{+}` in both directions yields the - multiplicative identity `X`):: - - sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries().compose(Eplus).coefficients(4) - [0, p[1], 0, 0] - """ - CIS = CycleIndexSeriesRing(R) - return CIS(_cl_gen(R)) - + n += 1 \ No newline at end of file From 24ce1d98cc827b416bb6e929c1bd98618077d0df Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Thu, 12 Aug 2021 00:24:54 +0530 Subject: [PATCH 012/350] Started Cyclic Series. --- .../combinat/species/new_generating_series.py | 890 +++++++++++++++++- 1 file changed, 884 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/species/new_generating_series.py b/src/sage/combinat/species/new_generating_series.py index 2c271aa6d6e..fd00d617ebf 100644 --- a/src/sage/combinat/species/new_generating_series.py +++ b/src/sage/combinat/species/new_generating_series.py @@ -68,8 +68,7 @@ def __init__(self, R): True """ - LazyTaylorSeriesRing.Element = OrdinaryGeneratingSeries - LazyTaylorSeriesRing.__init__(self, R, 'z') + Element = OrdinaryGeneratingSeries class OrdinaryGeneratingSeries(LazyTaylorSeries): @@ -128,9 +127,7 @@ def __init__(self, R): True """ - LazyTaylorSeriesRing.Element = ExponentialGeneratingSeries - LazyTaylorSeriesRing.__init__(self, R, 'z') - + Element = ExponentialGeneratingSeries class ExponentialGeneratingSeries(LazyTaylorSeries): def count(self, n): @@ -208,4 +205,885 @@ def _functorial_compose_gen(self, y, ao): n = 0 while True: yield self.count(y.count(n)) / factorial(n) - n += 1 \ No newline at end of file + n += 1 + + +class CycleIndexSeriesRing(LazyTaylorSeriesRing): + def __init__(self, R): + """ + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: R = CycleIndexSeriesRing(QQ); R + Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis + sage: R == loads(dumps(R)) + True + + """ + R = SymmetricFunctions(R).power() + LazyTaylorSeriesRing.Element = CycleIndexSeries + LazyTaylorSeriesRing.__init__(self, R, 'z') + + def __repr__(self): + """ + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: CycleIndexSeriesRing(QQ) + Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis + """ + return "Cycle Index Series Ring over %s"%self.base_ring() + + +class CycleIndexSeries(LazyTaylorSeries): + def count(self, t): + """ + Return the number of structures corresponding to a certain cycle + type ``t``. + + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) + sage: f.count([1]) + 1 + sage: f.count([1,1]) + 4 + sage: f.count([2,1]) + 6 + """ + t = Partition(t) + return t.aut() * self.coefficient_cycle_type(t) + + def coefficient_cycle_type(self, t): + """ + Returns the coefficient of a cycle type ``t`` in ``self``. + + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) + sage: f.coefficient_cycle_type([1]) + 1 + sage: f.coefficient_cycle_type([1,1]) + 2 + sage: f.coefficient_cycle_type([2,1]) + 3 + """ + t = Partition(t) + p = self.coefficient(t.size()) + return p.coefficient(t) + + def stretch(self, k): + r""" + Return the stretch of the cycle index series ``self`` by a positive + integer `k`. + + If + + .. MATH:: + + f = \sum_{n=0}^{\infty} f_n(p_1, p_2, p_3, \ldots ), + + then the stretch `g` of `f` by `k` is + + .. MATH:: + + g = \sum_{n=0}^{\infty} f_n(p_k, p_{2k}, p_{3k}, \ldots ). + + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) + sage: f.stretch(3).coefficients(10) + [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] + """ + return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) + + def _stretch_gen(self, k, ao): + """ + EXAMPLES:: + + sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing + sage: p = SymmetricFunctions(QQ).power() + sage: CIS = CycleIndexSeriesRing(QQ) + sage: f = CIS([p([1])]) # This is the power series whose all coefficients + ....: # are p[1]. Not combinatorially meaningful! + sage: g = f._stretch_gen(2,0) + sage: [next(g) for i in range(10)] + [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] + """ + BR = self.base_ring() + zero = BR.zero() + + stretch_k = lambda p: Partition([k*i for i in p]) + + yield self.coefficient(0).map_support(stretch_k) + + n = 1 + while True: + for i in range(k-1): + yield zero + yield self.coefficient(n).map_support(stretch_k) + n += 1 + + def isotype_generating_series(self): + """ + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: f = cis.isotype_generating_series() + sage: f.coefficients(10) + [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] + """ + R = self.base_ring().base_ring() + OGS = OrdinaryGeneratingSeriesRing(R)() + return OGS._new(self._ogs_gen, lambda ao: ao, self) + + def expand_as_sf(self, n, alphabet='x'): + """ + Returns the expansion of a cycle index series as a symmetric function in + ``n`` variables. + + Specifically, this returns a :class:`~sage.combinat.species.series.LazyPowerSeries` whose + ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` + on the ith term of ``self``. + + This relies on the (standard) interpretation of a cycle index series as a symmetric function + in the power sum basis. + + INPUT: + + - ``self`` -- a cycle index series + + - ``n`` -- a positive integer + + - ``alphabet`` -- a variable for the expansion (default: `x`) + + EXAMPLES:: + + sage: from sage.combinat.species.set_species import SetSpecies + sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4) + [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] + + """ + expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() + LPSR = LazyPowerSeriesRing(expanded_poly_ring) + + expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) + + return LPSR.sum_generator(expander_gen) + + def _ogs_gen(self, ao): + """ + Returns a generator for the coefficients of the ordinary generating + series obtained from a cycle index series. + + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: g = cis._ogs_gen(0) + sage: [next(g) for i in range(10)] + [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] + """ + for i in range(ao): + yield 0 + for i in _integers_from(ao): + yield sum( self.coefficient(i).coefficients() ) + + def generating_series(self): + """ + EXAMPLES:: + + sage: P = species.PartitionSpecies() + sage: cis = P.cycle_index_series() + sage: f = cis.generating_series() + sage: f.coefficients(5) + [1, 1, 1, 5/6, 5/8] + """ + R = self.base_ring().base_ring() + EGS = ExponentialGeneratingSeriesRing(R)() + return EGS._new(self._egs_gen, lambda ao: ao, self) + + def _egs_gen(self, ao): + """ + Returns a generator for the coefficients of the exponential + generating series obtained from a cycle index series. + + EXAMPLES:: + + sage: P = species.PermutationSpecies() + sage: cis = P.cycle_index_series() + sage: g = cis._egs_gen(0) + sage: [next(g) for i in range(10)] + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + """ + for i in range(ao): + yield 0 + for i in _integers_from(ao): + yield self.coefficient(i).coefficient([1]*i) + + def __invert__(self): + r""" + Return the multiplicative inverse of ``self``. + + This algorithm is derived from [BLL]_. + + EXAMPLES:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: E.__invert__().coefficients(4) + [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] + + The defining characteristic of the multiplicative inverse `F^{-1}` of + a cycle index series `F` is that `F \cdot F^{-1} = F^{-1} \cdot F = 1` + (that is, both products with `F` yield the multiplicative identity `1`):: + + sage: E = species.SetSpecies().cycle_index_series() + sage: (E * ~E).coefficients(6) + [p[], 0, 0, 0, 0, 0] + + REFERENCES: + + - [BLL]_ + - [BLL-Intro]_ + - http://bergeron.math.uqam.ca/Site/bergeron_anglais_files/livre_combinatoire.pdf + + AUTHORS: + + - Andrew Gainer-Dewar + """ + if self.coefficient(0) == 0: + raise ValueError("constant term must be non-zero") + + def multinv_builder(i): + return self.coefficient(0)**(-i-1) * (self.coefficient(0) + (-1)*self)**i + + return self.parent().sum_generator(multinv_builder(i) for i in _integers_from(0)) + + def _div_(self, y): + """ + TESTS:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: (E / E).coefficients(6) + [p[], 0, 0, 0, 0, 0] + """ + return self*(~y) + + def functorial_composition(self, g): + r""" + Returns the functorial composition of ``self`` and ``g``. + + If `F` and `G` are species, their functorial composition is the species + `F \Box G` obtained by setting `(F \Box G) [A] = F[ G[A] ]`. + In other words, an `(F \Box G)`-structure on a set `A` of labels is an + `F`-structure whose labels are the set of all `G`-structures on `A`. + + It can be shown (as in section 2.2 of [BLL]_) that there is a + corresponding operation on cycle indices: + + .. MATH:: + + Z_{F} \Box Z_{G} = \sum_{n \geq 0} \frac{1}{n!} + \sum_{\sigma \in \mathfrak{S}_{n}} + \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] + \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots. + + This method implements that operation on cycle index series. + + EXAMPLES: + + The species `G` of simple graphs can be expressed in terms of a functorial + composition: `G = \mathfrak{p} \Box \mathfrak{p}_{2}`, where + `\mathfrak{p}` is the :class:`~sage.combinat.species.subset_species.SubsetSpecies`. + This is how it is implemented in + :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: + + sage: S = species.SimpleGraphSpecies() + sage: S.cycle_index_series().coefficients(5) + [p[], + p[1], + p[1, 1] + p[2], + 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], + 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] + """ + return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) + + def _functorial_compose_gen(self, g, ao): + """ + Return a generator for the coefficients of the functorial + composition of ``self`` with ``g``. + + EXAMPLES:: + + sage: E = species.SetSpecies() + sage: E2 = species.SetSpecies(size=2) + sage: WP = species.SubsetSpecies() + sage: P2 = E2*E + sage: P2_cis = P2.cycle_index_series() + sage: WP_cis = WP.cycle_index_series() + sage: g = WP_cis._functorial_compose_gen(P2_cis,0) + sage: [next(g) for i in range(5)] + [p[], + p[1], + p[1, 1] + p[2], + 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], + 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] + """ + p = self.parent().base_ring() + n = 0 + while True: + res = p(0) + for s in Partitions(n): + t = g._cycle_type(s) + q = self.count(t) / s.aut() + res += q*p(s) + yield res + n += 1 + + def arithmetic_product(self, g, check_input = True): + r""" + Return the arithmetic product of ``self`` with ``g``. + + For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`, + their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures". + This operation is defined and several examples are given in [MM]_. + + The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`, + as implemented in this method. + + INPUT: + + - ``g`` -- a cycle index series having the same parent as ``self``. + + - ``check_input`` -- (default: ``True``) a Boolean which, when set + to ``False``, will cause input checks to be skipped. + + OUTPUT: + + The arithmetic product of ``self`` with ``g``. This is a cycle + index series defined in terms of ``self`` and ``g`` such that + if ``self`` and ``g`` are the cycle index series of two species + `M` and `N`, their arithmetic product is the cycle index series + of the species `M \\boxdot N`. + + EXAMPLES: + + For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds + to the species of "regular octopuses"; a `(C \\boxdot L_{+})`-structure is a cycle of some length, each of whose elements + is an ordered list of a length which is consistent for all the lists in the structure. :: + + sage: C = species.CycleSpecies().cycle_index_series() + sage: Lplus = species.LinearOrderSpecies(min=1).cycle_index_series() + sage: RegularOctopuses = C.arithmetic_product(Lplus) + sage: RegOctSpeciesSeq = RegularOctopuses.generating_series().counts(8) + sage: RegOctSpeciesSeq + [0, 1, 3, 8, 42, 144, 1440, 5760] + + It is shown in [MM]_ that the exponential generating function for regular octopuses satisfies + `(C \\boxdot L_{+}) (x) = \\sum_{n \geq 1} \\sigma (n) (n - 1)! \\frac{x^{n}}{n!}` (where `\\sigma (n)` is + the sum of the divisors of `n`). :: + + sage: RegOctDirectSeq = [0] + [sum(divisors(i))*factorial(i-1) for i in range(1,8)] + sage: RegOctDirectSeq == RegOctSpeciesSeq + True + + AUTHORS: + + - Andrew Gainer-Dewar (2013) + + REFERENCES: + + .. [MM] \M. Maia and M. Mendez. "On the arithmetic product of combinatorial species". + Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427. + :arxiv:`math/0503436v2`. + + """ + from itertools import product, repeat, chain + + p = self.base_ring() + + if check_input: + assert self.coefficient(0) == p.zero() + assert g.coefficient(0) == p.zero() + + # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_. + def arith_prod_of_partitions(l1, l2): + # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by + # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes + # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2` + # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a + # partition of `nm`. + term_iterable = chain.from_iterable(repeat(lcm(pair), gcd(pair)) + for pair in product(l1, l2)) + return Partition(sorted(term_iterable, reverse=True)) + + # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_. + # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric + # functions, but this boils down to the same: Their x_i corresponds to the i-th power + # sum symmetric function.) + def arith_prod_sf(x, y): + ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2)) + return p._apply_multi_module_morphism(x, y, ap_sf_wrapper) + + # Sage stores cycle index series by degree. + # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful + # to compute all terms of a given degree `n` at once. + def arith_prod_coeff(n): + if n == 0: + res = p.zero() + else: + index_set = ((d, n // d) for d in divisors(n)) + res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set) + + # Build a list which has res in the `n`th slot and 0's before and after + # to feed to sum_generator + res_in_seq = [p.zero()]*n + [res, p.zero()] + + return self.parent(res_in_seq) + + # Finally, we use the sum_generator method to assemble these results into a single + # LazyPowerSeries object. + return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) + + def _cycle_type(self, s): + """ + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[3, 1, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] + sage: cis = species.PermutationSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[3, 1, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1]] + sage: cis = species.SetSpecies().cycle_index_series() + sage: [cis._cycle_type(p) for p in Partitions(3)] + [[1], [1], [1]] + """ + if s == []: + return self._card(0) + res = [] + for k in range(1, self._upper_bound_for_longest_cycle(s)+1): + e = 0 + for d in divisors(k): + m = moebius(d) + if m == 0: + continue + u = s.power(k/d) + e += m*self.count(u) + res.extend([k]*int(e/k)) + res.reverse() + return Partition(res) + + + def _upper_bound_for_longest_cycle(self, s): + """ + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: cis._upper_bound_for_longest_cycle([4]) + 4 + sage: cis._upper_bound_for_longest_cycle([3,1]) + 3 + sage: cis._upper_bound_for_longest_cycle([2,2]) + 2 + sage: cis._upper_bound_for_longest_cycle([2,1,1]) + 2 + sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) + 1 + """ + if s == []: + return 1 + return min(self._card(sum(s)), lcm(list(s))) + + def _card(self, n): + r""" + Return the number of structures on an underlying set of size ``n`` for + the species associated with ``self``. + + This is just ``n!`` times the coefficient of ``p[1]n`` in ``self``. + + EXAMPLES:: + + sage: cis = species.PartitionSpecies().cycle_index_series() + sage: cis._card(4) + 15 + """ + p = self.coefficient(n) + return factorial(n) * p.coefficient([1] * n) + + def _compose_gen(self, y, ao): + """ + Return a generator for the coefficients of the composition of this + cycle index series and the cycle index series ``y``. This overrides + the method defined in ``LazyPowerSeries``. + + The notion "composition" means plethystic substitution here, as + defined in Section 2.2 of [BLL-Intro]_. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: g = E_cis._compose_gen(C.cycle_index_series(),0) + sage: [next(g) for i in range(4)] + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + assert y.coefficient(0) == 0 + y_powers = Stream(y._power_gen()) + + parent = self.parent() + res = parent.sum_generator(self._compose_term(self.coefficient(i), y_powers) + for i in _integers_from(0)) + + for i in _integers_from(0): + yield res.coefficient(i) + + def _compose_term(self, p, y_powers): + r""" + Return the composition of one term in ``self`` with `y`. + + INPUT: + + - ``p`` - a term in ``self`` + - ``y_powers`` - a stream for the powers of `y` + starting with `y` + + EXAMPLES:: + + sage: from sage.combinat.species.stream import Stream + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: C_cis = C.cycle_index_series() + sage: c_powers = Stream(C_cis._power_gen()) + sage: p2 = E_cis.coefficient(2); p2 + 1/2*p[1, 1] + 1/2*p[2] + sage: E_cis._compose_term(p2, c_powers).coefficients(4) + [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] + """ + parent = self.parent() + if p == 0: + return parent(0) + + res = [] + #Go through all the partition, coefficient pairs in the term p + for m, c in p: + res_t = parent.term(c, 0) + + for e,v in enumerate(m.to_exp()): + if v == 0: + continue + res_t = res_t * y_powers[v-1].stretch(e+1) + res.append(res_t) + + return parent.sum(res) + + def weighted_composition(self, y_species): + r""" + Return the composition of this cycle index series with the cycle + index series of the weighted species ``y_species``. + + Note that this is basically the same algorithm as composition + except we can not use the optimization that the powering of cycle + index series commutes with 'stretching'. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: E_cis.weighted_composition(C).coefficients(4) + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + sage: E(C).cycle_index_series().coefficients(4) + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + base_ring = self.base_ring() + y = y_species.cycle_index_series(base_ring) + assert y.coefficient(0) == 0 + return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) + + + def _weighted_compose_gen(self, y_species, ao): + r""" + Return an iterator for the composition of this cycle index series + and the cycle index series of the weighted species ``y_species``. + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: g = E_cis._weighted_compose_gen(C,0) + sage: [next(g) for i in range(4)] + [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] + """ + parent = self.parent() + res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) + for i in _integers_from(0)) + + for i in _integers_from(0): + yield res.coefficient(i) + + def _weighted_compose_term(self, p, y_species): + r""" + Return the weighted composition of one term in ``self`` with ``y``. + + INPUT: + + - ``p`` -- a term in ``self`` + - ``y_species`` -- a species + + EXAMPLES:: + + sage: E = species.SetSpecies(); C = species.CycleSpecies() + sage: E_cis = E.cycle_index_series() + sage: p2 = E_cis.coefficient(2); p2 + 1/2*p[1, 1] + 1/2*p[2] + sage: E_cis._weighted_compose_term(p2, C).coefficients(4) + [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] + """ + parent = self.parent() + if p == 0: + return parent(0) + + base_ring = self.base_ring().base_ring() + + res = [] + #Go through all the partition, coefficient pairs in the term p + for m, c in p: + res_t = parent.term(c, 0) + + for e,v in enumerate(m.to_exp()): + if v == 0: + continue + res_t = res_t * (y_species.weighted(y_species._weight**(e+1)).cycle_index_series(base_ring)**v).stretch(e+1) + res.append(res_t) + + return parent.sum(res) + + def compositional_inverse(self): + r""" + Return the compositional inverse of ``self`` if possible. + + (Specifically, if ``self`` is of the form `0 + p_{1} + \cdots`.) + + The compositional inverse is the inverse with respect to + plethystic substitution. This is the operation on cycle index + series which corresponds to substitution, a.k.a. partitional + composition, on the level of species. See Section 2.2 of + [BLL]_ for a definition of this operation. + + EXAMPLES:: + + sage: Eplus = species.SetSpecies(min=1).cycle_index_series() + sage: Eplus(Eplus.compositional_inverse()).coefficients(8) + [0, p[1], 0, 0, 0, 0, 0, 0] + + TESTS:: + + sage: Eplus = species.SetSpecies(min=2).cycle_index_series() + sage: Eplus.compositional_inverse() + Traceback (most recent call last): + ... + ValueError: not an invertible series + + ALGORITHM: + + Let `F` be a species satisfying `F = 0 + X + F_2 + F_3 + \cdots` for + `X` the species of singletons. (Equivalently, `\lvert F[\varnothing] + \rvert = 0` and `\lvert F[\{1\}] \rvert = 1`.) Then there exists a + (virtual) species `G` satisfying `F \circ G = G \circ F = X`. + + It follows that `(F - X) \circ G = F \circ G - X \circ G = X - G`. + Rearranging, we obtain the recursive equation `G = X - (F - X) \circ G`, + which can be solved using iterative methods. + + .. WARNING:: + + This algorithm is functional but can be very slow. + Use with caution! + + .. SEEALSO:: + + The compositional inverse `\Omega` of the species `E_{+}` + of nonempty sets can be handled much more efficiently + using specialized methods. See + :func:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries` + + AUTHORS: + + - Andrew Gainer-Dewar + """ + cisr = self.parent() + sfa = cisr._base + + X = cisr([0, sfa([1]), 0]) + + if self.coefficients(2) != X.coefficients(2): + raise ValueError('not an invertible series') + + res = cisr() + res.define(X - (self - X).compose(res)) + + return res + + def derivative(self, order=1): + r""" + Return the species-theoretic `n`-th derivative of ``self``, + where `n` is ``order``. + + For a cycle index series `F (p_{1}, p_{2}, p_{3}, \ldots)`, its + derivative is the cycle index series `F' = D_{p_{1}} F` (that is, + the formal derivative of `F` with respect to the variable `p_{1}`). + + If `F` is the cycle index series of a species `S` then `F'` is the + cycle index series of an associated species `S'` of `S`-structures + with a "hole". + + EXAMPLES: + + The species `E` of sets satisfies the relationship `E' = E`:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: E.coefficients(8) == E.derivative().coefficients(8) + True + + The species `C` of cyclic orderings and the species `L` of linear + orderings satisfy the relationship `C' = L`:: + + sage: C = species.CycleSpecies().cycle_index_series() + sage: L = species.LinearOrderSpecies().cycle_index_series() + sage: L.coefficients(8) == C.derivative().coefficients(8) + True + """ + # Make sure that order is integral + order = Integer(order) + + if order < 0: + raise ValueError("Order must be a non-negative integer") + + elif order == 0: + return self + + elif order == 1: + parent = self.parent() + derivative_term = lambda n: parent.term(self.coefficient(n+1).derivative_with_respect_to_p1(), n) + return parent.sum_generator(derivative_term(i) for i in _integers_from(0)) + + else: + return self.derivative(order-1) + + def pointing(self): + r""" + Return the species-theoretic pointing of ``self``. + + For a cycle index `F`, its pointing is the cycle index series + `F^{\bullet} = p_{1} \cdot F'`. + + If `F` is the cycle index series of a species `S` then `F^{\bullet}` + is the cycle index series of an associated species `S^{\bullet}` + of `S`-structures with a marked "root". + + EXAMPLES: + + The species `E^{\bullet}` of "pointed sets" satisfies + `E^{\bullet} = X \cdot E`:: + + sage: E = species.SetSpecies().cycle_index_series() + sage: X = species.SingletonSpecies().cycle_index_series() + sage: E.pointing().coefficients(8) == (X*E).coefficients(8) + True + + """ + p1 = self.base_ring()([1]) + X = self.parent()([0, p1, 0]) + + return X*self.derivative() + + def integral(self, *args): + r""" + Given a cycle index `G`, it is not in general possible to recover a + single cycle index `F` such that `F' = G` (even up to addition of a + constant term). + + More broadly, it may be the case that there are many non-isomorphic + species `S` such that `S' = T` for a given species `T`. + For example, the species `3 C_{3}` of 3-cycles from three distinct + classes and the species `X^{3}` of 3-sets are not isomorphic, but + `(3 C_{3})' = (X^{3})' = 3 X^{2}`. + + EXAMPLES:: + + sage: C3 = species.CycleSpecies(size=3).cycle_index_series() + sage: X = species.SingletonSpecies().cycle_index_series() + sage: (3*C3).derivative().coefficients(8) == (3*X^2).coefficients(8) + True + sage: (X^3).derivative().coefficients(8) == (3*X^2).coefficients(8) + True + + .. WARNING:: + + This method has no implementation and exists only to prevent you from + doing something strange. Calling it raises a ``NotImplementedError``! + """ + raise NotImplementedError + + def exponential(self): + r""" + Return the species-theoretic exponential of ``self``. + + For a cycle index `Z_{F}` of a species `F`, its exponential is the + cycle index series `Z_{E} \circ Z_{F}`, where `Z_{E}` is the + :meth:`~sage.combinat.species.generating_series.ExponentialCycleIndexSeries`. + + The exponential `Z_{E} \circ Z_{F}` is then the cycle index series + of the species `E \circ F` of "sets of `F`-structures". + + EXAMPLES: + + Let `BT` be the species of binary trees, `BF` the species of binary + forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: + + sage: BT = species.BinaryTreeSpecies().cycle_index_series() + sage: BF = species.BinaryForestSpecies().cycle_index_series() + sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) + True + """ + base_ring = self.parent().base_ring().base_ring() + E = ExponentialCycleIndexSeries(base_ring) + return E.compose(self) + + def logarithm(self): + r""" + Return the combinatorial logarithm of ``self``. + + For a cycle index `Z_{F}` of a species `F`, its logarithm is the + cycle index series `Z_{\Omega} \circ Z_{F}`, where `Z_{\Omega}` is the + :meth:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries`. + + The logarithm `Z_{\Omega} \circ Z_{F}` is then the cycle index series + of the (virtual) species `\Omega \circ F` of "connected `F`-structures". + In particular, if `F = E^{+} \circ G` for `E^{+}` the species of + nonempty sets and `G` some other species, then `\Omega \circ F = G`. + + EXAMPLES: + + Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected + graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: + + sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 + sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries + sage: CG = LogarithmCycleIndexSeries().compose(G) + sage: CG.isotype_generating_series().coefficients(8) + [0, 1, 1, 2, 6, 21, 112, 853] + """ + base_ring = self.parent().base_ring().base_ring() + Omega = LogarithmCycleIndexSeries(base_ring) + return Omega.compose(self) \ No newline at end of file From 0d56b0227713d7a6b26612593b311071a05782b8 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Thu, 12 Aug 2021 01:29:28 +0530 Subject: [PATCH 013/350] Merged new Taylor series and deleted new_gs.py --- .../combinat/species/generating_series.py | 93 +- .../combinat/species/new_generating_series.py | 1089 ----------------- 2 files changed, 44 insertions(+), 1138 deletions(-) delete mode 100644 src/sage/combinat/species/new_generating_series.py diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index f87d3c07613..2b94f5a1587 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -77,7 +77,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from .series import LazyPowerSeriesRing, LazyPowerSeries +from sage.rings.lazy_laurent_series import LazyTaylorSeries +from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing from .stream import Stream, _integers_from from sage.rings.all import Integer, RationalField from sage.arith.all import moebius, gcd, lcm, divisors @@ -88,23 +89,22 @@ from sage.functions.other import factorial -@cached_function -def OrdinaryGeneratingSeriesRing(R): - """ +class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): + r""" Return the ring of ordinary generating series over ``R``. Note that it is just a - :class:`LazyPowerSeriesRing` whose elements have + :class:`LazyTaylorSeriesRing` whose elements have some extra methods. EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ); R - Lazy Power Series Ring over Rational Field - sage: R([1]).coefficients(4) + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z'); R + Lazy Taylor Series Ring in z over Rational Field + sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] - sage: R([1]).counts(4) + sage: R(lambda n: 1).counts(4) [1, 1, 1, 1] TESTS: @@ -113,26 +113,24 @@ def OrdinaryGeneratingSeriesRing(R): :: - sage: R is OrdinaryGeneratingSeriesRing(QQ) + sage: R is OrdinaryGeneratingSeriesRing(QQ, 'z') True - """ - return OrdinaryGeneratingSeriesRing_class(R) - -class OrdinaryGeneratingSeriesRing_class(LazyPowerSeriesRing): - def __init__(self, R): + """ + def __init__(self, R, names): """ EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') sage: R == loads(dumps(R)) True """ - LazyPowerSeriesRing.__init__(self, R, element_class=OrdinaryGeneratingSeries) + LazyTaylorSeriesRing.Element = OrdinaryGeneratingSeries + LazyTaylorSeriesRing.__init__(self, R, names=names) -class OrdinaryGeneratingSeries(LazyPowerSeries): +class OrdinaryGeneratingSeries(LazyTaylorSeries): def count(self, n): """ Return the number of structures on a set of size ``n``. @@ -140,7 +138,7 @@ def count(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') sage: f = R(range(20)) sage: f.count(10) 10 @@ -155,7 +153,7 @@ def counts(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') sage: f = R(range(20)) sage: f.counts(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -163,23 +161,22 @@ def counts(self, n): return [self.count(i) for i in range(n)] -@cached_function -def ExponentialGeneratingSeriesRing(R): - """ +class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): + r""" Return the ring of exponential generating series over ``R``. Note that it is just a - :class:`LazyPowerSeriesRing` whose elements have + :class:`LazyTaylorSeriesRing` whose elements have some extra methods. EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ); R - Lazy Power Series Ring over Rational Field - sage: R([1]).coefficients(4) + sage: R = ExponentialGeneratingSeriesRing(QQ, 'z'); R + Lazy Taylor Series Ring in z over Rational Field + sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] - sage: R([1]).counts(4) + sage: R(lambda n: 1).counts(4) [1, 1, 2, 6] TESTS: @@ -188,25 +185,23 @@ def ExponentialGeneratingSeriesRing(R): :: - sage: R is ExponentialGeneratingSeriesRing(QQ) + sage: R is ExponentialGeneratingSeriesRing(QQ, 'z') True - """ - return ExponentialGeneratingSeriesRing_class(R) - -class ExponentialGeneratingSeriesRing_class(LazyPowerSeriesRing): - def __init__(self, R): + """ + def __init__(self, R, names): """ EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') sage: R == loads(dumps(R)) True """ - LazyPowerSeriesRing.__init__(self, R, element_class=ExponentialGeneratingSeries) + LazyTaylorSeriesRing.Element = ExponentialGeneratingSeries + LazyTaylorSeriesRing.__init__(self, R, names=names) -class ExponentialGeneratingSeries(LazyPowerSeries): +class ExponentialGeneratingSeries(LazyTaylorSeries): def count(self, n): """ Return the number of structures of size ``n``. @@ -214,8 +209,8 @@ def count(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: f = R([1]) + sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') + sage: f = R(lambda n: 1) sage: [f.count(i) for i in range(7)] [1, 1, 2, 6, 24, 120, 720] """ @@ -229,7 +224,7 @@ def counts(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') sage: f = R(range(20)) sage: f.counts(5) [0, 1, 4, 18, 96] @@ -336,7 +331,7 @@ def CycleIndexSeriesRing(R): difficult to implement in Sage, as it would be an element of a power series ring in infinitely many variables. - Note that it is just a :class:`LazyPowerSeriesRing` (whose base + Note that it is just a :class:`LazyTaylorSeriesRing` (whose base ring is `\Lambda`) whose elements have some extra methods. EXAMPLES:: @@ -357,10 +352,10 @@ def CycleIndexSeriesRing(R): sage: R is CycleIndexSeriesRing(QQ) True """ - return CycleIndexSeriesRing_class(R) + return CycleIndexSeriesRing(R) -class CycleIndexSeriesRing_class(LazyPowerSeriesRing): +class CycleIndexSeriesRing(LazyTaylorSeriesRing): def __init__(self, R): """ EXAMPLES:: @@ -372,7 +367,7 @@ def __init__(self, R): True """ R = SymmetricFunctions(R).power() - LazyPowerSeriesRing.__init__(self, R, element_class=CycleIndexSeries) + LazyTaylorSeriesRing.__init__(self, R, element_class=CycleIndexSeries) def __repr__(self): """ @@ -385,7 +380,7 @@ def __repr__(self): return "Cycle Index Series Ring over %s"%self.base_ring() -class CycleIndexSeries(LazyPowerSeries): +class CycleIndexSeries(LazyTaylorSeries): def count(self, t): """ Return the number of structures corresponding to a certain cycle @@ -504,7 +499,7 @@ def expand_as_sf(self, n, alphabet='x'): Returns the expansion of a cycle index series as a symmetric function in ``n`` variables. - Specifically, this returns a :class:`~sage.combinat.species.series.LazyPowerSeries` whose + Specifically, this returns a :class:`~sage.combinat.species.series.LazyTaylorSeries` whose ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` on the ith term of ``self``. @@ -527,7 +522,7 @@ def expand_as_sf(self, n, alphabet='x'): """ expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() - LPSR = LazyPowerSeriesRing(expanded_poly_ring) + LPSR = LazyTaylorSeriesRing(expanded_poly_ring) expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) @@ -804,7 +799,7 @@ def arith_prod_coeff(n): return self.parent(res_in_seq) # Finally, we use the sum_generator method to assemble these results into a single - # LazyPowerSeries object. + # LazyTaylorSeries object. return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) def _cycle_type(self, s): @@ -877,7 +872,7 @@ def _compose_gen(self, y, ao): """ Return a generator for the coefficients of the composition of this cycle index series and the cycle index series ``y``. This overrides - the method defined in ``LazyPowerSeries``. + the method defined in ``LazyTaylorSeries``. The notion "composition" means plethystic substitution here, as defined in Section 2.2 of [BLL-Intro]_. diff --git a/src/sage/combinat/species/new_generating_series.py b/src/sage/combinat/species/new_generating_series.py deleted file mode 100644 index fd00d617ebf..00000000000 --- a/src/sage/combinat/species/new_generating_series.py +++ /dev/null @@ -1,1089 +0,0 @@ -r""" -Generating Series - -This file makes a number of extensions to lazy power series by -endowing them with some semantic content for how they're to be -interpreted. - -This code is based on the work of Ralf Hemmecke and Martin Rubey's -Aldor-Combinat, which can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html. -In particular, the relevant section for this file can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse10.html. -One notable difference is that we use power-sum symmetric functions -as the coefficients of our cycle index series. - -REFERENCES: - -.. [BLL] \F. Bergeron, G. Labelle, and P. Leroux. - "Combinatorial species and tree-like structures". - Encyclopedia of Mathematics and its Applications, vol. 67, Cambridge Univ. Press. 1998. -.. [BLL-Intro] Francois Bergeron, Gilbert Labelle, and Pierre Leroux. - "Introduction to the Theory of Species of Structures", March 14, 2008. -""" - -#***************************************************************************** -# Copyright (C) 2008 Mike Hansen -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - -from sage.rings.lazy_laurent_series import LazyTaylorSeries -from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing -from sage.rings.all import Integer, RationalField -from sage.arith.all import moebius, gcd, lcm, divisors -from sage.combinat.partition import Partition, Partitions -from functools import partial -from sage.combinat.sf.sf import SymmetricFunctions -from sage.misc.cachefunc import cached_function -from sage.functions.other import factorial - -class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): - def __init__(self, R): - """ - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) - sage: R = OrdinaryGeneratingSeriesRing(QQ); R - Lazy Taylor Series Ring in z over Rational Field - sage: [R(lambda n: 1)[i] for i in range(4)] - [1, 1, 1, 1] - sage: R(lambda n: 1).counts(4) - [1, 1, 1, 1] - sage: R == loads(dumps(R)) - True - - TESTS: - - We test to make sure that caching works. - - :: - - sage: R is OrdinaryGeneratingSeriesRing(QQ) - True - - """ - Element = OrdinaryGeneratingSeries - - -class OrdinaryGeneratingSeries(LazyTaylorSeries): - def count(self, n): - """ - Return the number of structures on a set of size ``n``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) - sage: f = R(range(20)) - sage: f.count(10) - 10 - """ - return self.coefficient(n) - - def counts(self, n): - """ - Return the number of structures on a set for size ``i`` for - each ``i`` in ``range(n)``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ) - sage: f = R(range(20)) - sage: f.counts(10) - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - """ - return [self.count(i) for i in range(n)] - - -class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): - def __init__(self, R): - """ - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ); R - Lazy Taylor Series Ring in z over Rational Field - sage: R == loads(dumps(R)) - True - sage: [R(lambda n: 1).coefficient(i) for i in range(4)] - [1, 1, 1, 1] - sage: R(lambda n: 1).counts(4) - [1, 1, 2, 6] - - TESTS: - - We test to make sure that caching works. - - :: - - sage: R is ExponentialGeneratingSeriesRing(QQ) - True - - """ - Element = ExponentialGeneratingSeries - -class ExponentialGeneratingSeries(LazyTaylorSeries): - def count(self, n): - """ - Return the number of structures of size ``n``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: f = R(lambda n: 1) - sage: [f.count(i) for i in range(7)] - [1, 1, 2, 6, 24, 120, 720] - """ - return factorial(n) * self.coefficient(n) - - def counts(self, n): - """ - Return the number of structures on a set for size ``i`` for - each ``i`` in ``range(n)``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: f = R(range(20)) - sage: f.counts(5) - [0, 1, 4, 18, 96] - """ - return [self.count(i) for i in range(n)] - - def functorial_composition(self, y): - r""" - Return the exponential generating series which is the functorial - composition of ``self`` with ``y``. - - If `f = \sum_{n=0}^{\infty} f_n \frac{x^n}{n!}` and - `g = \sum_{n=0}^{\infty} g_n \frac{x^n}{n!}`, then - functorial composition `f \Box g` is defined as - - .. MATH:: - - f \Box g = \sum_{n=0}^{\infty} f_{g_n} \frac{x^n}{n!} - - REFERENCES: - - - Section 2.2 of [BLL]_. - - EXAMPLES:: - - sage: G = species.SimpleGraphSpecies() - sage: g = G.generating_series() - sage: g.coefficients(10) - [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] - """ - return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) - - def _functorial_compose_gen(self, y, ao): - """ - Returns a generator for the coefficients of the functorial - composition of self with y. - - EXAMPLES:: - - sage: E = species.SetSpecies() - sage: E2 = E.restricted(min=2, max=3) - sage: WP = species.SubsetSpecies() - sage: P2 = E2*E - sage: g1 = WP.generating_series() - sage: g2 = P2.generating_series() - sage: g = g1._functorial_compose_gen(g2, 0) - sage: [next(g) for i in range(10)] - [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] - """ - n = 0 - while True: - yield self.count(y.count(n)) / factorial(n) - n += 1 - - -class CycleIndexSeriesRing(LazyTaylorSeriesRing): - def __init__(self, R): - """ - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - sage: R == loads(dumps(R)) - True - - """ - R = SymmetricFunctions(R).power() - LazyTaylorSeriesRing.Element = CycleIndexSeries - LazyTaylorSeriesRing.__init__(self, R, 'z') - - def __repr__(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ) - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - """ - return "Cycle Index Series Ring over %s"%self.base_ring() - - -class CycleIndexSeries(LazyTaylorSeries): - def count(self, t): - """ - Return the number of structures corresponding to a certain cycle - type ``t``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) - sage: f.count([1]) - 1 - sage: f.count([1,1]) - 4 - sage: f.count([2,1]) - 6 - """ - t = Partition(t) - return t.aut() * self.coefficient_cycle_type(t) - - def coefficient_cycle_type(self, t): - """ - Returns the coefficient of a cycle type ``t`` in ``self``. - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) - sage: f.coefficient_cycle_type([1]) - 1 - sage: f.coefficient_cycle_type([1,1]) - 2 - sage: f.coefficient_cycle_type([2,1]) - 3 - """ - t = Partition(t) - p = self.coefficient(t.size()) - return p.coefficient(t) - - def stretch(self, k): - r""" - Return the stretch of the cycle index series ``self`` by a positive - integer `k`. - - If - - .. MATH:: - - f = \sum_{n=0}^{\infty} f_n(p_1, p_2, p_3, \ldots ), - - then the stretch `g` of `f` by `k` is - - .. MATH:: - - g = \sum_{n=0}^{\infty} f_n(p_k, p_{2k}, p_{3k}, \ldots ). - - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) - sage: f.stretch(3).coefficients(10) - [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] - """ - return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) - - def _stretch_gen(self, k, ao): - """ - EXAMPLES:: - - sage: from sage.combinat.species.new_generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([p([1])]) # This is the power series whose all coefficients - ....: # are p[1]. Not combinatorially meaningful! - sage: g = f._stretch_gen(2,0) - sage: [next(g) for i in range(10)] - [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] - """ - BR = self.base_ring() - zero = BR.zero() - - stretch_k = lambda p: Partition([k*i for i in p]) - - yield self.coefficient(0).map_support(stretch_k) - - n = 1 - while True: - for i in range(k-1): - yield zero - yield self.coefficient(n).map_support(stretch_k) - n += 1 - - def isotype_generating_series(self): - """ - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.isotype_generating_series() - sage: f.coefficients(10) - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - """ - R = self.base_ring().base_ring() - OGS = OrdinaryGeneratingSeriesRing(R)() - return OGS._new(self._ogs_gen, lambda ao: ao, self) - - def expand_as_sf(self, n, alphabet='x'): - """ - Returns the expansion of a cycle index series as a symmetric function in - ``n`` variables. - - Specifically, this returns a :class:`~sage.combinat.species.series.LazyPowerSeries` whose - ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` - on the ith term of ``self``. - - This relies on the (standard) interpretation of a cycle index series as a symmetric function - in the power sum basis. - - INPUT: - - - ``self`` -- a cycle index series - - - ``n`` -- a positive integer - - - ``alphabet`` -- a variable for the expansion (default: `x`) - - EXAMPLES:: - - sage: from sage.combinat.species.set_species import SetSpecies - sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4) - [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] - - """ - expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() - LPSR = LazyPowerSeriesRing(expanded_poly_ring) - - expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) - - return LPSR.sum_generator(expander_gen) - - def _ogs_gen(self, ao): - """ - Returns a generator for the coefficients of the ordinary generating - series obtained from a cycle index series. - - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: g = cis._ogs_gen(0) - sage: [next(g) for i in range(10)] - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield sum( self.coefficient(i).coefficients() ) - - def generating_series(self): - """ - EXAMPLES:: - - sage: P = species.PartitionSpecies() - sage: cis = P.cycle_index_series() - sage: f = cis.generating_series() - sage: f.coefficients(5) - [1, 1, 1, 5/6, 5/8] - """ - R = self.base_ring().base_ring() - EGS = ExponentialGeneratingSeriesRing(R)() - return EGS._new(self._egs_gen, lambda ao: ao, self) - - def _egs_gen(self, ao): - """ - Returns a generator for the coefficients of the exponential - generating series obtained from a cycle index series. - - EXAMPLES:: - - sage: P = species.PermutationSpecies() - sage: cis = P.cycle_index_series() - sage: g = cis._egs_gen(0) - sage: [next(g) for i in range(10)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield self.coefficient(i).coefficient([1]*i) - - def __invert__(self): - r""" - Return the multiplicative inverse of ``self``. - - This algorithm is derived from [BLL]_. - - EXAMPLES:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: E.__invert__().coefficients(4) - [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] - - The defining characteristic of the multiplicative inverse `F^{-1}` of - a cycle index series `F` is that `F \cdot F^{-1} = F^{-1} \cdot F = 1` - (that is, both products with `F` yield the multiplicative identity `1`):: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E * ~E).coefficients(6) - [p[], 0, 0, 0, 0, 0] - - REFERENCES: - - - [BLL]_ - - [BLL-Intro]_ - - http://bergeron.math.uqam.ca/Site/bergeron_anglais_files/livre_combinatoire.pdf - - AUTHORS: - - - Andrew Gainer-Dewar - """ - if self.coefficient(0) == 0: - raise ValueError("constant term must be non-zero") - - def multinv_builder(i): - return self.coefficient(0)**(-i-1) * (self.coefficient(0) + (-1)*self)**i - - return self.parent().sum_generator(multinv_builder(i) for i in _integers_from(0)) - - def _div_(self, y): - """ - TESTS:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E / E).coefficients(6) - [p[], 0, 0, 0, 0, 0] - """ - return self*(~y) - - def functorial_composition(self, g): - r""" - Returns the functorial composition of ``self`` and ``g``. - - If `F` and `G` are species, their functorial composition is the species - `F \Box G` obtained by setting `(F \Box G) [A] = F[ G[A] ]`. - In other words, an `(F \Box G)`-structure on a set `A` of labels is an - `F`-structure whose labels are the set of all `G`-structures on `A`. - - It can be shown (as in section 2.2 of [BLL]_) that there is a - corresponding operation on cycle indices: - - .. MATH:: - - Z_{F} \Box Z_{G} = \sum_{n \geq 0} \frac{1}{n!} - \sum_{\sigma \in \mathfrak{S}_{n}} - \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] - \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots. - - This method implements that operation on cycle index series. - - EXAMPLES: - - The species `G` of simple graphs can be expressed in terms of a functorial - composition: `G = \mathfrak{p} \Box \mathfrak{p}_{2}`, where - `\mathfrak{p}` is the :class:`~sage.combinat.species.subset_species.SubsetSpecies`. - This is how it is implemented in - :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: - - sage: S = species.SimpleGraphSpecies() - sage: S.cycle_index_series().coefficients(5) - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) - - def _functorial_compose_gen(self, g, ao): - """ - Return a generator for the coefficients of the functorial - composition of ``self`` with ``g``. - - EXAMPLES:: - - sage: E = species.SetSpecies() - sage: E2 = species.SetSpecies(size=2) - sage: WP = species.SubsetSpecies() - sage: P2 = E2*E - sage: P2_cis = P2.cycle_index_series() - sage: WP_cis = WP.cycle_index_series() - sage: g = WP_cis._functorial_compose_gen(P2_cis,0) - sage: [next(g) for i in range(5)] - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - p = self.parent().base_ring() - n = 0 - while True: - res = p(0) - for s in Partitions(n): - t = g._cycle_type(s) - q = self.count(t) / s.aut() - res += q*p(s) - yield res - n += 1 - - def arithmetic_product(self, g, check_input = True): - r""" - Return the arithmetic product of ``self`` with ``g``. - - For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`, - their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures". - This operation is defined and several examples are given in [MM]_. - - The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`, - as implemented in this method. - - INPUT: - - - ``g`` -- a cycle index series having the same parent as ``self``. - - - ``check_input`` -- (default: ``True``) a Boolean which, when set - to ``False``, will cause input checks to be skipped. - - OUTPUT: - - The arithmetic product of ``self`` with ``g``. This is a cycle - index series defined in terms of ``self`` and ``g`` such that - if ``self`` and ``g`` are the cycle index series of two species - `M` and `N`, their arithmetic product is the cycle index series - of the species `M \\boxdot N`. - - EXAMPLES: - - For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds - to the species of "regular octopuses"; a `(C \\boxdot L_{+})`-structure is a cycle of some length, each of whose elements - is an ordered list of a length which is consistent for all the lists in the structure. :: - - sage: C = species.CycleSpecies().cycle_index_series() - sage: Lplus = species.LinearOrderSpecies(min=1).cycle_index_series() - sage: RegularOctopuses = C.arithmetic_product(Lplus) - sage: RegOctSpeciesSeq = RegularOctopuses.generating_series().counts(8) - sage: RegOctSpeciesSeq - [0, 1, 3, 8, 42, 144, 1440, 5760] - - It is shown in [MM]_ that the exponential generating function for regular octopuses satisfies - `(C \\boxdot L_{+}) (x) = \\sum_{n \geq 1} \\sigma (n) (n - 1)! \\frac{x^{n}}{n!}` (where `\\sigma (n)` is - the sum of the divisors of `n`). :: - - sage: RegOctDirectSeq = [0] + [sum(divisors(i))*factorial(i-1) for i in range(1,8)] - sage: RegOctDirectSeq == RegOctSpeciesSeq - True - - AUTHORS: - - - Andrew Gainer-Dewar (2013) - - REFERENCES: - - .. [MM] \M. Maia and M. Mendez. "On the arithmetic product of combinatorial species". - Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427. - :arxiv:`math/0503436v2`. - - """ - from itertools import product, repeat, chain - - p = self.base_ring() - - if check_input: - assert self.coefficient(0) == p.zero() - assert g.coefficient(0) == p.zero() - - # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_. - def arith_prod_of_partitions(l1, l2): - # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by - # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes - # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2` - # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a - # partition of `nm`. - term_iterable = chain.from_iterable(repeat(lcm(pair), gcd(pair)) - for pair in product(l1, l2)) - return Partition(sorted(term_iterable, reverse=True)) - - # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_. - # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric - # functions, but this boils down to the same: Their x_i corresponds to the i-th power - # sum symmetric function.) - def arith_prod_sf(x, y): - ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2)) - return p._apply_multi_module_morphism(x, y, ap_sf_wrapper) - - # Sage stores cycle index series by degree. - # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful - # to compute all terms of a given degree `n` at once. - def arith_prod_coeff(n): - if n == 0: - res = p.zero() - else: - index_set = ((d, n // d) for d in divisors(n)) - res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set) - - # Build a list which has res in the `n`th slot and 0's before and after - # to feed to sum_generator - res_in_seq = [p.zero()]*n + [res, p.zero()] - - return self.parent(res_in_seq) - - # Finally, we use the sum_generator method to assemble these results into a single - # LazyPowerSeries object. - return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) - - def _cycle_type(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] - sage: cis = species.PermutationSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1]] - sage: cis = species.SetSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[1], [1], [1]] - """ - if s == []: - return self._card(0) - res = [] - for k in range(1, self._upper_bound_for_longest_cycle(s)+1): - e = 0 - for d in divisors(k): - m = moebius(d) - if m == 0: - continue - u = s.power(k/d) - e += m*self.count(u) - res.extend([k]*int(e/k)) - res.reverse() - return Partition(res) - - - def _upper_bound_for_longest_cycle(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._upper_bound_for_longest_cycle([4]) - 4 - sage: cis._upper_bound_for_longest_cycle([3,1]) - 3 - sage: cis._upper_bound_for_longest_cycle([2,2]) - 2 - sage: cis._upper_bound_for_longest_cycle([2,1,1]) - 2 - sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) - 1 - """ - if s == []: - return 1 - return min(self._card(sum(s)), lcm(list(s))) - - def _card(self, n): - r""" - Return the number of structures on an underlying set of size ``n`` for - the species associated with ``self``. - - This is just ``n!`` times the coefficient of ``p[1]n`` in ``self``. - - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._card(4) - 15 - """ - p = self.coefficient(n) - return factorial(n) * p.coefficient([1] * n) - - def _compose_gen(self, y, ao): - """ - Return a generator for the coefficients of the composition of this - cycle index series and the cycle index series ``y``. This overrides - the method defined in ``LazyPowerSeries``. - - The notion "composition" means plethystic substitution here, as - defined in Section 2.2 of [BLL-Intro]_. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._compose_gen(C.cycle_index_series(),0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - assert y.coefficient(0) == 0 - y_powers = Stream(y._power_gen()) - - parent = self.parent() - res = parent.sum_generator(self._compose_term(self.coefficient(i), y_powers) - for i in _integers_from(0)) - - for i in _integers_from(0): - yield res.coefficient(i) - - def _compose_term(self, p, y_powers): - r""" - Return the composition of one term in ``self`` with `y`. - - INPUT: - - - ``p`` - a term in ``self`` - - ``y_powers`` - a stream for the powers of `y` - starting with `y` - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: C_cis = C.cycle_index_series() - sage: c_powers = Stream(C_cis._power_gen()) - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._compose_term(p2, c_powers).coefficients(4) - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - parent = self.parent() - if p == 0: - return parent(0) - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent.term(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * y_powers[v-1].stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def weighted_composition(self, y_species): - r""" - Return the composition of this cycle index series with the cycle - index series of the weighted species ``y_species``. - - Note that this is basically the same algorithm as composition - except we can not use the optimization that the powering of cycle - index series commutes with 'stretching'. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: E_cis.weighted_composition(C).coefficients(4) - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - sage: E(C).cycle_index_series().coefficients(4) - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - base_ring = self.base_ring() - y = y_species.cycle_index_series(base_ring) - assert y.coefficient(0) == 0 - return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) - - - def _weighted_compose_gen(self, y_species, ao): - r""" - Return an iterator for the composition of this cycle index series - and the cycle index series of the weighted species ``y_species``. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._weighted_compose_gen(C,0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - parent = self.parent() - res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) - for i in _integers_from(0)) - - for i in _integers_from(0): - yield res.coefficient(i) - - def _weighted_compose_term(self, p, y_species): - r""" - Return the weighted composition of one term in ``self`` with ``y``. - - INPUT: - - - ``p`` -- a term in ``self`` - - ``y_species`` -- a species - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._weighted_compose_term(p2, C).coefficients(4) - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - parent = self.parent() - if p == 0: - return parent(0) - - base_ring = self.base_ring().base_ring() - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent.term(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * (y_species.weighted(y_species._weight**(e+1)).cycle_index_series(base_ring)**v).stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def compositional_inverse(self): - r""" - Return the compositional inverse of ``self`` if possible. - - (Specifically, if ``self`` is of the form `0 + p_{1} + \cdots`.) - - The compositional inverse is the inverse with respect to - plethystic substitution. This is the operation on cycle index - series which corresponds to substitution, a.k.a. partitional - composition, on the level of species. See Section 2.2 of - [BLL]_ for a definition of this operation. - - EXAMPLES:: - - sage: Eplus = species.SetSpecies(min=1).cycle_index_series() - sage: Eplus(Eplus.compositional_inverse()).coefficients(8) - [0, p[1], 0, 0, 0, 0, 0, 0] - - TESTS:: - - sage: Eplus = species.SetSpecies(min=2).cycle_index_series() - sage: Eplus.compositional_inverse() - Traceback (most recent call last): - ... - ValueError: not an invertible series - - ALGORITHM: - - Let `F` be a species satisfying `F = 0 + X + F_2 + F_3 + \cdots` for - `X` the species of singletons. (Equivalently, `\lvert F[\varnothing] - \rvert = 0` and `\lvert F[\{1\}] \rvert = 1`.) Then there exists a - (virtual) species `G` satisfying `F \circ G = G \circ F = X`. - - It follows that `(F - X) \circ G = F \circ G - X \circ G = X - G`. - Rearranging, we obtain the recursive equation `G = X - (F - X) \circ G`, - which can be solved using iterative methods. - - .. WARNING:: - - This algorithm is functional but can be very slow. - Use with caution! - - .. SEEALSO:: - - The compositional inverse `\Omega` of the species `E_{+}` - of nonempty sets can be handled much more efficiently - using specialized methods. See - :func:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries` - - AUTHORS: - - - Andrew Gainer-Dewar - """ - cisr = self.parent() - sfa = cisr._base - - X = cisr([0, sfa([1]), 0]) - - if self.coefficients(2) != X.coefficients(2): - raise ValueError('not an invertible series') - - res = cisr() - res.define(X - (self - X).compose(res)) - - return res - - def derivative(self, order=1): - r""" - Return the species-theoretic `n`-th derivative of ``self``, - where `n` is ``order``. - - For a cycle index series `F (p_{1}, p_{2}, p_{3}, \ldots)`, its - derivative is the cycle index series `F' = D_{p_{1}} F` (that is, - the formal derivative of `F` with respect to the variable `p_{1}`). - - If `F` is the cycle index series of a species `S` then `F'` is the - cycle index series of an associated species `S'` of `S`-structures - with a "hole". - - EXAMPLES: - - The species `E` of sets satisfies the relationship `E' = E`:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: E.coefficients(8) == E.derivative().coefficients(8) - True - - The species `C` of cyclic orderings and the species `L` of linear - orderings satisfy the relationship `C' = L`:: - - sage: C = species.CycleSpecies().cycle_index_series() - sage: L = species.LinearOrderSpecies().cycle_index_series() - sage: L.coefficients(8) == C.derivative().coefficients(8) - True - """ - # Make sure that order is integral - order = Integer(order) - - if order < 0: - raise ValueError("Order must be a non-negative integer") - - elif order == 0: - return self - - elif order == 1: - parent = self.parent() - derivative_term = lambda n: parent.term(self.coefficient(n+1).derivative_with_respect_to_p1(), n) - return parent.sum_generator(derivative_term(i) for i in _integers_from(0)) - - else: - return self.derivative(order-1) - - def pointing(self): - r""" - Return the species-theoretic pointing of ``self``. - - For a cycle index `F`, its pointing is the cycle index series - `F^{\bullet} = p_{1} \cdot F'`. - - If `F` is the cycle index series of a species `S` then `F^{\bullet}` - is the cycle index series of an associated species `S^{\bullet}` - of `S`-structures with a marked "root". - - EXAMPLES: - - The species `E^{\bullet}` of "pointed sets" satisfies - `E^{\bullet} = X \cdot E`:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: E.pointing().coefficients(8) == (X*E).coefficients(8) - True - - """ - p1 = self.base_ring()([1]) - X = self.parent()([0, p1, 0]) - - return X*self.derivative() - - def integral(self, *args): - r""" - Given a cycle index `G`, it is not in general possible to recover a - single cycle index `F` such that `F' = G` (even up to addition of a - constant term). - - More broadly, it may be the case that there are many non-isomorphic - species `S` such that `S' = T` for a given species `T`. - For example, the species `3 C_{3}` of 3-cycles from three distinct - classes and the species `X^{3}` of 3-sets are not isomorphic, but - `(3 C_{3})' = (X^{3})' = 3 X^{2}`. - - EXAMPLES:: - - sage: C3 = species.CycleSpecies(size=3).cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: (3*C3).derivative().coefficients(8) == (3*X^2).coefficients(8) - True - sage: (X^3).derivative().coefficients(8) == (3*X^2).coefficients(8) - True - - .. WARNING:: - - This method has no implementation and exists only to prevent you from - doing something strange. Calling it raises a ``NotImplementedError``! - """ - raise NotImplementedError - - def exponential(self): - r""" - Return the species-theoretic exponential of ``self``. - - For a cycle index `Z_{F}` of a species `F`, its exponential is the - cycle index series `Z_{E} \circ Z_{F}`, where `Z_{E}` is the - :meth:`~sage.combinat.species.generating_series.ExponentialCycleIndexSeries`. - - The exponential `Z_{E} \circ Z_{F}` is then the cycle index series - of the species `E \circ F` of "sets of `F`-structures". - - EXAMPLES: - - Let `BT` be the species of binary trees, `BF` the species of binary - forests, and `E` the species of sets. Then we have `BF = E \circ BT`:: - - sage: BT = species.BinaryTreeSpecies().cycle_index_series() - sage: BF = species.BinaryForestSpecies().cycle_index_series() - sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) - True - """ - base_ring = self.parent().base_ring().base_ring() - E = ExponentialCycleIndexSeries(base_ring) - return E.compose(self) - - def logarithm(self): - r""" - Return the combinatorial logarithm of ``self``. - - For a cycle index `Z_{F}` of a species `F`, its logarithm is the - cycle index series `Z_{\Omega} \circ Z_{F}`, where `Z_{\Omega}` is the - :meth:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries`. - - The logarithm `Z_{\Omega} \circ Z_{F}` is then the cycle index series - of the (virtual) species `\Omega \circ F` of "connected `F`-structures". - In particular, if `F = E^{+} \circ G` for `E^{+}` the species of - nonempty sets and `G` some other species, then `\Omega \circ F = G`. - - EXAMPLES: - - Let `G` be the species of nonempty graphs and `CG` be the species of nonempty connected - graphs. Then `G = E^{+} \circ CG`, so `CG = \Omega \circ G`:: - - sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 - sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: CG = LogarithmCycleIndexSeries().compose(G) - sage: CG.isotype_generating_series().coefficients(8) - [0, 1, 1, 2, 6, 21, 112, 853] - """ - base_ring = self.parent().base_ring().base_ring() - Omega = LogarithmCycleIndexSeries(base_ring) - return Omega.compose(self) \ No newline at end of file From 39993e3ac56e0e26b69dd3a889c2aa8c030558fb Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Fri, 13 Aug 2021 23:43:35 +0530 Subject: [PATCH 014/350] Fixed the initialising issue. --- .../combinat/species/generating_series.py | 282 +++++++++--------- 1 file changed, 145 insertions(+), 137 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 2b94f5a1587..a1072f1afbf 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -18,7 +18,7 @@ sage: from sage.combinat.species.stream import Stream, _integers_from sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ, 'z') :: @@ -89,52 +89,31 @@ from sage.functions.other import factorial -class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): +class OrdinaryGeneratingSeries(LazyTaylorSeries): r""" - Return the ring of ordinary generating series over ``R``. + A class for ordinary generating series. Note that it is just a - :class:`LazyTaylorSeriesRing` whose elements have + :class:`LazyTaylorSeries` whose elements have some extra methods. EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z'); R - Lazy Taylor Series Ring in z over Rational Field - sage: [R(lambda n: 1).coefficient(i) for i in range(4)] - [1, 1, 1, 1] - sage: R(lambda n: 1).counts(4) - [1, 1, 1, 1] - - TESTS: - - We test to make sure that caching works. - - :: - - sage: R is OrdinaryGeneratingSeriesRing(QQ, 'z') - True + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: f = R(lambda n: n) + sage: f + z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) """ - def __init__(self, R, names): - """ - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') - sage: R == loads(dumps(R)) - True - """ - LazyTaylorSeriesRing.Element = OrdinaryGeneratingSeries - LazyTaylorSeriesRing.__init__(self, R, names=names) - - -class OrdinaryGeneratingSeries(LazyTaylorSeries): def count(self, n): """ Return the number of structures on a set of size ``n``. + INPUT: + + - ``n`` -- the size of the set + EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing @@ -142,6 +121,7 @@ def count(self, n): sage: f = R(range(20)) sage: f.count(10) 10 + """ return self.coefficient(n) @@ -157,13 +137,14 @@ def counts(self, n): sage: f = R(range(20)) sage: f.counts(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + """ return [self.count(i) for i in range(n)] -class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): +class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): r""" - Return the ring of exponential generating series over ``R``. + Return the ring of ordinary generating series over ``R``. Note that it is just a :class:`LazyTaylorSeriesRing` whose elements have @@ -171,13 +152,15 @@ class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): EXAMPLES:: - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ, 'z'); R + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z'); R Lazy Taylor Series Ring in z over Rational Field sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] sage: R(lambda n: 1).counts(4) - [1, 1, 2, 6] + [1, 1, 1, 1] + sage: R == loads(dumps(R)) + True TESTS: @@ -185,23 +168,30 @@ class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): :: - sage: R is ExponentialGeneratingSeriesRing(QQ, 'z') + sage: R is OrdinaryGeneratingSeriesRing(QQ, 'z') True """ - def __init__(self, R, names): - """ - EXAMPLES:: + Element = OrdinaryGeneratingSeries - sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') - sage: R == loads(dumps(R)) - True - """ - LazyTaylorSeriesRing.Element = ExponentialGeneratingSeries - LazyTaylorSeriesRing.__init__(self, R, names=names) class ExponentialGeneratingSeries(LazyTaylorSeries): + r""" + A class for ordinary generating series. + + Note that it is just a + :class:`LazyTaylorSeries` whose elements have + some extra methods. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: f = R(lambda n: n) + sage: f + z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) + + """ def count(self, n): """ Return the number of structures of size ``n``. @@ -213,6 +203,7 @@ def count(self, n): sage: f = R(lambda n: 1) sage: [f.count(i) for i in range(7)] [1, 1, 2, 6, 24, 120, 720] + """ return factorial(n) * self.coefficient(n) @@ -228,6 +219,7 @@ def counts(self, n): sage: f = R(range(20)) sage: f.counts(5) [0, 1, 4, 18, 96] + """ return [self.count(i) for i in range(n)] @@ -254,6 +246,7 @@ def functorial_composition(self, y): sage: g = G.generating_series() sage: g.coefficients(10) [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] + """ return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) @@ -273,6 +266,7 @@ def _functorial_compose_gen(self, y, ao): sage: g = g1._functorial_compose_gen(g2, 0) sage: [next(g) for i in range(10)] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] + """ n = 0 while True: @@ -280,68 +274,23 @@ def _functorial_compose_gen(self, y, ao): n += 1 -def factorial_gen(): - """ - A generator for the factorials starting at 0. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import factorial_gen - sage: g = factorial_gen() - sage: [next(g) for i in range(5)] - [1, 1, 2, 6, 24] - """ - z = Integer(1) - yield z - yield z - n = Integer(2) - while True: - z *= n - yield z - n += 1 - - -@cached_function -def CycleIndexSeriesRing(R): +class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): r""" - Return the ring of cycle index series over ``R``. - - This is the ring of formal power series `\Lambda[x]`, where - `\Lambda` is the ring of symmetric functions over ``R`` in the - `p`-basis. Its purpose is to house the cycle index series of - species (in a somewhat nonstandard notation tailored to Sage): - If `F` is a species, then the *cycle index series* of `F` is - defined to be the formal power series - - .. MATH:: - - \sum_{n \geq 0} \frac{1}{n!} (\sum_{\sigma \in S_n} - \operatorname{fix} F[\sigma] - \prod_{z \text{ is a cycle of } \sigma} - p_{\text{length of } z}) x^n - \in \Lambda_\QQ [x], - - where `\operatorname{fix} F[\sigma]` denotes the number of - fixed points of the permutation `F[\sigma]` of `F[n]`. We - notice that this power series is "equigraded" (meaning that - its `x^n`-coefficient is homogeneous of degree `n`). A more - standard convention in combinatorics would be to use - `x_i` instead of `p_i`, and drop the `x` (that is, evaluate - the above power series at `x = 1`); but this would be more - difficult to implement in Sage, as it would be an element - of a power series ring in infinitely many variables. + Return the ring of exponential generating series over ``R``. - Note that it is just a :class:`LazyTaylorSeriesRing` (whose base - ring is `\Lambda`) whose elements have some extra methods. + Note that it is just a + :class:`LazyTaylorSeriesRing` whose elements have + some extra methods. EXAMPLES:: - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - sage: R([1]).coefficients(4) # This is not combinatorially - ....: # meaningful. + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ, 'z'); R + Lazy Taylor Series Ring in z over Rational Field + sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] + sage: R(lambda n: 1).counts(4) + [1, 1, 2, 6] TESTS: @@ -349,35 +298,32 @@ def CycleIndexSeriesRing(R): :: - sage: R is CycleIndexSeriesRing(QQ) + sage: R is ExponentialGeneratingSeriesRing(QQ, 'z') True - """ - return CycleIndexSeriesRing(R) + """ + Element = ExponentialGeneratingSeries -class CycleIndexSeriesRing(LazyTaylorSeriesRing): - def __init__(self, R): - """ - EXAMPLES:: - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - sage: R == loads(dumps(R)) - True - """ - R = SymmetricFunctions(R).power() - LazyTaylorSeriesRing.__init__(self, R, element_class=CycleIndexSeries) +def factorial_gen(): + """ + A generator for the factorials starting at 0. - def __repr__(self): - """ - EXAMPLES:: + EXAMPLES:: - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ) - Cycle Index Series Ring over Symmetric Functions over Rational Field in the powersum basis - """ - return "Cycle Index Series Ring over %s"%self.base_ring() + sage: from sage.combinat.species.generating_series import factorial_gen + sage: g = factorial_gen() + sage: [next(g) for i in range(5)] + [1, 1, 2, 6, 24] + """ + z = Integer(1) + yield z + yield z + n = Integer(2) + while True: + z *= n + yield z + n += 1 class CycleIndexSeries(LazyTaylorSeries): @@ -390,7 +336,7 @@ def count(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) sage: f.count([1]) 1 @@ -410,7 +356,7 @@ def coefficient_cycle_type(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) sage: f.coefficient_cycle_type([1]) 1 @@ -423,7 +369,6 @@ def coefficient_cycle_type(self, t): p = self.coefficient(t.size()) return p.coefficient(t) - def stretch(self, k): r""" Return the stretch of the cycle index series ``self`` by a positive @@ -445,7 +390,7 @@ def stretch(self, k): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) sage: f.stretch(3).coefficients(10) [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] @@ -458,7 +403,7 @@ def _stretch_gen(self, k, ao): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ) + sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([p([1])]) # This is the power series whose all coefficients ....: # are p[1]. Not combinatorially meaningful! sage: g = f._stretch_gen(2,0) @@ -831,7 +776,6 @@ def _cycle_type(self, s): res.reverse() return Partition(res) - def _upper_bound_for_longest_cycle(self, s): """ EXAMPLES:: @@ -957,7 +901,6 @@ def weighted_composition(self, y_species): assert y.coefficient(0) == 0 return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) - def _weighted_compose_gen(self, y_species, ao): r""" Return an iterator for the composition of this cycle index series @@ -1235,6 +1178,71 @@ def logarithm(self): Omega = LogarithmCycleIndexSeries(base_ring) return Omega.compose(self) + +class CycleIndexSeriesRing(LazyTaylorSeriesRing): + r""" + Return the ring of cycle index series over ``R``. + + This is the ring of formal power series `\Lambda[x]`, where + `\Lambda` is the ring of symmetric functions over ``R`` in the + `p`-basis. Its purpose is to house the cycle index series of + species (in a somewhat nonstandard notation tailored to Sage): + If `F` is a species, then the *cycle index series* of `F` is + defined to be the formal power series + + .. MATH:: + + \sum_{n \geq 0} \frac{1}{n!} (\sum_{\sigma \in S_n} + \operatorname{fix} F[\sigma] + \prod_{z \text{ is a cycle of } \sigma} + p_{\text{length of } z}) x^n + \in \Lambda_\QQ [x], + + where `\operatorname{fix} F[\sigma]` denotes the number of + fixed points of the permutation `F[\sigma]` of `F[n]`. We + notice that this power series is "equigraded" (meaning that + its `x^n`-coefficient is homogeneous of degree `n`). A more + standard convention in combinatorics would be to use + `x_i` instead of `p_i`, and drop the `x` (that is, evaluate + the above power series at `x = 1`); but this would be more + difficult to implement in Sage, as it would be an element + of a power series ring in infinitely many variables. + + Note that it is just a :class:`LazyTaylorSeriesRing` (whose base + ring is `\Lambda`) whose elements have some extra methods. + + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: R = CycleIndexSeriesRing(QQ, 'z'); R + Cycle Index Series Ring over Rational Field + sage: R([1]).coefficients(4) # This is not combinatorially + ....: # meaningful. + [1, 1, 1, 1] + + TESTS: + + We test to make sure that caching works. + + :: + + sage: R is CycleIndexSeriesRing(QQ, 'z') + True + + """ + Element = CycleIndexSeries + + def __repr__(self): + """ + EXAMPLES:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: CycleIndexSeriesRing(QQ, 'z') + Cycle Index Series Ring over Rational Field + """ + return "Cycle Index Series Ring over %s"%self.base_ring() + + @cached_function def _exp_term(n, R = RationalField()): """ @@ -1284,7 +1292,7 @@ def ExponentialCycleIndexSeries(R = RationalField()): + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] """ - CIS = CycleIndexSeriesRing(R) + CIS = CycleIndexSeriesRing(R, 'z') return CIS(_exp_gen(R)) @@ -1356,6 +1364,6 @@ def LogarithmCycleIndexSeries(R = RationalField()): sage: LogarithmCycleIndexSeries().compose(Eplus).coefficients(4) [0, p[1], 0, 0] """ - CIS = CycleIndexSeriesRing(R) + CIS = CycleIndexSeriesRing(R, 'z') return CIS(_cl_gen(R)) From 73b9964c3499ec8f10e3fb992dd97e8dc476f82d Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Sun, 15 Aug 2021 01:09:13 +0530 Subject: [PATCH 015/350] Fixed naming issue. --- .../combinat/species/generating_series.py | 31 +++++++++++++------ src/sage/rings/lazy_laurent_series_ring.py | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index a1072f1afbf..fff6bce7bab 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -85,7 +85,7 @@ from sage.combinat.partition import Partition, Partitions from functools import partial from sage.combinat.sf.sf import SymmetricFunctions -from sage.misc.cachefunc import cached_function +from sage.misc.cachefunc import cached_function, cached_method from sage.functions.other import factorial @@ -248,13 +248,20 @@ def functorial_composition(self, y): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) + # return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) + P = self.parent() + return P(partial(self._functorial_compose_gen, y), 0) - def _functorial_compose_gen(self, y, ao): + def _functorial_compose_gen(self, y, n): """ - Returns a generator for the coefficients of the functorial + Returns the ``n``th coefficient of the functorial composition of self with y. + INPUT: + + - ``y`` -- the other series + - ``n`` -- the nth term of the functorial composition + EXAMPLES:: sage: E = species.SetSpecies() @@ -268,10 +275,11 @@ def _functorial_compose_gen(self, y, ao): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - n = 0 - while True: - yield self.count(y.count(n)) / factorial(n) - n += 1 + return self.count(y.count(n)) / factorial(n) + # n = 0 + # while True: + # yield self.count(y.count(n)) / factorial(n) + # n += 1 class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): @@ -395,7 +403,10 @@ def stretch(self, k): sage: f.stretch(3).coefficients(10) [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] """ - return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) + # return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) + P = self.parent() + stream = partial(self._stretch_gen, k) + return P(next(stream), lambda ao: k*ao) def _stretch_gen(self, k, ao): """ @@ -1216,7 +1227,7 @@ class CycleIndexSeriesRing(LazyTaylorSeriesRing): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: R = CycleIndexSeriesRing(QQ, 'z'); R Cycle Index Series Ring over Rational Field - sage: R([1]).coefficients(4) # This is not combinatorially + sage: [R(lambda n: 1).coefficient(i) for i in range(4)] # This is not combinatorially ....: # meaningful. [1, 1, 1, 1] diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index daea58aebf0..90353026ea3 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -778,7 +778,7 @@ class LazyTaylorSeriesRing(UniqueRepresentation, Parent): """ Element = LazyTaylorSeries - def __init__(self, base_ring, names, sparse=False, category=None): + def __init__(self, base_ring, names='z', sparse=False, category=None): """ Initialize ``self``. From db206803e6c2847bb01600f1ba63ba9539894408 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Tue, 17 Aug 2021 01:02:34 +0530 Subject: [PATCH 016/350] Changed _gs_iterator to callables --- src/sage/combinat/species/cycle_species.py | 16 ++++++++++------ src/sage/combinat/species/generating_series.py | 7 +++---- src/sage/combinat/species/partition_species.py | 18 ++++++++++-------- .../combinat/species/permutation_species.py | 10 ++++++---- src/sage/combinat/species/set_species.py | 9 +++++---- src/sage/combinat/species/species.py | 13 +++++++++---- src/sage/combinat/species/subset_species.py | 11 ++++++----- 7 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index ba41b643d73..56cd3473f82 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -177,7 +177,7 @@ def _isotypes(self, structure_class, labels): if len(labels) != 0: yield structure_class(self, labels, range(1, len(labels)+1)) - def _gs_iterator(self, base_ring): + def _gs_iterator(self, base_ring, n): r""" The generating series for cyclic permutations is `-\log(1-x) = \sum_{n=1}^\infty x^n/n`. @@ -186,20 +186,24 @@ def _gs_iterator(self, base_ring): sage: P = species.CycleSpecies() sage: g = P.generating_series() - sage: g.coefficients(10) + sage: [g.coefficient(i) for i in range(10)] [0, 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9] TESTS:: sage: P = species.CycleSpecies() sage: g = P.generating_series(RR) - sage: g.coefficients(3) + sage: [g.coefficient(i) for i in range(3)] [0.000000000000000, 1.00000000000000, 0.500000000000000] """ one = base_ring(1) - yield base_ring(0) - for n in _integers_from(ZZ(1)): - yield self._weight*one/n + # yield base_ring(0) + # for n in _integers_from(ZZ(1)): + # yield self._weight*one/n + if n == 0: + return base_ring(0) + else: + return self._weight*one/n def _order(self): """ diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index fff6bce7bab..0f7466a0bc4 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -244,13 +244,13 @@ def functorial_composition(self, y): sage: G = species.SimpleGraphSpecies() sage: g = G.generating_series() - sage: g.coefficients(10) + sage: [g.coefficient(i) for i in range(10)] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ # return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) P = self.parent() - return P(partial(self._functorial_compose_gen, y), 0) + return P(lambda n: self._functorial_compose_gen(y, n), 0) def _functorial_compose_gen(self, y, n): """ @@ -270,8 +270,7 @@ def _functorial_compose_gen(self, y, n): sage: P2 = E2*E sage: g1 = WP.generating_series() sage: g2 = P2.generating_series() - sage: g = g1._functorial_compose_gen(g2, 0) - sage: [next(g) for i in range(10)] + sage: [g1._functorial_compose_gen(g2, i) for i in range(10)] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index 489f74385ca..62f1b7214a5 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -233,20 +233,21 @@ def _canonical_rep_from_partition(self, structure_class, labels, p): breaks = [sum(p[:i]) for i in range(len(p) + 1)] return structure_class(self, labels, [list(range(breaks[i]+1, breaks[i+1]+1)) for i in range(len(p))]) - def _gs_iterator(self, base_ring): + def _gs_iterator(self, base_ring, n): r""" EXAMPLES:: sage: P = species.PartitionSpecies() sage: g = P.generating_series() - sage: g.coefficients(5) + sage: [g.coefficient(i) for i in range(5)] [1, 1, 1, 5/6, 5/8] """ from sage.combinat.combinat import bell_number - for n in _integers_from(0): - yield self._weight * base_ring(bell_number(n) / factorial(n)) + # for n in _integers_from(0): + # yield self._weight * base_ring(bell_number(n) / factorial(n)) + return self._weight * base_ring(bell_number(n) / factorial(n)) - def _itgs_iterator(self, base_ring): + def _itgs_iterator(self, base_ring, n): r""" The isomorphism type generating series is given by `\frac{1}{1-x}`. @@ -255,12 +256,13 @@ def _itgs_iterator(self, base_ring): sage: P = species.PartitionSpecies() sage: g = P.isotype_generating_series() - sage: g.coefficients(10) + sage: [g.coefficient(i) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ from sage.combinat.partition import number_of_partitions - for n in _integers_from(0): - yield self._weight*base_ring(number_of_partitions(n)) + # for n in _integers_from(0): + # yield self._weight*base_ring(number_of_partitions(n)) + return self._weight*base_ring(number_of_partitions(n)) def _cis(self, series_ring, base_ring): r""" diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index 57b282e211b..c5aa5f5a5bc 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -201,7 +201,7 @@ def _gs_list(self, base_ring): return [base_ring(1)] - def _itgs_iterator(self, base_ring): + def _itgs_iterator(self, base_ring, n): r""" The isomorphism type generating series is given by `\frac{1}{1-x}`. @@ -210,12 +210,14 @@ def _itgs_iterator(self, base_ring): sage: P = species.PermutationSpecies() sage: g = P.isotype_generating_series() - sage: g.coefficients(10) + sage: [g.coefficient(i) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ + # from sage.combinat.partition import number_of_partitions + # for n in _integers_from(0): + # yield base_ring(number_of_partitions(n)) from sage.combinat.partition import number_of_partitions - for n in _integers_from(0): - yield base_ring(number_of_partitions(n)) + return base_ring(number_of_partitions(n)) def _cis(self, series_ring, base_ring): diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 5622d95e1ee..535f97616ac 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -130,7 +130,7 @@ def _structures(self, structure_class, labels): _isotypes = _structures - def _gs_iterator(self, base_ring): + def _gs_iterator(self, base_ring, n): r""" The generating series for the species of sets is given by `e^x`. @@ -139,13 +139,14 @@ def _gs_iterator(self, base_ring): sage: S = species.SetSpecies() sage: g = S.generating_series() - sage: g.coefficients(10) + sage: [g.coefficient(i) for i in range(10)] [1, 1, 1/2, 1/6, 1/24, 1/120, 1/720, 1/5040, 1/40320, 1/362880] sage: [g.count(i) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - for n in _integers_from(0): - yield base_ring(self._weight / factorial(n)) + # for n in _integers_from(0): + # yield base_ring(self._weight / factorial(n)) + return base_ring(self._weight / factorial(n)) def _itgs_list(self, base_ring): r""" diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index aa5e29356d2..07ddae377fd 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -484,11 +484,16 @@ def _get_series(self, series_ring_class, prefix, base_ring=None): """ series = self._series_helper(series_ring_class, prefix, base_ring=base_ring) + if self._min is not None: + series = series.parent()(lambda n: series[n], self._min) + if self._max is not None: + series = series.truncate(self._max) # We need to restrict the series based on the min # and max of this species. Note that if min and max # are both None (as in the default case), then the restrict # method will just return series. - return series.restricted(min=self._min, max=self._max) + # return series.restricted(min=self._min, max=self._max) + return series def _series_helper(self, series_ring_class, prefix, base_ring=None): """ @@ -555,11 +560,11 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): # for the coefficients of the generating series. Optionally, # the subclass can specify the order of the series. try: - iterator = getattr(self, prefix + "_iterator")(base_ring) + iterator = getattr(self, prefix + "_iterator") try: - return series_ring(iterator, order=self._order()) + return series_ring(lambda n: iterator(base_ring, n), valuation=self._order()) except AttributeError: - return series_ring(iterator) + return series_ring(lambda n: iterator(base_ring, n)) except AttributeError: pass diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 830a5ff8a9e..d110980e24d 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -187,7 +187,7 @@ def _isotypes(self, structure_class, labels): for i in range(len(labels)+1): yield structure_class(self, labels, range(1, i+1)) - def _gs_iterator(self, base_ring): + def _gs_iterator(self, base_ring, n): """ The generating series for the species of subsets is `e^{2x}`. @@ -195,13 +195,14 @@ def _gs_iterator(self, base_ring): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.generating_series().coefficients(5) + sage: [S.generating_series().coefficient(i) for i in range(5)] [1, 2, 2, 4/3, 2/3] """ - for n in _integers_from(0): - yield base_ring(2)**n / base_ring(factorial(n)) + return base_ring(2)**n / base_ring(factorial(n)) + # for n in _integers_from(0): + # yield base_ring(2)**n / base_ring(factorial(n)) - def _itgs_iterator(self, base_ring): + def _itgs_iterator(self, base_ring, n): r""" The generating series for the species of subsets is `e^{2x}`. From 974fa4f1c3a91dd05b677f0f8d363b9b525690d1 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 18 Aug 2021 01:00:49 +0530 Subject: [PATCH 017/350] Changed _list and _term methods. --- .../species/characteristic_species.py | 28 +++++++++---------- .../combinat/species/composition_species.py | 16 +++++------ src/sage/combinat/species/cycle_species.py | 19 ++++++------- src/sage/combinat/species/empty_species.py | 26 ++++++++--------- .../species/functorial_composition_species.py | 10 +++---- .../combinat/species/generating_series.py | 6 ++-- .../combinat/species/linear_order_species.py | 16 +++++------ .../combinat/species/partition_species.py | 10 ++----- .../combinat/species/permutation_species.py | 14 +++++----- src/sage/combinat/species/product_species.py | 8 +++--- .../combinat/species/recursive_species.py | 28 +++++++++---------- src/sage/combinat/species/set_species.py | 12 ++++---- src/sage/combinat/species/species.py | 10 +++---- src/sage/combinat/species/subset_species.py | 13 ++++----- 14 files changed, 104 insertions(+), 112 deletions(-) diff --git a/src/sage/combinat/species/characteristic_species.py b/src/sage/combinat/species/characteristic_species.py index a664ff80b4a..bd46b135ac5 100644 --- a/src/sage/combinat/species/characteristic_species.py +++ b/src/sage/combinat/species/characteristic_species.py @@ -109,15 +109,15 @@ def __init__(self, n, min=None, max=None, weight=None): [1] sage: X.structures([1,2]).list() [] - sage: X.generating_series().coefficients(4) + sage: X.generating_series()[0:4] [0, 1, 0, 0] - sage: X.isotype_generating_series().coefficients(4) + sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series().coefficients(4) + sage: X.cycle_index_series()[0:4] [0, p[1], 0, 0] sage: F = species.CharacteristicSpecies(3) - sage: c = F.generating_series().coefficients(4) + sage: c = F.generating_series()[0:4] sage: F._check() True sage: F == loads(dumps(F)) @@ -163,7 +163,7 @@ def _gs_term(self, base_ring): EXAMPLES:: sage: F = species.CharacteristicSpecies(2) - sage: F.generating_series().coefficients(5) + sage: F.generating_series()[0:5] [0, 0, 1/2, 0, 0] sage: F.generating_series().count(2) 1 @@ -187,7 +187,7 @@ def _itgs_term(self, base_ring): EXAMPLES:: sage: F = species.CharacteristicSpecies(2) - sage: F.isotype_generating_series().coefficients(5) + sage: F.isotype_generating_series()[0:5] [0, 0, 1, 0, 0] Here we test out weighting each structure by q. @@ -196,7 +196,7 @@ def _itgs_term(self, base_ring): sage: R. = ZZ[] sage: Fq = species.CharacteristicSpecies(2, weight=q) - sage: Fq.isotype_generating_series().coefficients(5) + sage: Fq.isotype_generating_series()[0:5] [0, 0, q, 0, 0] """ return base_ring(self._weight) @@ -207,7 +207,7 @@ def _cis_term(self, base_ring): sage: F = species.CharacteristicSpecies(2) sage: g = F.cycle_index_series() - sage: g.coefficients(5) + sage: g[0:5] [0, 0, 1/2*p[1, 1] + 1/2*p[2], 0, 0] """ cis = SetSpecies(weight=self._weight).cycle_index_series(base_ring) @@ -248,11 +248,11 @@ def __init__(self, min=None, max=None, weight=None): [{}] sage: X.structures([1,2]).list() [] - sage: X.generating_series().coefficients(4) + sage: X.generating_series()[0:4] [1, 0, 0, 0] - sage: X.isotype_generating_series().coefficients(4) + sage: X.isotype_generating_series()[0:4] [1, 0, 0, 0] - sage: X.cycle_index_series().coefficients(4) + sage: X.cycle_index_series()[0:4] [p[], 0, 0, 0] TESTS:: @@ -290,11 +290,11 @@ def __init__(self, min=None, max=None, weight=None): [1] sage: X.structures([1,2]).list() [] - sage: X.generating_series().coefficients(4) + sage: X.generating_series()[0:4] [0, 1, 0, 0] - sage: X.isotype_generating_series().coefficients(4) + sage: X.isotype_generating_series()[0:4] [0, 1, 0, 0] - sage: X.cycle_index_series().coefficients(4) + sage: X.cycle_index_series()[0:4] [0, p[1], 0, 0] TESTS:: diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index efc77ce508b..2866e5bad74 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -105,7 +105,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: E = species.SetSpecies() sage: C = species.CycleSpecies() sage: S = E(C) - sage: S.generating_series().coefficients(5) + sage: S.generating_series()[:5] [1, 1, 1, 1, 1] sage: E(C) is S True @@ -114,7 +114,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: c = L.generating_series().coefficients(3) + sage: c = L.generating_series()[:3] sage: L._check() #False due to isomorphism types not being implemented False sage: L == loads(dumps(L)) @@ -187,13 +187,13 @@ def _isotypes(self, structure_class, labels): raise NotImplementedError - def _gs(self, series_ring, base_ring): + def _gs(self, series_ring, base_ring, n): """ EXAMPLES:: sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.generating_series().coefficients(5) + sage: L.generating_series()[:5] [1, 1, 1, 1, 1] """ return self._F.generating_series(base_ring)(self._G.generating_series(base_ring)) @@ -204,7 +204,7 @@ def _itgs(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.isotype_generating_series().coefficients(10) + sage: L.isotype_generating_series()[:10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ cis = self.cycle_index_series(base_ring) @@ -216,7 +216,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) - sage: L.cycle_index_series().coefficients(5) + sage: L.cycle_index_series()[:5] [p[], p[1], p[1, 1] + p[2], @@ -233,7 +233,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: C = species.CycleSpecies(weight=t) sage: S = E(C) - sage: S.isotype_generating_series().coefficients(5) #indirect + sage: S.isotype_generating_series()[:5] #indirect [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] We do the same thing with set partitions weighted by the number of @@ -245,7 +245,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: E_t = species.SetSpecies(min=1,weight=t) sage: Par = E(E_t) - sage: Par.isotype_generating_series().coefficients(5) + sage: Par.isotype_generating_series()[:5] [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] """ f_cis = self._F.cycle_index_series(base_ring) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index 56cd3473f82..891d5e1d2ed 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -142,7 +142,7 @@ def __init__(self, min=None, max=None, weight=None): True sage: P = species.CycleSpecies() - sage: c = P.generating_series().coefficients(3) + sage: c = P.generating_series()[:3] sage: P._check() True sage: P == loads(dumps(P)) @@ -186,20 +186,17 @@ def _gs_iterator(self, base_ring, n): sage: P = species.CycleSpecies() sage: g = P.generating_series() - sage: [g.coefficient(i) for i in range(10)] + sage: g[0:10] [0, 1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9] TESTS:: sage: P = species.CycleSpecies() sage: g = P.generating_series(RR) - sage: [g.coefficient(i) for i in range(3)] + sage: g[0:3] [0.000000000000000, 1.00000000000000, 0.500000000000000] """ one = base_ring(1) - # yield base_ring(0) - # for n in _integers_from(ZZ(1)): - # yield self._weight*one/n if n == 0: return base_ring(0) else: @@ -217,7 +214,7 @@ def _order(self): """ return 1 - def _itgs_list(self, base_ring): + def _itgs_list(self, base_ring, n): """ The isomorphism type generating series for cyclic permutations is given by `x/(1-x)`. @@ -226,17 +223,17 @@ def _itgs_list(self, base_ring): sage: P = species.CycleSpecies() sage: g = P.isotype_generating_series() - sage: g.coefficients(5) + sage: g[0:5] [0, 1, 1, 1, 1] TESTS:: sage: P = species.CycleSpecies() sage: g = P.isotype_generating_series(RR) - sage: g.coefficients(3) + sage: g[0:3] [0.000000000000000, 1.00000000000000, 1.00000000000000] """ - return [base_ring(0), self._weight*base_ring(1)] + return base_ring(0) if n == 0 else self._weight*base_ring(1) def _cis_iterator(self, base_ring): r""" @@ -260,7 +257,7 @@ def _cis_iterator(self, base_ring): sage: P = species.CycleSpecies() sage: cis = P.cycle_index_series() - sage: cis.coefficients(7) + sage: cis[0:7] [0, p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/empty_species.py b/src/sage/combinat/species/empty_species.py index 600ea3ee2b7..6057732f490 100644 --- a/src/sage/combinat/species/empty_species.py +++ b/src/sage/combinat/species/empty_species.py @@ -34,11 +34,11 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): [] sage: X.structures([1,2]).list() [] - sage: X.generating_series().coefficients(4) + sage: X.generating_series()[0:4] [0, 0, 0, 0] - sage: X.isotype_generating_series().coefficients(4) + sage: X.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: X.cycle_index_series().coefficients(4) + sage: X.cycle_index_series()[0:4] [0, 0, 0, 0] The empty species is the zero of the semi-ring of species. @@ -49,14 +49,14 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): sage: X = S + Empt sage: X == S # TODO: Not Implemented True - sage: (X.generating_series().coefficients(4) == - ....: S.generating_series().coefficients(4)) + sage: (X.generating_series()[0:4] == + ....: S.generating_series()[0:4]) True - sage: (X.isotype_generating_series().coefficients(4) == - ....: S.isotype_generating_series().coefficients(4)) + sage: (X.isotype_generating_series()[0:4] == + ....: S.isotype_generating_series()[0:4]) True - sage: (X.cycle_index_series().coefficients(4) == - ....: S.cycle_index_series().coefficients(4)) + sage: (X.cycle_index_series()[0:4] == + ....: S.cycle_index_series()[0:4]) True The following tests that it is the zero element with respect to @@ -65,11 +65,11 @@ class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): sage: Y = Empt*S sage: Y == Empt # TODO: Not Implemented True - sage: Y.generating_series().coefficients(4) + sage: Y.generating_series()[0:4] [0, 0, 0, 0] - sage: Y.isotype_generating_series().coefficients(4) + sage: Y.isotype_generating_series()[0:4] [0, 0, 0, 0] - sage: Y.cycle_index_series().coefficients(4) + sage: Y.cycle_index_series()[0:4] [0, 0, 0, 0] TESTS:: @@ -102,7 +102,7 @@ def _gs(self, series_ring, base_ring): EXAMPLES:: sage: F = species.EmptySpecies() - sage: F.generating_series().coefficients(5) # indirect doctest + sage: F.generating_series()[0:5] # indirect doctest [0, 0, 0, 0, 0] sage: F.generating_series().count(3) 0 diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index e268af7802e..7eb3c2c399b 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -33,11 +33,11 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series().coefficients(5) + sage: G.isotype_generating_series()[0:5] [1, 1, 2, 4, 11] sage: G = species.SimpleGraphSpecies() - sage: c = G.generating_series().coefficients(2) + sage: c = G.generating_series()[0:2] sage: type(G) sage: G == loads(dumps(G)) @@ -93,7 +93,7 @@ def _gs(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.generating_series().coefficients(5) + sage: G.generating_series()[0:5] [1, 1, 1, 4/3, 8/3] """ return self._F.generating_series(base_ring).functorial_composition(self._G.generating_series(base_ring)) @@ -103,7 +103,7 @@ def _itgs(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.isotype_generating_series().coefficients(5) + sage: G.isotype_generating_series()[0:5] [1, 1, 2, 4, 11] """ return self.cycle_index_series(base_ring).isotype_generating_series() @@ -113,7 +113,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.cycle_index_series().coefficients(5) + sage: G.cycle_index_series()[0:5) [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 0f7466a0bc4..b0b64e2e661 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -399,7 +399,7 @@ def stretch(self, k): sage: p = SymmetricFunctions(QQ).power() sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) - sage: f.stretch(3).coefficients(10) + sage: f.stretch(3)[0:10] [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] """ # return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) @@ -442,7 +442,7 @@ def isotype_generating_series(self): sage: P = species.PermutationSpecies() sage: cis = P.cycle_index_series() sage: f = cis.isotype_generating_series() - sage: f.coefficients(10) + sage: f.coefficients(10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ R = self.base_ring().base_ring() @@ -472,7 +472,7 @@ def expand_as_sf(self, n, alphabet='x'): EXAMPLES:: sage: from sage.combinat.species.set_species import SetSpecies - sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4) + sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4] [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] """ diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 98c4f62eb44..ca6dbb3f88f 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -87,7 +87,7 @@ def __init__(self, min=None, max=None, weight=None): EXAMPLES:: sage: L = species.LinearOrderSpecies() - sage: L.generating_series().coefficients(5) + sage: L.generating_series()[0:5] [1, 1, 1, 1, 1] sage: L = species.LinearOrderSpecies() @@ -123,7 +123,7 @@ def _isotypes(self, structure_class, labels): """ yield structure_class(self, labels, range(1, len(labels)+1)) - def _gs_list(self, base_ring): + def _gs_list(self, base_ring, n): r""" The generating series for the species of linear orders is `\frac{1}{1-x}`. @@ -132,12 +132,12 @@ def _gs_list(self, base_ring): sage: L = species.LinearOrderSpecies() sage: g = L.generating_series() - sage: g.coefficients(10) + sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return [base_ring(1)] + return base_ring(1) - def _itgs_list(self, base_ring): + def _itgs_list(self, base_ring, n): r""" The isomorphism type generating series is given by `\frac{1}{1-x}`. @@ -146,10 +146,10 @@ def _itgs_list(self, base_ring): sage: L = species.LinearOrderSpecies() sage: g = L.isotype_generating_series() - sage: g.coefficients(10) + sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return [base_ring(1)] + return base_ring(1) def _cis_iterator(self, base_ring): @@ -158,7 +158,7 @@ def _cis_iterator(self, base_ring): sage: L = species.LinearOrderSpecies() sage: g = L.cycle_index_series() - sage: g.coefficients(5) + sage: g[0:5] [p[], p[1], p[1, 1], p[1, 1, 1], p[1, 1, 1, 1]] """ from sage.combinat.sf.sf import SymmetricFunctions diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index 62f1b7214a5..62f1f8aab6e 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -152,9 +152,9 @@ def __init__(self, min=None, max=None, weight=None): EXAMPLES:: sage: P = species.PartitionSpecies() - sage: P.generating_series().coefficients(5) + sage: P.generating_series()[0:5] [1, 1, 1, 5/6, 5/8] - sage: P.isotype_generating_series().coefficients(5) + sage: P.isotype_generating_series()[0:5] [1, 1, 2, 3, 5] sage: P = species.PartitionSpecies() @@ -243,8 +243,6 @@ def _gs_iterator(self, base_ring, n): [1, 1, 1, 5/6, 5/8] """ from sage.combinat.combinat import bell_number - # for n in _integers_from(0): - # yield self._weight * base_ring(bell_number(n) / factorial(n)) return self._weight * base_ring(bell_number(n) / factorial(n)) def _itgs_iterator(self, base_ring, n): @@ -260,8 +258,6 @@ def _itgs_iterator(self, base_ring, n): [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ from sage.combinat.partition import number_of_partitions - # for n in _integers_from(0): - # yield self._weight*base_ring(number_of_partitions(n)) return self._weight*base_ring(number_of_partitions(n)) def _cis(self, series_ring, base_ring): @@ -278,7 +274,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PartitionSpecies() sage: g = P.cycle_index_series() - sage: g.coefficients(5) + sage: g[0:5] [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index c5aa5f5a5bc..faabd035a13 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -123,13 +123,13 @@ def __init__(self, min=None, max=None, weight=None): EXAMPLES:: sage: P = species.PermutationSpecies() - sage: P.generating_series().coefficients(5) + sage: P.generating_series()[0:5] [1, 1, 1, 1, 1] - sage: P.isotype_generating_series().coefficients(5) + sage: P.isotype_generating_series()[0:5] [1, 1, 2, 3, 5] sage: P = species.PermutationSpecies() - sage: c = P.generating_series().coefficients(3) + sage: c = P.generating_series()[0:3] sage: P._check() True sage: P == loads(dumps(P)) @@ -186,7 +186,7 @@ def _canonical_rep_from_partition(self, structure_class, labels, p): return structure_class(self, labels, perm) - def _gs_list(self, base_ring): + def _gs_list(self, base_ring, n): r""" The generating series for the species of linear orders is `\frac{1}{1-x}`. @@ -195,10 +195,10 @@ def _gs_list(self, base_ring): sage: P = species.PermutationSpecies() sage: g = P.generating_series() - sage: g.coefficients(10) + sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return [base_ring(1)] + return base_ring(1) def _itgs_iterator(self, base_ring, n): @@ -234,7 +234,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: g = P.cycle_index_series() - sage: g.coefficients(5) + sage: g[0:5] [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index 4bbee606925..a9a3eed67eb 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -206,7 +206,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: X = species.SingletonSpecies() sage: A = X*X - sage: A.generating_series().coefficients(4) + sage: A.generating_series()[0:4] [0, 0, 1, 0] sage: P = species.PermutationSpecies() @@ -324,7 +324,7 @@ def _gs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.generating_series().coefficients(5) + sage: F.generating_series()[0:5] [1, 2, 3, 4, 5] """ res = (self.left_factor().generating_series(base_ring) * @@ -339,7 +339,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.isotype_generating_series().coefficients(5) + sage: F.isotype_generating_series()[0:5] [1, 2, 5, 10, 20] """ res = (self.left_factor().isotype_generating_series(base_ring) * @@ -354,7 +354,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P * P - sage: F.cycle_index_series().coefficients(5) + sage: F.cycle_index_series()[0:5] [p[], 2*p[1], 3*p[1, 1] + 2*p[2], diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 7af1a0dee36..2aad474323c 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -39,10 +39,10 @@ def __init__(self): sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) - sage: L.generating_series().coefficients(4) + sage: L.generating_series()[0:4] [1, 1, 1, 1] sage: LL = loads(dumps(L)) - sage: LL.generating_series().coefficients(4) + sage: LL.generating_series()[0:4] [1, 1, 1, 1] """ self._generating_series = {} @@ -325,7 +325,7 @@ def define(self, x): sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) - sage: L.generating_series().coefficients(4) + sage: L.generating_series()[0:4] [1, 1, 1, 1] sage: L.structures([1,2,3]).cardinality() 6 @@ -340,7 +340,7 @@ def define(self, x): :: sage: L = species.LinearOrderSpecies() - sage: L.generating_series().coefficients(4) + sage: L.generating_series()[0:4] [1, 1, 1, 1] sage: L.structures([1,2,3]).cardinality() 6 @@ -351,13 +351,13 @@ def define(self, x): sage: A = CombinatorialSpecies() sage: A.define(E+X*A*A) - sage: A.generating_series().coefficients(6) + sage: A.generating_series()[0:6] [1, 1, 2, 5, 14, 42] sage: A.generating_series().counts(6) [1, 1, 4, 30, 336, 5040] sage: len(A.structures([1,2,3,4]).list()) 336 - sage: A.isotype_generating_series().coefficients(6) + sage: A.isotype_generating_series()[0:6] [1, 1, 2, 5, 14, 42] sage: len(A.isotypes([1,2,3,4]).list()) 14 @@ -366,13 +366,13 @@ def define(self, x): sage: A = CombinatorialSpecies() sage: A.define(X+A*A) - sage: A.generating_series().coefficients(6) + sage: A.generating_series()[0:6] [0, 1, 1, 2, 5, 14] sage: A.generating_series().counts(6) [0, 1, 2, 12, 120, 1680] sage: len(A.structures([1,2,3]).list()) 12 - sage: A.isotype_generating_series().coefficients(6) + sage: A.isotype_generating_series()[0:6] [0, 1, 1, 2, 5, 14] sage: len(A.isotypes([1,2,3,4]).list()) 5 @@ -387,13 +387,13 @@ def define(self, x): sage: A.define(X5+B*B) sage: B.define(X5+C*C) sage: C.define(X2+C*C+A*A) - sage: A.generating_series().coefficients(Integer(10)) + sage: A.generating_series()[Integer(0):Integer(10) [0, 0, 0, 0, 0, 1, 0, 0, 1, 2] - sage: A.generating_series().coefficients(15) + sage: A.generating_series()[0:15] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] - sage: B.generating_series().coefficients(15) + sage: B.generating_series()[0:15] [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] - sage: C.generating_series().coefficients(15) + sage: C.generating_series()[0:15] [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142] :: @@ -402,9 +402,9 @@ def define(self, x): sage: F.define(E+X+(X*F+X*X*F)) sage: F.generating_series().counts(10) [1, 2, 6, 30, 192, 1560, 15120, 171360, 2217600, 32296320] - sage: F.generating_series().coefficients(10) + sage: F.generating_series()[0:10] [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] - sage: F.isotype_generating_series().coefficients(10) + sage: F.isotype_generating_series()[0:10] [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] """ if not isinstance(x, GenericCombinatorialSpecies): diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 535f97616ac..164fb0fca7e 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -102,11 +102,11 @@ def __init__(self, min=None, max=None, weight=None): sage: E = species.SetSpecies() sage: E.structures([1,2,3]).list() [{1, 2, 3}] - sage: E.isotype_generating_series().coefficients(4) + sage: E.isotype_generating_series()[0:4] [1, 1, 1, 1] sage: S = species.SetSpecies() - sage: c = S.generating_series().coefficients(3) + sage: c = S.generating_series()[0:3] sage: S._check() True sage: S == loads(dumps(S)) @@ -148,7 +148,7 @@ def _gs_iterator(self, base_ring, n): # yield base_ring(self._weight / factorial(n)) return base_ring(self._weight / factorial(n)) - def _itgs_list(self, base_ring): + def _itgs_list(self, base_ring, n): r""" The isomorphism type generating series for the species of sets is `\frac{1}{1-x}`. @@ -157,12 +157,12 @@ def _itgs_list(self, base_ring): sage: S = species.SetSpecies() sage: g = S.isotype_generating_series() - sage: g.coefficients(10) + sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] sage: [g.count(i) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return [base_ring(self._weight)] + return base_ring(self._weight) def _cis(self, series_ring, base_ring): r""" @@ -173,7 +173,7 @@ def _cis(self, series_ring, base_ring): sage: S = species.SetSpecies() sage: g = S.cycle_index_series() - sage: g.coefficients(5) + sage: g[0:5] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 07ddae377fd..c7cdcb49b09 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -521,13 +521,13 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing sage: S = species.SetSpecies() sage: itgs = S._series_helper(OrdinaryGeneratingSeriesRing, "itgs") - sage: itgs.coefficients(3) + sage: itgs[:3] [1, 1, 1] :: sage: itgs = S._series_helper(OrdinaryGeneratingSeriesRing, "itgs", base_ring=RDF) - sage: itgs.coefficients(3) + sage: itgs[:3] [1.0, 1.0, 1.0] """ prefix = "_" + prefix @@ -572,7 +572,7 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): # This is used when the generating series is just a single # term. try: - return series_ring.term(getattr(self, prefix + "_term")(base_ring), + return series_ring(getattr(self, prefix + "_term")(base_ring), self._order()) except AttributeError: pass @@ -583,7 +583,7 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): # The generating series with all ones coefficients is generated this # way. try: - return series_ring(getattr(self, prefix + "_list")(base_ring)) + return series_ring(lambda n: getattr(self, prefix + "_list")(base_ring, n)) except AttributeError: pass @@ -602,7 +602,7 @@ def generating_series(self, base_ring=None): sage: P = species.PermutationSpecies() sage: g = P.generating_series() - sage: g.coefficients(4) + sage: g[:4] [1, 1, 1, 1] sage: g.counts(4) [1, 1, 2, 6] diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index d110980e24d..20de1520b93 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -143,13 +143,13 @@ def __init__(self, min=None, max=None, weight=None): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.generating_series().coefficients(5) + sage: S.generating_series()[0:5] [1, 2, 2, 4/3, 2/3] - sage: S.isotype_generating_series().coefficients(5) + sage: S.isotype_generating_series()[0:5] [1, 2, 3, 4, 5] sage: S = species.SubsetSpecies() - sage: c = S.generating_series().coefficients(3) + sage: c = S.generating_series()[0:3] sage: S._check() True sage: S == loads(dumps(S)) @@ -210,11 +210,10 @@ def _itgs_iterator(self, base_ring, n): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.isotype_generating_series().coefficients(5) + sage: S.isotype_generating_series()[0:5] [1, 2, 3, 4, 5] """ - for n in _integers_from(1): - yield base_ring(n) + return base_ring(n + 1) def _cis(self, series_ring, base_ring): r""" @@ -227,7 +226,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: S = species.SubsetSpecies() - sage: S.cycle_index_series().coefficients(5) + sage: S.cycle_index_series()[0:5] [p[], 2*p[1], 2*p[1, 1] + p[2], From 6cfdf8dcd38c2e49fc6d04bbb04dbe958009fbb7 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 18 Aug 2021 01:53:42 +0530 Subject: [PATCH 018/350] Created restrict method in the series helper function. --- .../combinat/species/composition_species.py | 2 +- .../combinat/species/generating_series.py | 1 - src/sage/combinat/species/species.py | 32 +++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index 2866e5bad74..c9f58731672 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -196,7 +196,7 @@ def _gs(self, series_ring, base_ring, n): sage: L.generating_series()[:5] [1, 1, 1, 1, 1] """ - return self._F.generating_series(base_ring)(self._G.generating_series(base_ring)) + return self._F.generating_series(base_ring).functorial_composition(self._G.generating_series(base_ring)) def _itgs(self, series_ring, base_ring): """ diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index b0b64e2e661..21cc7737330 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -248,7 +248,6 @@ def functorial_composition(self, y): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - # return self._new(partial(self._functorial_compose_gen, y), lambda a,b: 0, self, y) P = self.parent() return P(lambda n: self._functorial_compose_gen(y, n), 0) diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index c7cdcb49b09..3cc983d72b4 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -24,7 +24,7 @@ sage: L = species.LinearOrderSpecies(min=1) sage: T = species.CombinatorialSpecies() sage: T.define(leaf + internal_node*L(T)) - sage: T.isotype_generating_series().coefficients(6) + sage: T.isotype_generating_series()[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] Consider the following:: @@ -335,7 +335,7 @@ def functorial_composition(self, g): sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: G = WP.functorial_composition(P2) - sage: G.isotype_generating_series().coefficients(5) + sage: G.isotype_generating_series()[0:5] [1, 1, 2, 4, 11] """ from .functorial_composition_species import FunctorialCompositionSpecies @@ -360,7 +360,7 @@ def restricted(self, min=None, max=None): Set species with min=3 sage: S.structures([1,2]).list() [] - sage: S.generating_series().coefficients(5) + sage: S.generating_series()[0:5] [0, 0, 0, 1/6, 1/24] """ kwargs = {'min': self._min if min is None else min, @@ -431,19 +431,19 @@ def __pow__(self, n): (Singleton species) and (Singleton species)) and (Product of (Singleton species) and (Singleton species))) - sage: (X^2).generating_series().coefficients(4) + sage: (X^2).generating_series()[0:4] [0, 0, 1, 0] - sage: (X^3).generating_series().coefficients(4) + sage: (X^3).generating_series()[0:4] [0, 0, 0, 1] - sage: ((One+X)^3).generating_series().coefficients(4) + sage: ((One+X)^3).generating_series()[0:4] [1, 3, 3, 1] - sage: ((One+X)^7).generating_series().coefficients(8) + sage: ((One+X)^7).generating_series()[0:8] [1, 7, 21, 35, 35, 21, 7, 1] sage: x = QQ[['x']].gen() sage: coeffs = ((1+x+x+x**2)**25+O(x**10)).padded_list() sage: T = ((One+X+X+X^2)^25) - sage: T.generating_series().coefficients(10) == coeffs + sage: T.generating_series()[0:10] == coeffs True sage: X^1 is X True @@ -479,20 +479,20 @@ def _get_series(self, series_ring_class, prefix, base_ring=None): EXAMPLES:: sage: P = species.PermutationSpecies(min=2, max=4) - sage: P.generating_series().coefficients(8) #indirect doctest + sage: P.generating_series()[0:8] #indirect doctest [0, 0, 1, 1, 0, 0, 0, 0] """ series = self._series_helper(series_ring_class, prefix, base_ring=base_ring) - - if self._min is not None: - series = series.parent()(lambda n: series[n], self._min) - if self._max is not None: - series = series.truncate(self._max) # We need to restrict the series based on the min # and max of this species. Note that if min and max # are both None (as in the default case), then the restrict # method will just return series. # return series.restricted(min=self._min, max=self._max) + if self._min is not None: + series = series.parent()(lambda n: series[n], valuation=self._min) + from sage.rings.infinity import Infinity + if self._max is not None and self._max is not Infinity: + series = series.parent()(lambda n: series[n], degree=self._max + 1) return series def _series_helper(self, series_ring_class, prefix, base_ring=None): @@ -625,7 +625,7 @@ def isotype_generating_series(self, base_ring=None): sage: P = species.PermutationSpecies() sage: g = P.isotype_generating_series() - sage: g.coefficients(4) + sage: g[0:4] [1, 1, 2, 3] sage: g.counts(4) [1, 1, 2, 3] @@ -647,7 +647,7 @@ def cycle_index_series(self, base_ring=None): sage: P = species.PermutationSpecies() sage: g = P.cycle_index_series() - sage: g.coefficients(4) + sage: g[0:4] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ return self._get_series(CycleIndexSeriesRing, "cis", base_ring) From eef15d81bb9734c3aaa07b8dc141652b8d9f0b82 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 18 Aug 2021 02:01:08 +0530 Subject: [PATCH 019/350] Changed the name of iterator to callable. --- src/sage/combinat/species/cycle_species.py | 4 ++-- src/sage/combinat/species/linear_order_species.py | 2 +- src/sage/combinat/species/partition_species.py | 4 ++-- src/sage/combinat/species/permutation_species.py | 5 +---- src/sage/combinat/species/set_species.py | 4 +--- src/sage/combinat/species/species.py | 10 +++++----- src/sage/combinat/species/subset_species.py | 6 ++---- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index 891d5e1d2ed..ec3c0b34eee 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -177,7 +177,7 @@ def _isotypes(self, structure_class, labels): if len(labels) != 0: yield structure_class(self, labels, range(1, len(labels)+1)) - def _gs_iterator(self, base_ring, n): + def _gs_callable(self, base_ring, n): r""" The generating series for cyclic permutations is `-\log(1-x) = \sum_{n=1}^\infty x^n/n`. @@ -235,7 +235,7 @@ def _itgs_list(self, base_ring, n): """ return base_ring(0) if n == 0 else self._weight*base_ring(1) - def _cis_iterator(self, base_ring): + def _cis_callable(self, base_ring): r""" The cycle index series of the species of cyclic permutations is given by diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index ca6dbb3f88f..6603849d86a 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -152,7 +152,7 @@ def _itgs_list(self, base_ring, n): return base_ring(1) - def _cis_iterator(self, base_ring): + def _cis_callable(self, base_ring, n): """ EXAMPLES:: diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index 62f1f8aab6e..97a37ea68ea 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -233,7 +233,7 @@ def _canonical_rep_from_partition(self, structure_class, labels, p): breaks = [sum(p[:i]) for i in range(len(p) + 1)] return structure_class(self, labels, [list(range(breaks[i]+1, breaks[i+1]+1)) for i in range(len(p))]) - def _gs_iterator(self, base_ring, n): + def _gs_callable(self, base_ring, n): r""" EXAMPLES:: @@ -245,7 +245,7 @@ def _gs_iterator(self, base_ring, n): from sage.combinat.combinat import bell_number return self._weight * base_ring(bell_number(n) / factorial(n)) - def _itgs_iterator(self, base_ring, n): + def _itgs_callable(self, base_ring, n): r""" The isomorphism type generating series is given by `\frac{1}{1-x}`. diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index faabd035a13..10db8939984 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -201,7 +201,7 @@ def _gs_list(self, base_ring, n): return base_ring(1) - def _itgs_iterator(self, base_ring, n): + def _itgs_callable(self, base_ring, n): r""" The isomorphism type generating series is given by `\frac{1}{1-x}`. @@ -213,9 +213,6 @@ def _itgs_iterator(self, base_ring, n): sage: [g.coefficient(i) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - # from sage.combinat.partition import number_of_partitions - # for n in _integers_from(0): - # yield base_ring(number_of_partitions(n)) from sage.combinat.partition import number_of_partitions return base_ring(number_of_partitions(n)) diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 164fb0fca7e..c0b1feb1fa1 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -130,7 +130,7 @@ def _structures(self, structure_class, labels): _isotypes = _structures - def _gs_iterator(self, base_ring, n): + def _gs_callable(self, base_ring, n): r""" The generating series for the species of sets is given by `e^x`. @@ -144,8 +144,6 @@ def _gs_iterator(self, base_ring, n): sage: [g.count(i) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - # for n in _integers_from(0): - # yield base_ring(self._weight / factorial(n)) return base_ring(self._weight / factorial(n)) def _itgs_list(self, base_ring, n): diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 3cc983d72b4..42308ee9651 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -555,16 +555,16 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): except AttributeError: pass - # Try to return things like self._gs_iterator(base_ring). - # This is used when the subclass just provides an iterator + # Try to return things like self._gs_callable(base_ring). + # This is used when the subclass just provides an callable # for the coefficients of the generating series. Optionally, # the subclass can specify the order of the series. try: - iterator = getattr(self, prefix + "_iterator") + callable = getattr(self, prefix + "_callable") try: - return series_ring(lambda n: iterator(base_ring, n), valuation=self._order()) + return series_ring(lambda n: callable(base_ring, n), valuation=self._order()) except AttributeError: - return series_ring(lambda n: iterator(base_ring, n)) + return series_ring(lambda n: callable(base_ring, n)) except AttributeError: pass diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 20de1520b93..288f7796899 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -187,7 +187,7 @@ def _isotypes(self, structure_class, labels): for i in range(len(labels)+1): yield structure_class(self, labels, range(1, i+1)) - def _gs_iterator(self, base_ring, n): + def _gs_callable(self, base_ring, n): """ The generating series for the species of subsets is `e^{2x}`. @@ -199,10 +199,8 @@ def _gs_iterator(self, base_ring, n): [1, 2, 2, 4/3, 2/3] """ return base_ring(2)**n / base_ring(factorial(n)) - # for n in _integers_from(0): - # yield base_ring(2)**n / base_ring(factorial(n)) - def _itgs_iterator(self, base_ring, n): + def _itgs_callable(self, base_ring, n): r""" The generating series for the species of subsets is `e^{2x}`. From 7d491f6f7deee6cf4755c94442212366a0d96322 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 18 Aug 2021 02:13:36 +0530 Subject: [PATCH 020/350] Raised a not implemented error for all not corrected methods in the generating_series file. --- .../combinat/species/composition_species.py | 2 +- .../combinat/species/generating_series.py | 39 +++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index c9f58731672..a0ca0937137 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -187,7 +187,7 @@ def _isotypes(self, structure_class, labels): raise NotImplementedError - def _gs(self, series_ring, base_ring, n): + def _gs(self, series_ring, base_ring): """ EXAMPLES:: diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 21cc7737330..e61810be9b3 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -248,6 +248,7 @@ def functorial_composition(self, y): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ + raise NotImplementedError() P = self.parent() return P(lambda n: self._functorial_compose_gen(y, n), 0) @@ -273,11 +274,8 @@ def _functorial_compose_gen(self, y, n): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ + raise NotImplementedError() return self.count(y.count(n)) / factorial(n) - # n = 0 - # while True: - # yield self.count(y.count(n)) / factorial(n) - # n += 1 class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): @@ -351,6 +349,7 @@ def count(self, t): sage: f.count([2,1]) 6 """ + raise NotImplementedError() t = Partition(t) return t.aut() * self.coefficient_cycle_type(t) @@ -371,6 +370,7 @@ def coefficient_cycle_type(self, t): sage: f.coefficient_cycle_type([2,1]) 3 """ + raise NotImplementedError() t = Partition(t) p = self.coefficient(t.size()) return p.coefficient(t) @@ -402,6 +402,7 @@ def stretch(self, k): [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] """ # return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) + raise NotImplementedError() P = self.parent() stream = partial(self._stretch_gen, k) return P(next(stream), lambda ao: k*ao) @@ -419,6 +420,7 @@ def _stretch_gen(self, k, ao): sage: [next(g) for i in range(10)] [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] """ + raise NotImplementedError() from sage.combinat.partition import Partition BR = self.base_ring() zero = BR.zero() @@ -444,6 +446,7 @@ def isotype_generating_series(self): sage: f.coefficients(10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ + raise NotImplementedError() R = self.base_ring().base_ring() OGS = OrdinaryGeneratingSeriesRing(R)() return OGS._new(self._ogs_gen, lambda ao: ao, self) @@ -475,6 +478,7 @@ def expand_as_sf(self, n, alphabet='x'): [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] """ + raise NotImplementedError() expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() LPSR = LazyTaylorSeriesRing(expanded_poly_ring) @@ -495,6 +499,7 @@ def _ogs_gen(self, ao): sage: [next(g) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ + raise NotImplementedError() for i in range(ao): yield 0 for i in _integers_from(ao): @@ -510,6 +515,7 @@ def generating_series(self): sage: f.coefficients(5) [1, 1, 1, 5/6, 5/8] """ + raise NotImplementedError() R = self.base_ring().base_ring() EGS = ExponentialGeneratingSeriesRing(R)() return EGS._new(self._egs_gen, lambda ao: ao, self) @@ -527,6 +533,7 @@ def _egs_gen(self, ao): sage: [next(g) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ + raise NotImplementedError() for i in range(ao): yield 0 for i in _integers_from(ao): @@ -562,6 +569,7 @@ def __invert__(self): - Andrew Gainer-Dewar """ + raise NotImplementedError() if self.coefficient(0) == 0: raise ValueError("constant term must be non-zero") @@ -578,6 +586,7 @@ def _div_(self, y): sage: (E / E).coefficients(6) [p[], 0, 0, 0, 0, 0] """ + raise NotImplementedError() return self*(~y) def functorial_composition(self, g): @@ -617,6 +626,7 @@ def functorial_composition(self, g): 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ + raise NotImplementedError() return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) def _functorial_compose_gen(self, g, ao): @@ -640,6 +650,7 @@ def _functorial_compose_gen(self, g, ao): 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ + raise NotImplementedError() p = self.parent().base_ring() n = 0 while True: @@ -709,6 +720,7 @@ def arithmetic_product(self, g, check_input = True): :arxiv:`math/0503436v2`. """ + raise NotImplementedError() from itertools import product, repeat, chain p = self.base_ring() @@ -770,6 +782,7 @@ def _cycle_type(self, s): sage: [cis._cycle_type(p) for p in Partitions(3)] [[1], [1], [1]] """ + raise NotImplementedError() if s == []: return self._card(0) res = [] @@ -801,6 +814,7 @@ def _upper_bound_for_longest_cycle(self, s): sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) 1 """ + raise NotImplementedError() if s == []: return 1 return min(self._card(sum(s)), lcm(list(s))) @@ -818,6 +832,7 @@ def _card(self, n): sage: cis._card(4) 15 """ + raise NotImplementedError() p = self.coefficient(n) return factorial(n) * p.coefficient([1] * n) @@ -838,6 +853,7 @@ def _compose_gen(self, y, ao): sage: [next(g) for i in range(4)] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ + raise NotImplementedError() assert y.coefficient(0) == 0 y_powers = Stream(y._power_gen()) @@ -870,6 +886,7 @@ def _compose_term(self, p, y_powers): sage: E_cis._compose_term(p2, c_powers).coefficients(4) [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] """ + raise NotImplementedError() parent = self.parent() if p == 0: return parent(0) @@ -905,6 +922,7 @@ def weighted_composition(self, y_species): sage: E(C).cycle_index_series().coefficients(4) [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ + raise NotImplementedError() base_ring = self.base_ring() y = y_species.cycle_index_series(base_ring) assert y.coefficient(0) == 0 @@ -923,6 +941,7 @@ def _weighted_compose_gen(self, y_species, ao): sage: [next(g) for i in range(4)] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ + raise NotImplementedError() parent = self.parent() res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) for i in _integers_from(0)) @@ -948,6 +967,7 @@ def _weighted_compose_term(self, p, y_species): sage: E_cis._weighted_compose_term(p2, C).coefficients(4) [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] """ + raise NotImplementedError() parent = self.parent() if p == 0: return parent(0) @@ -1020,6 +1040,7 @@ def compositional_inverse(self): - Andrew Gainer-Dewar """ + raise NotImplementedError() cisr = self.parent() sfa = cisr._base @@ -1063,6 +1084,7 @@ def derivative(self, order=1): True """ # Make sure that order is integral + raise NotImplementedError() order = Integer(order) if order < 0: @@ -1101,6 +1123,7 @@ def pointing(self): True """ + raise NotImplementedError() p1 = self.base_ring()([1]) X = self.parent()([0, p1, 0]) @@ -1155,6 +1178,7 @@ def exponential(self): sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) True """ + raise NotImplementedError() base_ring = self.parent().base_ring().base_ring() E = ExponentialCycleIndexSeries(base_ring) return E.compose(self) @@ -1183,6 +1207,7 @@ def logarithm(self): sage: CG.isotype_generating_series().coefficients(8) [0, 1, 1, 2, 6, 21, 112, 853] """ + raise NotImplementedError() base_ring = self.parent().base_ring().base_ring() Omega = LogarithmCycleIndexSeries(base_ring) return Omega.compose(self) @@ -1263,6 +1288,7 @@ def _exp_term(n, R = RationalField()): sage: [_exp_term(i) for i in range(4)] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ + raise NotImplementedError() p = SymmetricFunctions(R).power() return sum(p(part) / part.aut() for part in Partitions(n)) @@ -1279,6 +1305,7 @@ def _exp_gen(R = RationalField()): sage: [next(g) for i in range(4)] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ + raise NotImplementedError() return (_exp_term(i, R) for i in _integers_from(0)) @cached_function @@ -1301,6 +1328,7 @@ def ExponentialCycleIndexSeries(R = RationalField()): + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] """ + raise NotImplementedError() CIS = CycleIndexSeriesRing(R, 'z') return CIS(_exp_gen(R)) @@ -1317,6 +1345,7 @@ def _cl_term(n, R = RationalField()): sage: [_cl_term(i) for i in range(4)] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ + raise NotImplementedError() n = Integer(n) # check that n is an integer p = SymmetricFunctions(R).power() @@ -1343,6 +1372,7 @@ def _cl_gen (R = RationalField()): sage: [next(g) for i in range(4)] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ + raise NotImplementedError() return (_cl_term(i, R) for i in _integers_from(0)) @@ -1373,6 +1403,7 @@ def LogarithmCycleIndexSeries(R = RationalField()): sage: LogarithmCycleIndexSeries().compose(Eplus).coefficients(4) [0, p[1], 0, 0] """ + raise NotImplementedError() CIS = CycleIndexSeriesRing(R, 'z') return CIS(_cl_gen(R)) From fb1b8c046ef3bda0a62bbdabcef9728084e85857 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 18 Aug 2021 11:22:28 +0200 Subject: [PATCH 021/350] fixes for uninitialized species --- src/sage/combinat/species/composition_species.py | 2 +- src/sage/combinat/species/generating_series.py | 2 -- src/sage/combinat/species/recursive_species.py | 6 +++--- src/sage/combinat/species/species.py | 11 ++++------- src/sage/combinat/species/sum_species.py | 1 - src/sage/rings/lazy_laurent_series_ring.py | 12 +++++++++++- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index a0ca0937137..2dd166f4e91 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -196,7 +196,7 @@ def _gs(self, series_ring, base_ring): sage: L.generating_series()[:5] [1, 1, 1, 1, 1] """ - return self._F.generating_series(base_ring).functorial_composition(self._G.generating_series(base_ring)) + return self._F.generating_series(base_ring)(self._G.generating_series(base_ring)) def _itgs(self, series_ring, base_ring): """ diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index e61810be9b3..6f6ae46a35c 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -248,7 +248,6 @@ def functorial_composition(self, y): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - raise NotImplementedError() P = self.parent() return P(lambda n: self._functorial_compose_gen(y, n), 0) @@ -274,7 +273,6 @@ def _functorial_compose_gen(self, y, n): [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - raise NotImplementedError() return self.count(y.count(n)) / factorial(n) diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 2aad474323c..83c9140cfd3 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -236,7 +236,7 @@ def _gs(self, series_ring, base_ring): Uninitialized lazy power series """ if base_ring not in self._generating_series: - self._generating_series[base_ring] = series_ring() + self._generating_series[base_ring] = series_ring(None) res = self._generating_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): @@ -253,7 +253,7 @@ def _itgs(self, series_ring, base_ring): Uninitialized lazy power series """ if base_ring not in self._isotype_generating_series: - self._isotype_generating_series[base_ring] = series_ring() + self._isotype_generating_series[base_ring] = series_ring(None) res = self._isotype_generating_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): @@ -270,7 +270,7 @@ def _cis(self, series_ring, base_ring): Uninitialized lazy power series """ if base_ring not in self._cycle_index_series: - self._cycle_index_series[base_ring] = series_ring() + self._cycle_index_series[base_ring] = series_ring(None) res = self._cycle_index_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 42308ee9651..78cd6758362 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -487,13 +487,10 @@ def _get_series(self, series_ring_class, prefix, base_ring=None): # and max of this species. Note that if min and max # are both None (as in the default case), then the restrict # method will just return series. - # return series.restricted(min=self._min, max=self._max) - if self._min is not None: - series = series.parent()(lambda n: series[n], valuation=self._min) - from sage.rings.infinity import Infinity - if self._max is not None and self._max is not Infinity: - series = series.parent()(lambda n: series[n], degree=self._max + 1) - return series + if self._min is None and self._max is None: + return series + return series.parent()(lambda n: series[n], + valuation=self._min, degree=self._max) def _series_helper(self, series_ring_class, prefix, base_ring=None): """ diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index a7f0a616fdc..204857baca6 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -147,7 +147,6 @@ def _gs(self, series_ring, base_ring): return (self.left_summand().generating_series(base_ring) + self.right_summand().generating_series(base_ring)) - def _itgs(self, series_ring, base_ring): """ Returns the isomorphism type generating series of this species. diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index 90353026ea3..81c97581b25 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -343,7 +343,7 @@ def _coerce_map_from_base_ring(self): return self._generic_coerce_map(self.base_ring()) def _element_constructor_(self, x=None, valuation=None, constant=None, degree=None): - """ + r""" Construct a Laurent series from ``x``. INPUT: @@ -358,6 +358,9 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No polynomial or is a lazy Laurent series, then the data is shifted so that the result has the specified valuation. + However, if ``x`` is a callable, passing ``valuation`` and ``degree`` + truncates the series appropriately. + EXAMPLES:: sage: L = LazyLaurentSeriesRing(GF(2), 'z') @@ -486,6 +489,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No .. TODO:: Add a method to change the sparse/dense implementation. + """ if x is None: if valuation is None: @@ -1045,6 +1049,10 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No ValueError: coefficients must be homogeneous polynomials of the correct degree """ + if valuation is infinity: + return self.zero() + if degree is infinity: + degree = None if valuation is not None: if valuation < 0: raise ValueError("the valuation of a Taylor series must be positive") @@ -1055,6 +1063,8 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No BR = self.base_ring() if x is None: assert degree is None + if valuation is None: + valuation = 0 coeff_stream = CoefficientStream_uninitialized(self._sparse, valuation) return self.element_class(self, coeff_stream) try: From 4b76e93596f91a5068a5d2dbba31a65f748dea73 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 18 Aug 2021 11:34:12 +0200 Subject: [PATCH 022/350] switch to power sum by default --- src/sage/rings/lazy_laurent_series_ring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index 8513547cf3f..60f15416f29 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -1369,9 +1369,9 @@ def __init__(self, base_ring, names, sparse=True, category=None): self._sparse = sparse n = len(self.variable_names()) if n == 1: - self._coeff_ring = SymmetricFunctions(base_ring).m() + self._coeff_ring = SymmetricFunctions(base_ring).p() else: - self._coeff_ring = tensor([SymmetricFunctions(base_ring).m()]*len(self.variable_names())) + self._coeff_ring = tensor([SymmetricFunctions(base_ring).p()]*len(self.variable_names())) self._laurent_poly_ring = self._coeff_ring def _repr_(self): From 9080a12e3e187e0bf1c5fac60f714990d3030264 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Thu, 19 Aug 2021 23:44:58 +0530 Subject: [PATCH 023/350] Started Cyclic Series. --- .../combinat/species/generating_series.py | 87 ++++++------------- src/sage/combinat/species/library.py | 6 +- src/sage/combinat/species/sum_species.py | 8 +- src/sage/rings/lazy_laurent_series_ring.py | 2 +- 4 files changed, 35 insertions(+), 68 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 6f6ae46a35c..f4873298863 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -77,8 +77,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.lazy_laurent_series import LazyTaylorSeries -from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing +from sage.rings.lazy_laurent_series import LazyTaylorSeries, LazySymmetricFunction +from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing, LazySymmetricFunctions from .stream import Stream, _integers_from from sage.rings.all import Integer, RationalField from sage.arith.all import moebius, gcd, lcm, divisors @@ -328,7 +328,7 @@ def factorial_gen(): n += 1 -class CycleIndexSeries(LazyTaylorSeries): +class CycleIndexSeries(LazySymmetricFunction): def count(self, t): """ Return the number of structures corresponding to a certain cycle @@ -347,7 +347,6 @@ def count(self, t): sage: f.count([2,1]) 6 """ - raise NotImplementedError() t = Partition(t) return t.aut() * self.coefficient_cycle_type(t) @@ -368,7 +367,6 @@ def coefficient_cycle_type(self, t): sage: f.coefficient_cycle_type([2,1]) 3 """ - raise NotImplementedError() t = Partition(t) p = self.coefficient(t.size()) return p.coefficient(t) @@ -400,7 +398,6 @@ def stretch(self, k): [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] """ # return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) - raise NotImplementedError() P = self.parent() stream = partial(self._stretch_gen, k) return P(next(stream), lambda ao: k*ao) @@ -418,7 +415,6 @@ def _stretch_gen(self, k, ao): sage: [next(g) for i in range(10)] [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] """ - raise NotImplementedError() from sage.combinat.partition import Partition BR = self.base_ring() zero = BR.zero() @@ -441,10 +437,9 @@ def isotype_generating_series(self): sage: P = species.PermutationSpecies() sage: cis = P.cycle_index_series() sage: f = cis.isotype_generating_series() - sage: f.coefficients(10] + sage: f[:10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - raise NotImplementedError() R = self.base_ring().base_ring() OGS = OrdinaryGeneratingSeriesRing(R)() return OGS._new(self._ogs_gen, lambda ao: ao, self) @@ -472,11 +467,10 @@ def expand_as_sf(self, n, alphabet='x'): EXAMPLES:: sage: from sage.combinat.species.set_species import SetSpecies - sage: SetSpecies().cycle_index_series().expand_as_sf(2).coefficients(4] + sage: SetSpecies().cycle_index_series().expand_as_sf(2)[:4] [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] """ - raise NotImplementedError() expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() LPSR = LazyTaylorSeriesRing(expanded_poly_ring) @@ -497,7 +491,6 @@ def _ogs_gen(self, ao): sage: [next(g) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - raise NotImplementedError() for i in range(ao): yield 0 for i in _integers_from(ao): @@ -510,10 +503,9 @@ def generating_series(self): sage: P = species.PartitionSpecies() sage: cis = P.cycle_index_series() sage: f = cis.generating_series() - sage: f.coefficients(5) + sage: f[:5] [1, 1, 1, 5/6, 5/8] """ - raise NotImplementedError() R = self.base_ring().base_ring() EGS = ExponentialGeneratingSeriesRing(R)() return EGS._new(self._egs_gen, lambda ao: ao, self) @@ -531,7 +523,6 @@ def _egs_gen(self, ao): sage: [next(g) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - raise NotImplementedError() for i in range(ao): yield 0 for i in _integers_from(ao): @@ -546,7 +537,7 @@ def __invert__(self): EXAMPLES:: sage: E = species.SetSpecies().cycle_index_series() - sage: E.__invert__().coefficients(4) + sage: E.__invert__()[:4] [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] The defining characteristic of the multiplicative inverse `F^{-1}` of @@ -554,7 +545,7 @@ def __invert__(self): (that is, both products with `F` yield the multiplicative identity `1`):: sage: E = species.SetSpecies().cycle_index_series() - sage: (E * ~E).coefficients(6) + sage: (E * ~E)[:6] [p[], 0, 0, 0, 0, 0] REFERENCES: @@ -567,7 +558,6 @@ def __invert__(self): - Andrew Gainer-Dewar """ - raise NotImplementedError() if self.coefficient(0) == 0: raise ValueError("constant term must be non-zero") @@ -581,10 +571,9 @@ def _div_(self, y): TESTS:: sage: E = species.SetSpecies().cycle_index_series() - sage: (E / E).coefficients(6) + sage: (E / E)[:6] [p[], 0, 0, 0, 0, 0] """ - raise NotImplementedError() return self*(~y) def functorial_composition(self, g): @@ -617,14 +606,13 @@ def functorial_composition(self, g): :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: sage: S = species.SimpleGraphSpecies() - sage: S.cycle_index_series().coefficients(5) + sage: S.cycle_index_series()[:5] [p[], p[1], p[1, 1] + p[2], 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ - raise NotImplementedError() return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) def _functorial_compose_gen(self, g, ao): @@ -648,7 +636,6 @@ def _functorial_compose_gen(self, g, ao): 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ - raise NotImplementedError() p = self.parent().base_ring() n = 0 while True: @@ -718,7 +705,6 @@ def arithmetic_product(self, g, check_input = True): :arxiv:`math/0503436v2`. """ - raise NotImplementedError() from itertools import product, repeat, chain p = self.base_ring() @@ -780,7 +766,6 @@ def _cycle_type(self, s): sage: [cis._cycle_type(p) for p in Partitions(3)] [[1], [1], [1]] """ - raise NotImplementedError() if s == []: return self._card(0) res = [] @@ -812,7 +797,6 @@ def _upper_bound_for_longest_cycle(self, s): sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) 1 """ - raise NotImplementedError() if s == []: return 1 return min(self._card(sum(s)), lcm(list(s))) @@ -830,7 +814,6 @@ def _card(self, n): sage: cis._card(4) 15 """ - raise NotImplementedError() p = self.coefficient(n) return factorial(n) * p.coefficient([1] * n) @@ -851,7 +834,6 @@ def _compose_gen(self, y, ao): sage: [next(g) for i in range(4)] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ - raise NotImplementedError() assert y.coefficient(0) == 0 y_powers = Stream(y._power_gen()) @@ -881,10 +863,9 @@ def _compose_term(self, p, y_powers): sage: c_powers = Stream(C_cis._power_gen()) sage: p2 = E_cis.coefficient(2); p2 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._compose_term(p2, c_powers).coefficients(4) + sage: E_cis._compose_term(p2, c_powers)[:4] [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] """ - raise NotImplementedError() parent = self.parent() if p == 0: return parent(0) @@ -915,12 +896,11 @@ def weighted_composition(self, y_species): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: E_cis = E.cycle_index_series() - sage: E_cis.weighted_composition(C).coefficients(4) + sage: E_cis.weighted_composition(C)[:4] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - sage: E(C).cycle_index_series().coefficients(4) + sage: E(C).cycle_index_series()[:4] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ - raise NotImplementedError() base_ring = self.base_ring() y = y_species.cycle_index_series(base_ring) assert y.coefficient(0) == 0 @@ -939,7 +919,6 @@ def _weighted_compose_gen(self, y_species, ao): sage: [next(g) for i in range(4)] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] """ - raise NotImplementedError() parent = self.parent() res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) for i in _integers_from(0)) @@ -962,10 +941,9 @@ def _weighted_compose_term(self, p, y_species): sage: E_cis = E.cycle_index_series() sage: p2 = E_cis.coefficient(2); p2 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._weighted_compose_term(p2, C).coefficients(4) + sage: E_cis._weighted_compose_term(p2, C)[:4] [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] """ - raise NotImplementedError() parent = self.parent() if p == 0: return parent(0) @@ -1000,7 +978,7 @@ def compositional_inverse(self): EXAMPLES:: sage: Eplus = species.SetSpecies(min=1).cycle_index_series() - sage: Eplus(Eplus.compositional_inverse()).coefficients(8) + sage: Eplus(Eplus.compositional_inverse())[:8] [0, p[1], 0, 0, 0, 0, 0, 0] TESTS:: @@ -1038,13 +1016,12 @@ def compositional_inverse(self): - Andrew Gainer-Dewar """ - raise NotImplementedError() cisr = self.parent() sfa = cisr._base X = cisr([0, sfa([1]), 0]) - if self.coefficients(2) != X.coefficients(2): + if self[:2] != X[:2]: raise ValueError('not an invertible series') res = cisr() @@ -1070,7 +1047,7 @@ def derivative(self, order=1): The species `E` of sets satisfies the relationship `E' = E`:: sage: E = species.SetSpecies().cycle_index_series() - sage: E.coefficients(8) == E.derivative().coefficients(8) + sage: E[:8] == E.derivative()[:8] True The species `C` of cyclic orderings and the species `L` of linear @@ -1078,11 +1055,10 @@ def derivative(self, order=1): sage: C = species.CycleSpecies().cycle_index_series() sage: L = species.LinearOrderSpecies().cycle_index_series() - sage: L.coefficients(8) == C.derivative().coefficients(8) + sage: L[:8] == C.derivative()[:8] True """ # Make sure that order is integral - raise NotImplementedError() order = Integer(order) if order < 0: @@ -1117,11 +1093,10 @@ def pointing(self): sage: E = species.SetSpecies().cycle_index_series() sage: X = species.SingletonSpecies().cycle_index_series() - sage: E.pointing().coefficients(8) == (X*E).coefficients(8) + sage: E.pointing()[:8] == (X*E)[:8] True """ - raise NotImplementedError() p1 = self.base_ring()([1]) X = self.parent()([0, p1, 0]) @@ -1143,9 +1118,9 @@ def integral(self, *args): sage: C3 = species.CycleSpecies(size=3).cycle_index_series() sage: X = species.SingletonSpecies().cycle_index_series() - sage: (3*C3).derivative().coefficients(8) == (3*X^2).coefficients(8) + sage: (3*C3).derivative()[:8] == (3*X^2)[:8] True - sage: (X^3).derivative().coefficients(8) == (3*X^2).coefficients(8) + sage: (X^3).derivative()[:8] == (3*X^2)[:8] True .. WARNING:: @@ -1173,10 +1148,9 @@ def exponential(self): sage: BT = species.BinaryTreeSpecies().cycle_index_series() sage: BF = species.BinaryForestSpecies().cycle_index_series() - sage: BT.exponential().isotype_generating_series().coefficients(8) == BF.isotype_generating_series().coefficients(8) + sage: BT.exponential().isotype_generating_series()[:8] == BF.isotype_generating_series()[:8] True """ - raise NotImplementedError() base_ring = self.parent().base_ring().base_ring() E = ExponentialCycleIndexSeries(base_ring) return E.compose(self) @@ -1202,16 +1176,15 @@ def logarithm(self): sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries sage: CG = LogarithmCycleIndexSeries().compose(G) - sage: CG.isotype_generating_series().coefficients(8) + sage: CG.isotype_generating_series()[:8] [0, 1, 1, 2, 6, 21, 112, 853] """ - raise NotImplementedError() base_ring = self.parent().base_ring().base_ring() Omega = LogarithmCycleIndexSeries(base_ring) return Omega.compose(self) -class CycleIndexSeriesRing(LazyTaylorSeriesRing): +class CycleIndexSeriesRing(LazySymmetricFunctions): r""" Return the ring of cycle index series over ``R``. @@ -1286,7 +1259,6 @@ def _exp_term(n, R = RationalField()): sage: [_exp_term(i) for i in range(4)] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ - raise NotImplementedError() p = SymmetricFunctions(R).power() return sum(p(part) / part.aut() for part in Partitions(n)) @@ -1303,7 +1275,6 @@ def _exp_gen(R = RationalField()): sage: [next(g) for i in range(4)] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ - raise NotImplementedError() return (_exp_term(i, R) for i in _integers_from(0)) @cached_function @@ -1321,12 +1292,11 @@ def ExponentialCycleIndexSeries(R = RationalField()): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries - sage: ExponentialCycleIndexSeries().coefficients(5) + sage: ExponentialCycleIndexSeries()[:5] [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] """ - raise NotImplementedError() CIS = CycleIndexSeriesRing(R, 'z') return CIS(_exp_gen(R)) @@ -1343,7 +1313,6 @@ def _cl_term(n, R = RationalField()): sage: [_cl_term(i) for i in range(4)] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ - raise NotImplementedError() n = Integer(n) # check that n is an integer p = SymmetricFunctions(R).power() @@ -1370,7 +1339,6 @@ def _cl_gen (R = RationalField()): sage: [next(g) for i in range(4)] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ - raise NotImplementedError() return (_cl_term(i, R) for i in _integers_from(0)) @@ -1390,7 +1358,7 @@ def LogarithmCycleIndexSeries(R = RationalField()): its cycle index has negative coefficients:: sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: LogarithmCycleIndexSeries().coefficients(4) + sage: LogarithmCycleIndexSeries()[:4] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` @@ -1398,10 +1366,9 @@ def LogarithmCycleIndexSeries(R = RationalField()): multiplicative identity `X`):: sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries().compose(Eplus).coefficients(4) + sage: LogarithmCycleIndexSeries().compose(Eplus)[:4] [0, p[1], 0, 0] """ - raise NotImplementedError() CIS = CycleIndexSeriesRing(R, 'z') return CIS(_cl_gen(R)) diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index c107edbfa33..cade34fcaca 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -42,13 +42,13 @@ def SimpleGraphSpecies(): sage: S = species.SimpleGraphSpecies() sage: S.generating_series().counts(10) [1, 1, 2, 8, 64, 1024, 32768, 2097152, 268435456, 68719476736] - sage: S.cycle_index_series().coefficients(5) + sage: S.cycle_index_series()[:5] [p[], p[1], p[1, 1] + p[2], 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - sage: S.isotype_generating_series().coefficients(6) + sage: S.isotype_generating_series()[:6] [1, 1, 2, 4, 11, 34] TESTS:: @@ -121,7 +121,7 @@ def BinaryForestSpecies(): [1, 1, 3, 19, 193, 2721, 49171, 1084483, 28245729, 848456353] sage: F.isotype_generating_series().counts(10) [1, 1, 2, 4, 10, 26, 77, 235, 758, 2504] - sage: F.cycle_index_series().coefficients(7) + sage: F.cycle_index_series()[:7] [p[], p[1], 3/2*p[1, 1] + 1/2*p[2], diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index 204857baca6..95a6be6875a 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -32,7 +32,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: S = species.PermutationSpecies() sage: A = S+S - sage: A.generating_series().coefficients(5) + sage: A.generating_series()[:5] [2, 2, 2, 2, 2] sage: P = species.PermutationSpecies() @@ -141,7 +141,7 @@ def _gs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.generating_series().coefficients(5) + sage: F.generating_series()[:5] [2, 2, 2, 2, 2] """ return (self.left_summand().generating_series(base_ring) + @@ -155,7 +155,7 @@ def _itgs(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.isotype_generating_series().coefficients(5) + sage: F.isotype_generating_series()[:5] [2, 2, 4, 6, 10] """ return (self.left_summand().isotype_generating_series(base_ring) + @@ -169,7 +169,7 @@ def _cis(self, series_ring, base_ring): sage: P = species.PermutationSpecies() sage: F = P + P - sage: F.cycle_index_series().coefficients(5) + sage: F.cycle_index_series()[:5] [2*p[], 2*p[1], 2*p[1, 1] + 2*p[2], diff --git a/src/sage/rings/lazy_laurent_series_ring.py b/src/sage/rings/lazy_laurent_series_ring.py index 60f15416f29..227d097455b 100644 --- a/src/sage/rings/lazy_laurent_series_ring.py +++ b/src/sage/rings/lazy_laurent_series_ring.py @@ -1343,7 +1343,7 @@ class LazySymmetricFunctions(UniqueRepresentation, Parent): """ Element = LazySymmetricFunction - def __init__(self, base_ring, names, sparse=True, category=None): + def __init__(self, base_ring, names='z', sparse=True, category=None): """ Initialize ``self``. From 48e8e2686f68a911c5a705b91971e0f3d5924113 Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Wed, 25 Aug 2021 01:47:34 +0530 Subject: [PATCH 024/350] Changed more methods. --- .../combinat/species/composition_species.py | 1 + src/sage/combinat/species/cycle_species.py | 16 ++--- .../species/functorial_composition_species.py | 2 +- .../combinat/species/generating_series.py | 68 +++++++++---------- .../combinat/species/linear_order_species.py | 3 +- .../combinat/species/partition_species.py | 2 +- .../combinat/species/permutation_species.py | 26 +++---- .../combinat/species/recursive_species.py | 6 +- 8 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index 2dd166f4e91..56736f7bc6a 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -207,6 +207,7 @@ def _itgs(self, series_ring, base_ring): sage: L.isotype_generating_series()[:10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ + raise NotImplementedError() cis = self.cycle_index_series(base_ring) return cis.isotype_generating_series() diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index ec3c0b34eee..8df2f2ea393 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -235,7 +235,7 @@ def _itgs_list(self, base_ring, n): """ return base_ring(0) if n == 0 else self._weight*base_ring(1) - def _cis_callable(self, base_ring): + def _cis_callable(self, base_ring, n): r""" The cycle index series of the species of cyclic permutations is given by @@ -271,13 +271,13 @@ def _cis_callable(self, base_ring): zero = base_ring(0) - yield zero - for n in _integers_from(1): - res = zero - for k in divisors(n): - res += euler_phi(k)*p([k])**(n//k) - res /= n - yield self._weight*res + if n == 0: + return zero + res = zero + for k in divisors(n): + res += euler_phi(k)*p([k])**(n//k) + res /= n + return self._weight * res #Backward compatibility CycleSpecies_class = CycleSpecies diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index 7eb3c2c399b..a92797d6727 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -113,7 +113,7 @@ def _cis(self, series_ring, base_ring): EXAMPLES:: sage: G = species.SimpleGraphSpecies() - sage: G.cycle_index_series()[0:5) + sage: G.cycle_index_series()[0:5] [p[], p[1], p[1, 1] + p[2], diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index f4873298863..984cbe6522e 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -397,12 +397,10 @@ def stretch(self, k): sage: f.stretch(3)[0:10] [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] """ - # return self._new(partial(self._stretch_gen, k), lambda ao: k*ao, self) P = self.parent() - stream = partial(self._stretch_gen, k) - return P(next(stream), lambda ao: k*ao) + return P(lambda n: self._stretch_gen(k, n), k * self._coeff_stream._approximate_order) - def _stretch_gen(self, k, ao): + def _stretch_gen(self, k, n): """ EXAMPLES:: @@ -411,8 +409,7 @@ def _stretch_gen(self, k, ao): sage: CIS = CycleIndexSeriesRing(QQ, 'z') sage: f = CIS([p([1])]) # This is the power series whose all coefficients ....: # are p[1]. Not combinatorially meaningful! - sage: g = f._stretch_gen(2,0) - sage: [next(g) for i in range(10)] + sage: [f._stretch_gen(2, i) for i in range(10)] [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] """ from sage.combinat.partition import Partition @@ -421,14 +418,11 @@ def _stretch_gen(self, k, ao): stretch_k = lambda p: Partition([k*i for i in p]) - yield self.coefficient(0).map_support(stretch_k) - - n = 1 - while True: - for i in range(k-1): - yield zero - yield self.coefficient(n).map_support(stretch_k) - n += 1 + if n == 0: + return self.coefficient(0).map_support(stretch_k) + elif n % k: + return zero + return self.coefficient(n//k).map_support(stretch_k) def isotype_generating_series(self): """ @@ -441,8 +435,8 @@ def isotype_generating_series(self): [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ R = self.base_ring().base_ring() - OGS = OrdinaryGeneratingSeriesRing(R)() - return OGS._new(self._ogs_gen, lambda ao: ao, self) + OGS = OrdinaryGeneratingSeriesRing(R, 'z') + return OGS(lambda n: self._ogs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) def expand_as_sf(self, n, alphabet='x'): """ @@ -478,7 +472,7 @@ def expand_as_sf(self, n, alphabet='x'): return LPSR.sum_generator(expander_gen) - def _ogs_gen(self, ao): + def _ogs_gen(self, n, ao): """ Returns a generator for the coefficients of the ordinary generating series obtained from a cycle index series. @@ -487,14 +481,16 @@ def _ogs_gen(self, ao): sage: P = species.PermutationSpecies() sage: cis = P.cycle_index_series() - sage: g = cis._ogs_gen(0) - sage: [next(g) for i in range(10)] + sage: [cis._ogs_gen(i, 0) for i in range(10)] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield sum( self.coefficient(i).coefficients() ) + if n < ao: + return 0 + return sum(self.coefficient(n).coefficients()) + # for i in range(ao): + # yield 0 + # for i in _integers_from(ao): + # yield sum( self.coefficient(i).coefficients() ) def generating_series(self): """ @@ -1263,19 +1259,20 @@ def _exp_term(n, R = RationalField()): return sum(p(part) / part.aut() for part in Partitions(n)) -def _exp_gen(R = RationalField()): - r""" - Produce a generator which yields the terms of the cycle index - series of the species `E` of sets. +# def _exp_gen(n, R = RationalField()): +# r""" +# Produce a generator which yields the terms of the cycle index +# series of the species `E` of sets. - EXAMPLES:: +# EXAMPLES:: - sage: from sage.combinat.species.generating_series import _exp_gen - sage: g = _exp_gen() - sage: [next(g) for i in range(4)] - [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] - """ - return (_exp_term(i, R) for i in _integers_from(0)) +# sage: from sage.combinat.species.generating_series import _exp_gen +# sage: g = _exp_gen() +# sage: [next(g) for i in range(4)] +# [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] +# """ +# return (_exp_term(i) for i in range(n)) + # return (_exp_term(i, R) for i in _integers_from(0)) @cached_function def ExponentialCycleIndexSeries(R = RationalField()): @@ -1298,7 +1295,8 @@ def ExponentialCycleIndexSeries(R = RationalField()): + 1/3*p[3, 1] + 1/4*p[4]] """ CIS = CycleIndexSeriesRing(R, 'z') - return CIS(_exp_gen(R)) + return CIS(lambda n: _exp_term(n)) + # return CIS(_exp_gen(R)) @cached_function diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 6603849d86a..2b8a9540b8a 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -163,8 +163,7 @@ def _cis_callable(self, base_ring, n): """ from sage.combinat.sf.sf import SymmetricFunctions p = SymmetricFunctions(base_ring).power() - for n in _integers_from(0): - yield p([1]*n) + return p([1]*n) #Backward compatibility LinearOrderSpecies_class = LinearOrderSpecies diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index 97a37ea68ea..63ee0a85bd1 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -282,7 +282,7 @@ def _cis(self, series_ring, base_ring): 5/8*p[1, 1, 1, 1] + 7/4*p[2, 1, 1] + 7/8*p[2, 2] + p[3, 1] + 3/4*p[4]] """ ciset = SetSpecies().cycle_index_series(base_ring) - res = ciset.composition(ciset - 1) + res = ciset(ciset - 1) if self.is_weighted(): res *= self._weight return res diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index 10db8939984..1cbac2c5521 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -241,27 +241,29 @@ def _cis(self, series_ring, base_ring): CIS = series_ring return CIS.product_generator( CIS(self._cis_gen(base_ring, i)) for i in _integers_from(ZZ(1)) ) - def _cis_gen(self, base_ring, n): + def _cis_gen(self, base_ring, m, n): """ EXAMPLES:: sage: P = species.PermutationSpecies() - sage: g = P._cis_gen(QQ, 2) - sage: [next(g) for i in range(10)] + sage: [P._cis_gen(QQ, 2, i) for i in range(10)] [p[], 0, p[2], 0, p[2, 2], 0, p[2, 2, 2], 0, p[2, 2, 2, 2], 0] """ from sage.combinat.sf.sf import SymmetricFunctions p = SymmetricFunctions(base_ring).power() - pn = p([n]) - - n = n - 1 - yield p(1) - - for k in _integers_from(1): - for i in range(n): - yield base_ring(0) - yield pn**k + pn = p([m]) + + if n == 0: + return p(1) + if m == 1: + if n % 2: + return base_ring(0) + else: + return pn**(n//2) + elif n % m: + return base_ring(0) + return pn**(n//m) #Backward compatibility PermutationSpecies_class = PermutationSpecies diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 83c9140cfd3..8519f062774 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -233,7 +233,7 @@ def _gs(self, series_ring, base_ring): sage: F = CombinatorialSpecies() sage: F.generating_series() - Uninitialized lazy power series + Uninitialized Lazy Laurent Series """ if base_ring not in self._generating_series: self._generating_series[base_ring] = series_ring(None) @@ -250,7 +250,7 @@ def _itgs(self, series_ring, base_ring): sage: F = CombinatorialSpecies() sage: F.isotype_generating_series() - Uninitialized lazy power series + Uninitialized Lazy Laurent Series """ if base_ring not in self._isotype_generating_series: self._isotype_generating_series[base_ring] = series_ring(None) @@ -267,7 +267,7 @@ def _cis(self, series_ring, base_ring): sage: F = CombinatorialSpecies() sage: F.cycle_index_series() - Uninitialized lazy power series + Uninitialized Lazy Laurent Series """ if base_ring not in self._cycle_index_series: self._cycle_index_series[base_ring] = series_ring(None) From 78a85aeeaeabf44e6a6ebd9c58a486cebf373eca Mon Sep 17 00:00:00 2001 From: tejasvicsr1 Date: Thu, 26 Aug 2021 00:17:13 +0530 Subject: [PATCH 025/350] Some more work in generating series. --- .../combinat/species/generating_series.py | 109 ++++++++---------- 1 file changed, 48 insertions(+), 61 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 984cbe6522e..ef814a789bf 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -503,10 +503,10 @@ def generating_series(self): [1, 1, 1, 5/6, 5/8] """ R = self.base_ring().base_ring() - EGS = ExponentialGeneratingSeriesRing(R)() - return EGS._new(self._egs_gen, lambda ao: ao, self) + EGS = ExponentialGeneratingSeriesRing(R, 'z') + return EGS(lambda n: self._egs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) - def _egs_gen(self, ao): + def _egs_gen(self, n, ao): """ Returns a generator for the coefficients of the exponential generating series obtained from a cycle index series. @@ -515,14 +515,12 @@ def _egs_gen(self, ao): sage: P = species.PermutationSpecies() sage: cis = P.cycle_index_series() - sage: g = cis._egs_gen(0) - sage: [next(g) for i in range(10)] + sage: [cis._egs_gen(i, 0) for i in range(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - for i in range(ao): - yield 0 - for i in _integers_from(ao): - yield self.coefficient(i).coefficient([1]*i) + if n < ao: + return 0 + return self.coefficient(n).coefficient([1]*n) def __invert__(self): r""" @@ -609,9 +607,11 @@ def functorial_composition(self, g): 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ - return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) + # return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) + P = self.parent() + return P(lambda n: self._functorial_compose_gen(g, n, self._coeff_stream._approximate_order), 0) - def _functorial_compose_gen(self, g, ao): + def _functorial_compose_gen(self, g, n, ao): """ Return a generator for the coefficients of the functorial composition of ``self`` with ``g``. @@ -624,8 +624,7 @@ def _functorial_compose_gen(self, g, ao): sage: P2 = E2*E sage: P2_cis = P2.cycle_index_series() sage: WP_cis = WP.cycle_index_series() - sage: g = WP_cis._functorial_compose_gen(P2_cis,0) - sage: [next(g) for i in range(5)] + sage: [WP_cis._functorial_compose_gen(P2_cis, i, 0) for i in range(5)] [p[], p[1], p[1, 1] + p[2], @@ -633,15 +632,35 @@ def _functorial_compose_gen(self, g, ao): 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] """ p = self.parent().base_ring() - n = 0 - while True: - res = p(0) - for s in Partitions(n): - t = g._cycle_type(s) - q = self.count(t) / s.aut() - res += q*p(s) - yield res - n += 1 + res = p(0) + print(n) + print(res) + for s in Partitions(n): + print(s) + t = g._cycle_type(s) + print(t) + q = self.count(t) / s.aut() + print(q) + res += q * p(s) + print(res) + return res + # p = self.parent().base_ring() + # m = 0 + # print(p) + # print(m) + # while True: + # res = p(0) + # print(res) + # for s in Partitions(m): + # print(s) + # t = g._cycle_type(s) + # print(t) + # q = self.count(t) / s.aut() + # print(q) + # res += q*p(s) + # print(res) + # yield res + # m += 1 def arithmetic_product(self, g, check_input = True): r""" @@ -949,7 +968,7 @@ def _weighted_compose_term(self, p, y_species): res = [] #Go through all the partition, coefficient pairs in the term p for m, c in p: - res_t = parent.term(c, 0) + res_t = parent(c, 0) for e,v in enumerate(m.to_exp()): if v == 0: @@ -1021,7 +1040,8 @@ def compositional_inverse(self): raise ValueError('not an invertible series') res = cisr() - res.define(X - (self - X).compose(res)) + # res.define(X - (self - X).compose(res)) + res.define(X - (self - X)(res)) return res @@ -1149,7 +1169,7 @@ def exponential(self): """ base_ring = self.parent().base_ring().base_ring() E = ExponentialCycleIndexSeries(base_ring) - return E.compose(self) + return E(self) def logarithm(self): r""" @@ -1177,7 +1197,7 @@ def logarithm(self): """ base_ring = self.parent().base_ring().base_ring() Omega = LogarithmCycleIndexSeries(base_ring) - return Omega.compose(self) + return Omega(self) class CycleIndexSeriesRing(LazySymmetricFunctions): @@ -1259,21 +1279,6 @@ def _exp_term(n, R = RationalField()): return sum(p(part) / part.aut() for part in Partitions(n)) -# def _exp_gen(n, R = RationalField()): -# r""" -# Produce a generator which yields the terms of the cycle index -# series of the species `E` of sets. - -# EXAMPLES:: - -# sage: from sage.combinat.species.generating_series import _exp_gen -# sage: g = _exp_gen() -# sage: [next(g) for i in range(4)] -# [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] -# """ -# return (_exp_term(i) for i in range(n)) - # return (_exp_term(i, R) for i in _integers_from(0)) - @cached_function def ExponentialCycleIndexSeries(R = RationalField()): r""" @@ -1296,7 +1301,6 @@ def ExponentialCycleIndexSeries(R = RationalField()): """ CIS = CycleIndexSeriesRing(R, 'z') return CIS(lambda n: _exp_term(n)) - # return CIS(_exp_gen(R)) @cached_function @@ -1323,23 +1327,6 @@ def _cl_term(n, R = RationalField()): return res - -def _cl_gen (R = RationalField()): - r""" - Produce a generator which yields the terms of the cycle index series - of the virtual species `\Omega`, the compositional inverse of the - species `E^{+}` of nonempty sets. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import _cl_gen - sage: g = _cl_gen() - sage: [next(g) for i in range(4)] - [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] - """ - return (_cl_term(i, R) for i in _integers_from(0)) - - @cached_function def LogarithmCycleIndexSeries(R = RationalField()): r""" @@ -1364,9 +1351,9 @@ def LogarithmCycleIndexSeries(R = RationalField()): multiplicative identity `X`):: sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries().compose(Eplus)[:4] + sage: LogarithmCycleIndexSeries()(Eplus)[:4] [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R, 'z') - return CIS(_cl_gen(R)) + return CIS(lambda n: _cl_term(n)) From 3bc14de3f2f2fae26b62fa4d6d7e4ab6be32b9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 7 Apr 2022 18:03:48 +0200 Subject: [PATCH 026/350] 33680: moving _repr_fixups from module header to method do_fixup --- src/sage/doctest/parsing.py | 51 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index d2939218bb9..ce1fa521e45 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -104,26 +104,6 @@ def fake_RIFtol(*args): ansi_escape_sequence = re.compile(r'(\x1b[@-Z\\-~]|\x1b\[.*?[@-~]|\x9b.*?[@-~])') -# Collection of fixups applied in the SageOutputChecker. Each element in this -# this list a pair of functions applied to the actual test output ('g' for -# "got") and the expected test output ('w' for "wanted"). The first function -# should be a simple fast test on the expected and/or actual output to -# determine if a fixup should be applied. The second function is the actual -# fixup, which is applied if the test function passes. In most fixups only one -# of the expected or received outputs are normalized, depending on the -# application. -_repr_fixups = [ - (lambda g, w: "Long-step" in g, - lambda g, w: (glpk_simplex_warning_regex.sub('', g), w)), - - (lambda g, w: "dylib" in g, - lambda g, w: (ld_warning_regex.sub('', g), w)), - - (lambda g, w: "pie being ignored" in g, - lambda g, w: (ld_pie_warning_regex.sub('', g), w)) -] - - def parse_optional_tags(string): """ Return a set consisting of the optional tags from the following @@ -984,10 +964,18 @@ def do_fixup(self, want, got): A tuple: - - bool, True when some fixup were performed - - string, (unchanged) wanted string + - bool, ``True`` when some fixup were performed and ``False`` otherwise + - string, edited wanted string - string, edited got string + .. NOTE:: + + Currently, the code only possibly changes the string ``got`` + while keeping ``want`` invariant. We keep open the possibility + of adding a regular expression which would also change the + ``want`` string. This is why ``want`` is an input and an output + of the method even if currently kept invariant. + EXAMPLES:: sage: from sage.doctest.parsing import SageOutputChecker @@ -1020,11 +1008,20 @@ def do_fixup(self, want, got): """ did_fixup = False - for quick_check, fixup in _repr_fixups: - do_fixup = quick_check(got, want) - if do_fixup: - got, want = fixup(got, want) - did_fixup = True + # The conditions in the below `if` are simple fast test on the expected + # and/or actual output to determine if a fixup should be applied. + + if "Long-step" in got: + got = glpk_simplex_warning_regex.sub('', got) + did_fixup = True + + if "dylib" in got: + got = ld_warning_regex.sub('', got) + did_fixup = True + + if "pie being ignored" in got: + got = ld_pie_warning_regex.sub('', got) + did_fixup = True return did_fixup, want, got From 805f235c59a29d23d7470674e941b6bf79a75e39 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 11:30:51 -0800 Subject: [PATCH 027/350] build/bin/sage-site --package: Quoting fix --- build/bin/sage-site | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-site b/build/bin/sage-site index b496a3653e6..4fcbdb233c2 100755 --- a/build/bin/sage-site +++ b/build/bin/sage-site @@ -98,7 +98,7 @@ fi if [ "$1" = '-package' -o "$1" = "--package" ]; then shift - exec sage-package $@ + exec sage-package "$@" fi if [ "$1" = '-optional' -o "$1" = "--optional" ]; then From 5ec7f5c21c369b66eaa08c5a9e778226c3d27e00 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 11:50:30 -0800 Subject: [PATCH 028/350] build/pkgs/antic: New --- build/pkgs/antic/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/antic/checksums.ini | 5 +++++ build/pkgs/antic/package-version.txt | 1 + build/pkgs/antic/spkg-install.in | 19 +++++++++++++++++++ build/pkgs/antic/type | 1 + 5 files changed, 44 insertions(+) create mode 100644 build/pkgs/antic/SPKG.rst create mode 100644 build/pkgs/antic/checksums.ini create mode 100644 build/pkgs/antic/package-version.txt create mode 100644 build/pkgs/antic/spkg-install.in create mode 100644 build/pkgs/antic/type diff --git a/build/pkgs/antic/SPKG.rst b/build/pkgs/antic/SPKG.rst new file mode 100644 index 00000000000..d6c32377957 --- /dev/null +++ b/build/pkgs/antic/SPKG.rst @@ -0,0 +1,18 @@ +antic: Algebraic Number Theory In C +=================================== + +Description +----------- + +Algebraic Number Theory In C + +License +------- + +LGPL 2.1 + +Upstream Contact +---------------- + +https://github.com/wbhart/antic + diff --git a/build/pkgs/antic/checksums.ini b/build/pkgs/antic/checksums.ini new file mode 100644 index 00000000000..c09176c7177 --- /dev/null +++ b/build/pkgs/antic/checksums.ini @@ -0,0 +1,5 @@ +tarball=antic-VERSION.tar.gz +sha1=4a377a3679310e5530a4c7effc5247d523e243ee +md5=278efbf95645a43e81651605bc4e02dd +cksum=2671916781 +upstream_url=https://github.com/wbhart/antic/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/antic/package-version.txt b/build/pkgs/antic/package-version.txt new file mode 100644 index 00000000000..abd410582de --- /dev/null +++ b/build/pkgs/antic/package-version.txt @@ -0,0 +1 @@ +0.2.4 diff --git a/build/pkgs/antic/spkg-install.in b/build/pkgs/antic/spkg-install.in new file mode 100644 index 00000000000..c57fa884a20 --- /dev/null +++ b/build/pkgs/antic/spkg-install.in @@ -0,0 +1,19 @@ +cd src + +# Copied from build/pkgs/flint/spkg-install.in: +# Trac #29607: We must always supply --with-gmp, --with-mpfr, +# --with-ntl because otherwise FLINT's configure script uses +# /usr/local, which is always wrong. +# This is why we do not use $SAGE_CONFIGURE_GMP etc. here. +# The value $SAGE_LOCAL is always a safe choice even if the library +# is coming from the system and is found using what is in +# LIBRARY_PATH or LDFLAGS etc. +./configure \ + --disable-static \ + --prefix="$SAGE_LOCAL" \ + --with-gmp="$SAGE_LOCAL" \ + --with-mpfr="$SAGE_LOCAL" \ + --with-flint="$SAGE_LOCAL" || sdh_die "Error: Failed to configure antic." + +sdh_make verbose +sdh_make_install diff --git a/build/pkgs/antic/type b/build/pkgs/antic/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/antic/type @@ -0,0 +1 @@ +optional From dbde68dd1fdc60e0fea7fb58f313f039581047c5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 11:57:24 -0800 Subject: [PATCH 029/350] build/pkgs/antic/dependencies: New --- build/pkgs/antic/dependencies | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 build/pkgs/antic/dependencies diff --git a/build/pkgs/antic/dependencies b/build/pkgs/antic/dependencies new file mode 100644 index 00000000000..c95d2836ce5 --- /dev/null +++ b/build/pkgs/antic/dependencies @@ -0,0 +1,4 @@ +$(MP_LIBRARY) mpfr flint + +---------- +All lines of this file are ignored except the first. From fa3917b1df5c1fbcd0b7766bf4642832ad9c95a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 11:58:35 -0800 Subject: [PATCH 030/350] build/pkgs/e_antic: Update to 1.0.3 --- build/pkgs/e_antic/checksums.ini | 8 ++++---- build/pkgs/e_antic/dependencies | 3 +-- build/pkgs/e_antic/package-version.txt | 2 +- build/pkgs/e_antic/spkg-install.in | 8 ++------ 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/build/pkgs/e_antic/checksums.ini b/build/pkgs/e_antic/checksums.ini index 15e0fcd9a9d..d1d90e998b8 100644 --- a/build/pkgs/e_antic/checksums.ini +++ b/build/pkgs/e_antic/checksums.ini @@ -1,5 +1,5 @@ tarball=e-antic-VERSION.tar.gz -sha1=f51d90fcffb2c849eebc1013eb14984f9ad59719 -md5=84ab45f0e1eb3ddbbfb175927506b7bc -cksum=3161097188 -upstream_url=https://www.labri.fr/perso/vdelecro/e-antic/e-antic-VERSION.tar.gz +sha1=21160cdc6e12386f10d30fd3d44af0c330a68607 +md5=a51f9214f18417f10654a1fd2f069947 +cksum=2360264573 +upstream_url=https://github.com/flatsurf/e-antic/releases/download/VERSION/e-antic-VERSION.tar.gz diff --git a/build/pkgs/e_antic/dependencies b/build/pkgs/e_antic/dependencies index 895cffa0013..fea1ffbda45 100644 --- a/build/pkgs/e_antic/dependencies +++ b/build/pkgs/e_antic/dependencies @@ -1,5 +1,4 @@ -$(MP_LIBRARY) flint arb +$(MP_LIBRARY) flint arb antic boost_cropped ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/e_antic/package-version.txt b/build/pkgs/e_antic/package-version.txt index 1a030947e83..21e8796a09d 100644 --- a/build/pkgs/e_antic/package-version.txt +++ b/build/pkgs/e_antic/package-version.txt @@ -1 +1 @@ -0.1.9 +1.0.3 diff --git a/build/pkgs/e_antic/spkg-install.in b/build/pkgs/e_antic/spkg-install.in index 0c0f5d01a1f..fcaf76055b3 100644 --- a/build/pkgs/e_antic/spkg-install.in +++ b/build/pkgs/e_antic/spkg-install.in @@ -1,10 +1,6 @@ -############################################################################### -# -# e-antic Sage install script -# -############################################################################### cd src -sdh_configure +# Following https://github.com/Normaliz/Normaliz/blob/master/install_scripts_opt/install_nmz_e-antic.sh +sdh_configure --without-byexample --without-doc --without-benchmark --without-pyeantic sdh_make sdh_make_install From 8554b71fa60cd90716387ada419bb338c0188089 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 12:10:13 -0800 Subject: [PATCH 031/350] build/pkgs/normaliz: Update to 3.9.2 --- build/pkgs/normaliz/checksums.ini | 6 +++--- build/pkgs/normaliz/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/normaliz/checksums.ini b/build/pkgs/normaliz/checksums.ini index c3afbfb2656..092b4fc3273 100644 --- a/build/pkgs/normaliz/checksums.ini +++ b/build/pkgs/normaliz/checksums.ini @@ -1,5 +1,5 @@ tarball=normaliz-VERSION.tar.gz -sha1=7486d046c5e8e352d6d7c3544a0e6a1164e9b1fd -md5=136edc12b5c027bb1a019e06fb8d9113 -cksum=1640404889 +sha1=5cb40fc45f25c460df1662dd23c0bd3a9ac9a979 +md5=63c85df072d72e3feea542d47b406d5f +cksum=4133496545 upstream_url=https://github.com/Normaliz/Normaliz/releases/download/vVERSION/normaliz-VERSION.tar.gz diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt index d20cc2bf020..2009c7dfad9 100644 --- a/build/pkgs/normaliz/package-version.txt +++ b/build/pkgs/normaliz/package-version.txt @@ -1 +1 @@ -3.8.10 +3.9.2 From 8f828caef6fc8d9f80108f49de429fd7bc281914 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 8 Feb 2022 12:14:31 -0800 Subject: [PATCH 032/350] build/pkgs/pynormaliz: Update to 2.16 --- build/pkgs/pynormaliz/checksums.ini | 6 +++--- build/pkgs/pynormaliz/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pynormaliz/checksums.ini b/build/pkgs/pynormaliz/checksums.ini index a7e0febfe80..9de8075164f 100644 --- a/build/pkgs/pynormaliz/checksums.ini +++ b/build/pkgs/pynormaliz/checksums.ini @@ -1,5 +1,5 @@ tarball=PyNormaliz-VERSION.tar.gz -sha1=f24f5c4a1b9b7a084ad1f2a0b95374d1a83e31b2 -md5=51e67733702d6cea3cd81144888d9dc7 -cksum=3201946747 +sha1=e383bde810a9337900d9e69f0683b6b387535508 +md5=e581e8ce0da928b1bf9dcc923165c940 +cksum=2627754172 upstream_url=https://pypi.io/packages/source/p/pynormaliz/PyNormaliz-VERSION.tar.gz diff --git a/build/pkgs/pynormaliz/package-version.txt b/build/pkgs/pynormaliz/package-version.txt index 123a39a8e91..6d28a11dd0e 100644 --- a/build/pkgs/pynormaliz/package-version.txt +++ b/build/pkgs/pynormaliz/package-version.txt @@ -1 +1 @@ -2.14 +2.16 From 1fc7373b841ae0e2cd0646983fb435b279dbff81 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 13 May 2022 15:10:47 -0700 Subject: [PATCH 033/350] build/pkgs/e_antic: Update to 1.2.0 --- build/pkgs/e_antic/checksums.ini | 6 +++--- build/pkgs/e_antic/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/e_antic/checksums.ini b/build/pkgs/e_antic/checksums.ini index d1d90e998b8..beeb8780bcd 100644 --- a/build/pkgs/e_antic/checksums.ini +++ b/build/pkgs/e_antic/checksums.ini @@ -1,5 +1,5 @@ tarball=e-antic-VERSION.tar.gz -sha1=21160cdc6e12386f10d30fd3d44af0c330a68607 -md5=a51f9214f18417f10654a1fd2f069947 -cksum=2360264573 +sha1=c22e7b4306d1a53e4dba514cc53fb26654ee1cc6 +md5=1e56c1de2bb535b746601494978987fa +cksum=2460371789 upstream_url=https://github.com/flatsurf/e-antic/releases/download/VERSION/e-antic-VERSION.tar.gz diff --git a/build/pkgs/e_antic/package-version.txt b/build/pkgs/e_antic/package-version.txt index 21e8796a09d..26aaba0e866 100644 --- a/build/pkgs/e_antic/package-version.txt +++ b/build/pkgs/e_antic/package-version.txt @@ -1 +1 @@ -1.0.3 +1.2.0 From 7a817091e9367a20bfe56810184b809250926642 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 13 May 2022 15:12:41 -0700 Subject: [PATCH 034/350] build/pkgs/normaliz: Update to 3.9.3 --- build/pkgs/normaliz/checksums.ini | 6 +++--- build/pkgs/normaliz/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/normaliz/checksums.ini b/build/pkgs/normaliz/checksums.ini index 092b4fc3273..4d50e8ef39a 100644 --- a/build/pkgs/normaliz/checksums.ini +++ b/build/pkgs/normaliz/checksums.ini @@ -1,5 +1,5 @@ tarball=normaliz-VERSION.tar.gz -sha1=5cb40fc45f25c460df1662dd23c0bd3a9ac9a979 -md5=63c85df072d72e3feea542d47b406d5f -cksum=4133496545 +sha1=9436353151c2c2ad7703dcf66d713ecb6cc729ca +md5=e3c18ea44026c8c1dc3dd0093418d23e +cksum=2977572867 upstream_url=https://github.com/Normaliz/Normaliz/releases/download/vVERSION/normaliz-VERSION.tar.gz diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt index 2009c7dfad9..820476af941 100644 --- a/build/pkgs/normaliz/package-version.txt +++ b/build/pkgs/normaliz/package-version.txt @@ -1 +1 @@ -3.9.2 +3.9.3 From b899290da35e3bbff8318293dbe0d43dac6b8709 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 10 Jun 2022 09:03:34 +0200 Subject: [PATCH 035/350] 33969: initial --- build/pkgs/database_knotinfo/checksums.ini | 6 +- .../database_knotinfo/package-version.txt | 2 +- src/sage/databases/knotinfo_db.py | 60 ++++++- src/sage/knots/knotinfo.py | 153 ++++++++++++++++++ 4 files changed, 216 insertions(+), 5 deletions(-) diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index 01afb61648f..4c1afa4174b 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,5 +1,5 @@ tarball=database_knotinfo-VERSION.tar.gz -sha1=187e6b5ee2a935e3a50bc7648b181dfc7cb7bfa2 -md5=90822e09a1a84c8dbb84e20773c367f1 -cksum=1855405219 +sha1=8158005cf470c22122efdb0da99d4d7710a4454e +md5=b5a20e7773e8de044672952f606fd938 +cksum=4001595896 upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/package-version.txt b/build/pkgs/database_knotinfo/package-version.txt index bb762ff812e..755b627fe2c 100644 --- a/build/pkgs/database_knotinfo/package-version.txt +++ b/build/pkgs/database_knotinfo/package-version.txt @@ -1 +1 @@ -2021.10.1 +2022.6.1 diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 7d789b42229..6480fa53f7a 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -75,6 +75,7 @@ class KnotInfoColumns(Enum): 'PD Notation (vector)', 'PD Notation (KnotTheory)', 'Braid Notation', + 'Quasipositive Braid', 'Multivariable Alexander Polynomial', 'HOMFLYPT Polynomial', 'Unoriented', @@ -822,6 +823,8 @@ def _test_database(self, **options): 'homfly_polynomial': ['HOMFLY', KnotInfoColumnTypes.OnlyKnots], 'homflypt_polynomial': ['HOMFLYPT Polynomial', KnotInfoColumnTypes.OnlyLinks], 'kauffman_polynomial': ['Kauffman', KnotInfoColumnTypes.KnotsAndLinks], + 'khovanov_polynomial': ['Khovanov', KnotInfoColumnTypes.KnotsAndLinks], + 'khovanov_torsion_polynomial': ['Khovanov Torsion', KnotInfoColumnTypes.OnlyKnots], 'determinant': ['Determinant', KnotInfoColumnTypes.KnotsAndLinks], 'positive': ['Positive', KnotInfoColumnTypes.OnlyKnots], 'fibered': ['Fibered', KnotInfoColumnTypes.OnlyKnots], @@ -1089,5 +1092,60 @@ def _test_database(self, **options): '1-3*t+ 3*t^2-3*t^3+ t^4', '1-3*t+ 5*t^2-3*t^3+ t^4', '1-t+ t^2-t^3+ t^4-t^5+ t^6', - '3-5*t+ 3*t^2'] + '3-5*t+ 3*t^2'], + dc.conway_polynomial: [ + '1', + '1+z^2', + '1-z^2', + '1+3*z^2+z^4', + '1+2*z^2', + '1-2*z^2', + '1-z^2-z^4', + '1+z^2+z^4', + '1+6*z^2+5*z^4+z^6', + '1+3*z^2', + '-z', + 'z', + '-2*z', + '2*z + z^3', + 'z^3', + 'z^3', + '-2*z + z^3', + '2*z + 2*z^3', + '-3*z-2*z^3', + '3*z + 2*z^3', + '-3*z-4*z^3-z^5'], + dc.khovanov_polynomial: [ + '', + 'q^(-9)t^(-3)+q^(-5)t^(-2)+q^(-3)+q^(-1)', + 'q^(-5)t^(-2)+q^(-1)t^(-1)+q+q^(-1)+qt+q^5t^2', + 'q^(-15)t^(-5)+q^(-11)t^(-4)+q^(-11)t^(-3)+q^(-7)t^(-2)+q^(-5)+q^(-3)', + 'q^(-13)t^(-5)+q^(-9)t^(-4)+q^(-9)t^(-3)+(q^(-7)+q^(-5))t^(-2)+q^(-3)t^(-1)+q^(-3)+q^(-1)', + 'q^(-9)t^(-4)+q^(-5)t^(-3)+q^(-5)t^(-2)+(q^(-3)+q^(-1))t^(-1)+2q+q^(-1)+qt+q^5t^2', + 'q^(-11)t^(-4)+(q^(-9)+q^(-7))t^(-3)+(q^(-7)+q^(-5))t^(-2)+(q^(-5)+q^(-3))t^(-1)+q^(-3)+2q^(-1)+tq^(-1)+q^3t^2', + 'q^(-7)t^(-3)+(q^(-5)+q^(-3))t^(-2)+(q^(-3)+q^(-1))t^(-1)+2q+2q^(-1)+t(q+q^3)+(q^3+q^5)t^2+q^7t^3', + 'q^(-21)t^(-7)+q^(-17)t^(-6)+q^(-17)t^(-5)+q^(-13)t^(-4)+q^(-13)t^(-3)+q^(-9)t^(-2)+q^(-7)+q^(-5)', + 'q^(-17)t^(-7)+q^(-13)t^(-6)+q^(-13)t^(-5)+(q^(-11)+q^(-9))t^(-4)+(q^(-9)+q^(-7))t^(-3)+(q^(-7)+q^(-5))t^(-2)+q^(-3)t^(-1)+q^(-3)+q^(-1)', + '1 + q^(-2) + 1/(q^6*t^2) + 1/(q^4*t^2)', + '1 + q^2 + q^4*t^2 + q^6*t^2', + '1 + q^(-2) + 1/(q^10*t^4) + 1/(q^8*t^4) + 1/(q^6*t^2) + 1/(q^2*t)', + 'q^2 + q^4 + q^6*t^2 + q^10*t^3 + q^10*t^4 + q^12*t^4', + '2 + 2/q^2 + 1/(q^8*t^3) + 1/(q^6*t^2) + 1/(q^4*t^2) + 1/(q^2*t) + t + q^4*t^2', + '2 + 2/q^2 + 1/(q^8*t^3) + 1/(q^6*t^2) + 1/(q^4*t^2) + 1/(q^2*t) + t + q^4*t^2', + '1 + 2/q^2 + 1/(q^10*t^4) + 1/(q^8*t^4) + 1/(q^8*t^3) + 2/(q^6*t^2) + 1/(q^4*t^2) + 2/(q^2*t) + t + q^2*t + q^4*t^2', + 'q^2 + q^4 + q^4*t + 2*q^6*t^2 + q^8*t^2 + 2*q^10*t^3 + 2*q^10*t^4 + q^12*t^4 + q^12*t^5 + q^14*t^5 + q^16*t^6', + 'q^(-4) + q^(-2) + 1/(q^16*t^6) + 1/(q^14*t^6) + 1/(q^14*t^5) + 1/(q^12*t^4) + 1/(q^10*t^4) + 1/(q^10*t^3) + 1/(q^8*t^3) + 1/(q^8*t^2) + 1/(q^6*t^2) + 1/(q^4*t)', + 'q^2 + q^4 + q^4*t + q^6*t^2 + q^8*t^2 + q^8*t^3 + q^10*t^3 + q^10*t^4 + q^12*t^4 + q^14*t^5 + q^14*t^6 + q^16*t^6', + 'q^(-6) + q^(-4) + 1/(q^18*t^6) + 1/(q^16*t^6) + 1/(q^16*t^5) + 1/(q^12*t^4) + 1/(q^12*t^3) + 1/(q^8*t^2)'], + dc.khovanov_torsion_polynomial: [ + '', + 'Q^(-7)t^(-2)', + 'Q^(-3)t^(-1)+Q^3t^2', + 'Q^(-13)t^(-4)+Q^(-9)t^(-2)', + 'Q^(-11)t^(-4)+Q^(-7)t^(-2)+Q^(-5)t^(-1)', + 'Q^(-7)t^(-3)+Q^(-3)t^(-1)+Q^(-1)+Q^3t^2', + 'Q^(-9)t^(-3)+Q^(-7)t^(-2)+Q^(-5)t^(-1)+Q^(-3)+Qt^2', + 'Q^(-5)t^(-2)+Q^(-3)t^(-1)+Q^(-1)+Qt+Q^3t^2+Q^5t^3', + 'Q^(-19)t^(-6)+Q^(-15)t^(-4)+Q^(-11)t^(-2)', + 'Q^(-15)t^(-6)+Q^(-11)t^(-4)+Q^(-9)t^(-3)+Q^(-7)t^(-2)+Q^(-5)t^(-1)'] } diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 45417f83757..7096e400f4b 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -216,6 +216,7 @@ AUTHORS: - Sebastian Oehms August 2020: initial version +- Sebastian Oehms June 2022: add :meth:`conway_polynomial` and :meth:`khovanov_polynomial` (:trac:`33969`) Thanks to Chuck Livingston and Allison Moore for their support. For further acknowledgments see the correspondig hompages. """ @@ -1620,6 +1621,158 @@ def alexander_polynomial(self, var='t', original=False, laurent_poly=False): exp = ap.exponents() return t ** ((-max(exp) - min(exp)) // 2) * ap + @cached_method + def conway_polynomial(self, var='t', original=False): + r""" + Return the Conway polynomial according to the value of column + ``conway_polynomial`` for this knot or link as an instance of + :class:`~sage.rings.polynomial.polynomial_element.Polynomial`. + + It is obtained from the Seifert matrix `V` of ``self`` by the following + formula (see the KnotInfo description web-page; to launch it see the + example below): + + .. MATH:: + + \nabla(L) = \det(t^{\frac{1}{2}} V -t^{\frac{-1}{2}} V^t) + + Here `V^t` stands for the transpose of `V`. + + + INPUT: + + - ``var`` -- (default: ``'t'``) the variable + - ``original`` -- boolean (optional, default ``False``) if set to + ``True`` the original table entry is returned as a string + + OUTPUT: + + A polynomial over the integers, more precisely an instance of + :class:`~sage.rings.polynomial.polynomial_element.Polynomial`. + If ``original`` is set to ``True`` then a string is returned. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import KnotInfo + sage: K = KnotInfo.K4_1 + sage: Kc = K.conway_polynomial(); Kc + -t^2 + 1 + sage: L = KnotInfo.L5a1_0 + sage: Lc = L.conway_polynomial(); Lc + t^3 + + Comparision to Sage's results:: + + sage: Kc == K.link().conway_polynomial() + True + sage: Lc == L.link().conway_polynomial() + True + + Launch the KnotInfo description web-page:: + + sage: K.items.conway_polynomial.description_webpage() # not tested + True + """ + conway_polynomial = self[self.items.conway_polynomial] + + if original: + return conway_polynomial + + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(ZZ, var) + + if not conway_polynomial and self.crossing_number() == 0: + return R.one() + + t, = R.gens() + lc = {'z': t} + return R(eval_knotinfo(conway_polynomial, locals=lc)) + + @cached_method + def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): + r""" + Return the Khovanov polynomial according to the value of column + ``khovnov_polynomial`` for this knot or link as an instance of + :class:`~sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair`. + + INPUT: + + - ``var1`` -- (default: ``'q'``) the first variable + - ``var2`` -- (default: ``'t'``) the second variable + - ``base_ring`` -- (default: ``ZZ``) the ring of the polynomial's + coefficients + - ``original`` -- boolean (optional, default ``False``) if set to + ``True`` the original table entry is returned as a string + + OUTPUT: + + A Laurent polynomial over the integers, more precisely an instance of + :class:`~sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair`. + If ``original`` is set to ``True`` then a string is returned. + + .. NOTE :: + + The Khovanov polynomial given in KnotInfo corresponds to the mirror + image of the given knot for a `list of 140 exceptions + `__. + + EXAMPLES:: + + sage: from sage.knots.knotinfo import KnotInfo + sage: K = KnotInfo.K6_3 + sage: Kk = K.khovanov_polynomial(); Kk + q^7*t^3 + q^5*t^2 + q^3*t^2 + q^3*t + q*t + 2*q + 2*q^-1 + q^-1*t^-1 + + q^-3*t^-1 + q^-3*t^-2 + q^-5*t^-2 + q^-7*t^-3 + sage: Kk2 = K.khovanov_polynomial(var1='p', base_ring=GF(2)); Kk2 + p^7*t^3 + p^5*t^3 + p^5*t^2 + p^3*t + p^-1 + p^-1*t^-1 + p^-3*t^-2 + p^-7*t^-3 + + sage: L = KnotInfo.L5a1_0 + sage: Lk = L.khovanov_polynomial(); Lk + q^4*t^2 + t + 2 + 2*q^-2 + q^-2*t^-1 + q^-4*t^-2 + q^-6*t^-2 + q^-8*t^-3 + + Comparision to Sage's results:: + + sage: Kk == K.link().khovanov_polynomial() + True + sage: Kk2 == K.link().khovanov_polynomial(var1='p', base_ring=GF(2)) + True + sage: Lk == L.link().khovanov_polynomial() + True + """ + khovanov_polynomial = self[self.items.khovanov_polynomial] + + if original: + return khovanov_polynomial + + from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing + var_names = [var1, var2] + R = LaurentPolynomialRing(base_ring, var_names) + ch = base_ring.characteristic() + if ch == 2: + khovanov_torsion_polynomial = self[self.items.khovanov_torsion_polynomial] + khovanov_torsion_polynomial = khovanov_torsion_polynomial.replace('Q', 'q') + khovanov_polynomial = '%s + %s' % (khovanov_polynomial, khovanov_torsion_polynomial) + + if not khovanov_polynomial and self.crossing_number() == 0: + return R({(1, 0): 1, (-1, 0): 1}) + + if not khovanov_polynomial: + # given just for links with less than 12 crossings + raise NotImplementedError('Khovanov polynomial not available for this link') + + from sage.repl.preparse import implicit_mul + # since implicit_mul does not know about the choice of variable names + # we have to insert * between them separately + for i in ['q', 't',')']: + for j in ['q', 't', '(']: + khovanov_polynomial = khovanov_polynomial.replace('%s%s' % (i, j), '%s*%s' % (i, j)) + khovanov_polynomial = implicit_mul(khovanov_polynomial) + gens = R.gens_dict() + lc = {} + lc['q'] = gens[var1] + lc['t'] = gens[var2] + + return R(eval_knotinfo(khovanov_polynomial, locals=lc)) @cached_method def link(self, use_item=db.columns().pd_notation, snappy=False): From ad7c107b33dacd19e1a942660424d1c6e12e606f Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Mon, 4 Jul 2022 19:16:41 +0200 Subject: [PATCH 036/350] 33969: characteristic 2 only for knots and push to current db-version --- build/pkgs/database_knotinfo/checksums.ini | 6 +++--- build/pkgs/database_knotinfo/package-version.txt | 2 +- src/sage/knots/knotinfo.py | 9 ++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index 4c1afa4174b..9b521522202 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,5 +1,5 @@ tarball=database_knotinfo-VERSION.tar.gz -sha1=8158005cf470c22122efdb0da99d4d7710a4454e -md5=b5a20e7773e8de044672952f606fd938 -cksum=4001595896 +sha1=16039d4e399efc78e4b1278527019f4bcdfdde13 +md5=3095993756f6b51d14c35adae5a75930 +cksum=2884062991 upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/package-version.txt b/build/pkgs/database_knotinfo/package-version.txt index 755b627fe2c..eef52011e7f 100644 --- a/build/pkgs/database_knotinfo/package-version.txt +++ b/build/pkgs/database_knotinfo/package-version.txt @@ -1 +1 @@ -2022.6.1 +2022.7.1 diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 7096e400f4b..49f55e4aac9 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1747,15 +1747,18 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing var_names = [var1, var2] R = LaurentPolynomialRing(base_ring, var_names) + + if not khovanov_polynomial and self.crossing_number() == 0: + return R({(1, 0): 1, (-1, 0): 1}) + ch = base_ring.characteristic() if ch == 2: + if not self.is_knot(): + raise NotImplementedError('Khovanov polynomial available only for knots in characteristic 2') khovanov_torsion_polynomial = self[self.items.khovanov_torsion_polynomial] khovanov_torsion_polynomial = khovanov_torsion_polynomial.replace('Q', 'q') khovanov_polynomial = '%s + %s' % (khovanov_polynomial, khovanov_torsion_polynomial) - if not khovanov_polynomial and self.crossing_number() == 0: - return R({(1, 0): 1, (-1, 0): 1}) - if not khovanov_polynomial: # given just for links with less than 12 crossings raise NotImplementedError('Khovanov polynomial not available for this link') From 1733d845716aa51f86ec052fed5f5463870f42f5 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Thu, 14 Jul 2022 11:51:56 +0200 Subject: [PATCH 037/350] trac #34179: document range of vertices in each class --- src/sage/graphs/graph_generators.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 5555b222b1f..5f72b1d6c5f 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -1004,8 +1004,10 @@ def nauty_genbg(self, options="", debug=False): The possible options, obtained as output of ``genbg --help``:: - n1 : the number of vertices in the first class - n2 : the number of vertices in the second class + n1 : the number of vertices in the first class. + We must have n1=1..24. + n2 : the number of vertices in the second class. + We must have n2=0..32 and n1+n2=1..32. mine:maxe : : a range for the number of edges :0 means ' or more' except in the case 0:0 res/mod : only generate subset res out of subsets 0..mod-1 @@ -1119,6 +1121,27 @@ def nauty_genbg(self, options="", debug=False): ['>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... sage: list(graphs.nauty_genbg("-c 1 2", debug=True)) ['>A ...genbg n=1+2 e=2:2 d=1:1 D=2:1 c\n', Bipartite graph on 3 vertices] + + We must have n1=1..24, n2=0..32 and n1+n2=1..32 (:trac:`34179`):: + + sage: next(graphs.nauty_genbg("25 1", debug=False)) + Traceback (most recent call last): + ... + ValueError: wrong format of parameter options + sage: next(graphs.nauty_genbg("25 1", debug=True)) + '>E ...genbg: must have n1=1..24, n1+n2=1..32... + sage: next(graphs.nauty_genbg("24 9", debug=True)) + '>E ...genbg: must have n1=1..24, n1+n2=1..32... + sage: next(graphs.nauty_genbg("1 31", debug=False)) + Bipartite graph on 32 vertices + sage: next(graphs.nauty_genbg("1 32", debug=True)) + '>E ...genbg: must have n1=1..24, n1+n2=1..32... + sage: next(graphs.nauty_genbg("0 32", debug=True)) + '>E ...genbg: must have n1=1..24, n1+n2=1..32... + sage: next(graphs.nauty_genbg("2 0", debug=False)) + Bipartite graph on 2 vertices + sage: next(graphs.nauty_genbg("2 -1", debug=True)) + '>E Usage: ...genbg [-c -ugs -vq -lzF] [-Z#] [-D#] [-A] [-d#|-d#:#] [-D#|-D#:#] n1 n2... """ import shlex from sage.features.nauty import NautyExecutable From df79b853022fde4fbc720b6538594ed4fe230b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nadia=20Lafreni=C3=A8re?= Date: Thu, 14 Jul 2022 13:35:56 -0400 Subject: [PATCH 038/350] Added from_lehmer_cocode --- src/sage/combinat/permutation.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index a38eaa71079..20775f3c2e1 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -7401,6 +7401,32 @@ def from_lehmer_code(lehmer, parent=None): parent = Permutations() return parent(p) +def from_lehmer_cocode(lehmer, parent=Permutations()): + r""" + Return the permutation with Lehmer cocode ``lehmer``. + + The Lehmer cocode of a permutation `p` is defined as the + list `(c_1, c_2, \ldots, c_n)`, where `c_i` is the number + of `j < i` such that `p(j) > p(i)`. + + EXAMPLES:: + + sage: import sage.combinat.permutation as permutation + sage: lcc = Permutation([2,1,5,4,3]).to_lehmer_cocode(); lcc + [0, 1, 0, 1, 2] + sage: permutation.from_lehmer_cocode(lcc) + [2, 1, 5, 4, 3] + """ + p = [] + i = 1 + lehmer.reverse() + open_spots = list(range(1,len(lehmer)+1)) + for ivi in lehmer: + p.append(open_spots.pop(len(lehmer)-i-ivi)) + i += 1 + p.reverse() + return parent(p) + def from_reduced_word(rw, parent=None): r""" Return the permutation corresponding to the reduced word ``rw``. From c68ccfc110eed8deabc4b3696705318e17c29b9d Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Tue, 26 Jul 2022 07:17:25 +0100 Subject: [PATCH 039/350] Initialization --- src/sage/graphs/edge_connectivity.pyx | 98 +++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index ca0469e1902..0ea4ce64ffc 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -169,6 +169,11 @@ cdef class GabowEdgeConnectivity: cdef queue[pair[int, int]] joining_edges # queue of tuples (edge id, edge state) cdef queue[int] incident_edges_Q # queue of edges + cdef int num_start_f_trees # number of f-trees at the beginning of an iteration + cdef bint isReverse # whether or not graph is reverses + cdef int* T # whether the an edge is in the proven k-intersection + cdef bint* visited # for method find_dfs_tree + def __init__(self, G): r""" Initialize this object. @@ -232,6 +237,8 @@ cdef class GabowEdgeConnectivity: self.stack = self.mem.calloc(self.n, sizeof(int)) self.tree_edges.resize(self.max_ec) self.tree_edges_incident.resize(self.n) + self.T = self.mem.calloc(self.m, sizeof(int)) + self.visited = self.mem.calloc(self.n, sizeof(bint)) # Set some constants self.UNUSED = INT_MAX @@ -242,6 +249,7 @@ cdef class GabowEdgeConnectivity: self.edge_state_1[i] = self.UNUSED # edge i is unused self.edge_state_2[i] = self.UNUSED self.labels[i] = self.UNUSED # edge i is unlabeled + self.T[i] = False # edge i doesn't belong to any k-intersection yet _ = self.compute_edge_connectivity() sig_check() @@ -271,7 +279,7 @@ cdef class GabowEdgeConnectivity: for i in range(self.n): self.g_out[i].clear() self.g_in[i].clear() - + cdef int x, y cdef int e_id = 0 for x, u in enumerate(self.int_to_vertex): @@ -357,8 +365,7 @@ cdef class GabowEdgeConnectivity: cdef int njoins = 0 cdef int z - - while njoins < self.n - 1: + while njoins < self.num_start_f_trees-1: # Get the root of an active subtree or INT_MAX if none exists z = self.choose_root() while z != INT_MAX: @@ -415,13 +422,94 @@ cdef class GabowEdgeConnectivity: self.labeled[tree][j] = False self.root[j] = j self.forests[j] = True + + self.num_start_f_trees = 1 + + # Initialize T_k to be a DFS spanning forest of G \ T + self.G_minus_T() + self.compute_dfs_tree() - # Set inactive the f_trees of the root vertex + # Set inactive the f-trees of the root vertex self.forests[self.root_vertex] = False self.L_roots[tree] = self.UNUSED self.tree_flag[tree] = False + cdef void G_minus_T(self): + """ + Delete all edges in the proven k-intersection (T) from the graph + We then consider G as the subgraph of G induced by the unused edges + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + for e_id in range(self.m): + self.T[e_id] = False + for i in range(self.max_ec): + edge_list = self.tree_edges[i] + # All True edges in T correspond to the proven complete (k−1)-intersection of G + for e_id in edge_list: + self.T[e_id] = True + + cdef void compute_dfs_tree(self): + """ + Find a DFS spanning forest of G \ T + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + # Mark all vertices as unvisited + for i in range(self.n): + self.visited[i] = False + + # Avoid considering the root + self.visited[self.root_vertex] = True + + for r in range(self.n): + if not self.visited[r]: + # Make this vertex the root of the following dfs tree + self.root[r] = r + # Make the f_tree rooted at this vertex active + self.forests[r] = True + # Find connected vertices of the f-tree rooted at r + self.find_dfs_tree(r, r) + # Each call of find_dfs_tree creates an f-tree + self.num_start_f_trees += 1 + + cdef void find_dfs_tree(self, u, r): + """ + Find more vertices of the f-tree rooted at r + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + # Mark vertex u as visited to avoid visiting it multiple times + self.visited[u] = True + + # Visit outgoing arcs of current vertex + for e_id in self.g_out[u]: + v = self.my_to[e_id] + # Ensure a vertex is not visited and does not a proven k-intersection edge + if not self.visited[v] and not self.T[e_id]: + # Make current vertex belong to the f_tree rooted at r + self.root[v] = r + self.forests[v] = False + self.my_edge_state[e_id] = self.current_tree + # recursively find more vertices and grow the subtree rooted at r + self.find_dfs_tree(v, r) + cdef int choose_root(self): """ Return the root of an active f_tree, or INT_MAX if none exists. @@ -728,7 +816,7 @@ cdef class GabowEdgeConnectivity: cdef bint label_step(self, int e_id, int e_label): """ - Label edge e_id with e_label and check wheteher edge e_id is joining. + Label edge e_id with e_label and check whether edge e_id is joining. EXAMPLES:: From 9b95c47319ec72ad55586333edd4ef17b1e2e8ce Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Tue, 26 Jul 2022 07:33:25 +0100 Subject: [PATCH 040/350] Remove unnecessary variable --- src/sage/graphs/edge_connectivity.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 0ea4ce64ffc..802bf1608eb 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -170,7 +170,6 @@ cdef class GabowEdgeConnectivity: cdef queue[int] incident_edges_Q # queue of edges cdef int num_start_f_trees # number of f-trees at the beginning of an iteration - cdef bint isReverse # whether or not graph is reverses cdef int* T # whether the an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree From 5368f71ffee62e2f59e960c5945e1359db39fc81 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Tue, 2 Aug 2022 10:30:40 +0100 Subject: [PATCH 041/350] Replace G_minus_T function with inline code --- src/sage/graphs/edge_connectivity.pyx | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 802bf1608eb..c581a8cfef2 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -425,7 +425,6 @@ cdef class GabowEdgeConnectivity: self.num_start_f_trees = 1 # Initialize T_k to be a DFS spanning forest of G \ T - self.G_minus_T() self.compute_dfs_tree() # Set inactive the f-trees of the root vertex @@ -434,26 +433,6 @@ cdef class GabowEdgeConnectivity: self.L_roots[tree] = self.UNUSED self.tree_flag[tree] = False - cdef void G_minus_T(self): - """ - Delete all edges in the proven k-intersection (T) from the graph - We then consider G as the subgraph of G induced by the unused edges - - EXAMPLES:: - - sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity - sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D).edge_connectivity() - 4 - """ - for e_id in range(self.m): - self.T[e_id] = False - for i in range(self.max_ec): - edge_list = self.tree_edges[i] - # All True edges in T correspond to the proven complete (k−1)-intersection of G - for e_id in edge_list: - self.T[e_id] = True - cdef void compute_dfs_tree(self): """ Find a DFS spanning forest of G \ T @@ -948,10 +927,14 @@ cdef class GabowEdgeConnectivity: # Arrange the edges of each tree for j in range(tree + 1): + for e in range(len(self.tree_edges[j])): + e_id = self.tree_edges[j][e] + self.T[e_id] = False self.tree_edges[j].clear() for j in range(self.m): if self.my_edge_state[j] != self.UNUSED: self.tree_edges[self.my_edge_state[j]].push_back(j) + self.T[j] = False for j in range(tree + 1): if not j or j == tree or self.tree_flag[j]: From 7984773392f9e6bd98f2874c74b9c3e2427b5cf5 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Tue, 2 Aug 2022 13:51:50 +0100 Subject: [PATCH 042/350] Mark (k-1)-intersection edges as True --- src/sage/graphs/edge_connectivity.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index c581a8cfef2..071b148433e 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -934,7 +934,8 @@ cdef class GabowEdgeConnectivity: for j in range(self.m): if self.my_edge_state[j] != self.UNUSED: self.tree_edges[self.my_edge_state[j]].push_back(j) - self.T[j] = False + # All True edges in T correspond to the proven complete (k−1)-intersection of G + self.T[j] = True for j in range(tree + 1): if not j or j == tree or self.tree_flag[j]: From e5339d0d1466767a493973464ba168b5da7dfedc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 11:09:26 -0700 Subject: [PATCH 043/350] build/pkgs/r: Reduce to dummy package --- build/pkgs/r/bin/java | 2 - build/pkgs/r/bin/javac | 2 - build/pkgs/r/checksums.ini | 5 - build/pkgs/r/dependencies | 4 - build/pkgs/r/package-version.txt | 1 - build/pkgs/r/patches/autoconf_verb_dash.patch | 41 ------ .../pkgs/r/patches/configure_bzlibtest.patch | 13 -- .../pkgs/r/patches/cygwin_build_support.patch | 123 ------------------ build/pkgs/r/patches/hardcoded_dirs.patch | 58 --------- .../r/patches/libcurl_https_support.patch | 116 ----------------- .../pkgs/r/patches/link_all_shared_libs.patch | 25 ---- build/pkgs/r/patches/m4_macro_bug.patch | 57 -------- build/pkgs/r/patches/rcmd_exec.patch | 31 ----- build/pkgs/r/spkg-check.in | 2 - build/pkgs/r/spkg-install.in | 123 ------------------ build/pkgs/r/spkg-legacy-uninstall | 7 - build/pkgs/r/spkg-src | 13 -- 17 files changed, 623 deletions(-) delete mode 100755 build/pkgs/r/bin/java delete mode 100755 build/pkgs/r/bin/javac delete mode 100644 build/pkgs/r/checksums.ini delete mode 100644 build/pkgs/r/dependencies delete mode 100644 build/pkgs/r/package-version.txt delete mode 100644 build/pkgs/r/patches/autoconf_verb_dash.patch delete mode 100644 build/pkgs/r/patches/configure_bzlibtest.patch delete mode 100644 build/pkgs/r/patches/cygwin_build_support.patch delete mode 100644 build/pkgs/r/patches/hardcoded_dirs.patch delete mode 100644 build/pkgs/r/patches/libcurl_https_support.patch delete mode 100644 build/pkgs/r/patches/link_all_shared_libs.patch delete mode 100644 build/pkgs/r/patches/m4_macro_bug.patch delete mode 100644 build/pkgs/r/patches/rcmd_exec.patch delete mode 100644 build/pkgs/r/spkg-check.in delete mode 100644 build/pkgs/r/spkg-install.in delete mode 100755 build/pkgs/r/spkg-legacy-uninstall delete mode 100755 build/pkgs/r/spkg-src diff --git a/build/pkgs/r/bin/java b/build/pkgs/r/bin/java deleted file mode 100755 index d5e39b620f7..00000000000 --- a/build/pkgs/r/bin/java +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -exit 1 diff --git a/build/pkgs/r/bin/javac b/build/pkgs/r/bin/javac deleted file mode 100755 index d5e39b620f7..00000000000 --- a/build/pkgs/r/bin/javac +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -exit 1 diff --git a/build/pkgs/r/checksums.ini b/build/pkgs/r/checksums.ini deleted file mode 100644 index 69a1a7059dc..00000000000 --- a/build/pkgs/r/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=R-VERSION.tar.gz -sha1=d2383dabc0d6c70f8a0171a0fb1bfdc31ddb5b52 -md5=506c9576ba33e1262ad5b5624db9d96a -cksum=2403187565 -upstream_url=https://cran.r-project.org/src/base/R-3/R-VERSION.tar.gz diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies deleted file mode 100644 index c34daf966bd..00000000000 --- a/build/pkgs/r/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -$(BLAS) gfortran iconv readline bzip2 liblzma pcre curl | pkgconf - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/r/package-version.txt b/build/pkgs/r/package-version.txt deleted file mode 100644 index 4a788a01dad..00000000000 --- a/build/pkgs/r/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -3.6.3 diff --git a/build/pkgs/r/patches/autoconf_verb_dash.patch b/build/pkgs/r/patches/autoconf_verb_dash.patch deleted file mode 100644 index c5217fdd94d..00000000000 --- a/build/pkgs/r/patches/autoconf_verb_dash.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 04d878728603db345c0a0b01718864a12bcfa97d Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:36 +0100 -Subject: [PATCH 1/9] autoconf_verb_dash - -Bug in autoconf and R macros. -Use -### instead of -v to detect linker options. -See Sage ticket #12787 and R ticket -* https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14865 -The corresponding patch to m4/clibs.m4 is not included, as -autoconf-2.68 gives errors, even on the clean upstream sources. - ---- - configure | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/configure b/configure -index a314719..dee602f 100755 ---- a/configure -+++ b/configure -@@ -24837,7 +24837,7 @@ _ACEOF - if ac_fn_f77_try_compile "$LINENO"; then : - ac_cv_prog_f77_v= - # Try some options frequently used verbose output --for ac_verb in -v -verbose --verbose -V -\#\#\#; do -+for ac_verb in -\#\#\# -v -verbose --verbose -V ; do - cat > conftest.$ac_ext <<_ACEOF - program main - -@@ -25193,7 +25193,7 @@ _ACEOF - if ac_fn_c_try_compile "$LINENO"; then : - r_cv_prog_c_v= - # Try some options frequently used verbose output --for r_verb in -v -verbose --verbose -V -\#\#\#; do -+for r_verb in -\#\#\# -v -verbose --verbose -V ; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - --- -2.16.1 - diff --git a/build/pkgs/r/patches/configure_bzlibtest.patch b/build/pkgs/r/patches/configure_bzlibtest.patch deleted file mode 100644 index b4d3f61ef9e..00000000000 --- a/build/pkgs/r/patches/configure_bzlibtest.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/configure b/configure -index 976de50..14b6b4c 100755 ---- a/configure -+++ b/configure -@@ -42239,6 +42239,8 @@ else - - #ifdef HAVE_BZLIB_H - #include -+#include -+#include - #endif - int main() { - char *ver = BZ2_bzlibVersion(); diff --git a/build/pkgs/r/patches/cygwin_build_support.patch b/build/pkgs/r/patches/cygwin_build_support.patch deleted file mode 100644 index e6965110602..00000000000 --- a/build/pkgs/r/patches/cygwin_build_support.patch +++ /dev/null @@ -1,123 +0,0 @@ -From b03ea08e8fe3cbda01824225447943c77c244ba8 Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:36 +0100 -Subject: [PATCH 2/9] cygwin_build_support - -Patches required to explicitly support Cygwin when building R. - ---- - configure | 15 ++++++++++++--- - configure.ac | 15 ++++++++++++--- - src/library/tools/R/install.R | 2 +- - 3 files changed, 25 insertions(+), 7 deletions(-) - -diff --git a/configure b/configure -index dee602f..fadb84e 100755 ---- a/configure -+++ b/configure -@@ -27723,6 +27723,15 @@ case "${host_os}" in - shlib_cxxldflags="-shared ${shlib_cxxldflags}" - fi - ;; -+ cygwin*) -+ ## All Windows binaries are PIC -+ cpicflags= -+ cxxpicflags= -+ fpicflags= -+ fcpicflags= -+ SHLIB_EXT=".dll" -+ dylib_undefined_allowed=no -+ ;; - darwin*) - darwin_pic="-fPIC" - dylib_undefined_allowed=no -@@ -27987,7 +27996,7 @@ fi - : ${CPICFLAGS="${cpicflags}"} - if test -z "${CPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I could not determine CPICFLAGS." >&5 -@@ -28000,7 +28009,7 @@ fi - : ${FPICFLAGS="${fpicflags}"} - if test -z "${FPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I could not determine FPICFLAGS." >&5 -@@ -28013,7 +28022,7 @@ fi - : ${CXXPICFLAGS="${cxxpicflags}"} - if test -n "${CXX}" -a -z "${CXXPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - warn_cxxpicflags="I could not determine CXXPICFLAGS." -diff --git a/configure.ac b/configure.ac -index 330d79a..ab7967b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1294,6 +1294,15 @@ case "${host_os}" in - shlib_cxxldflags="-shared ${shlib_cxxldflags}" - fi - ;; -+ cygwin*) -+ ## All Windows binaries are PIC -+ cpicflags= -+ cxxpicflags= -+ fpicflags= -+ fcpicflags= -+ SHLIB_EXT=".dll" -+ dylib_undefined_allowed=no -+ ;; - darwin*) - darwin_pic="-fPIC" - dylib_undefined_allowed=no -@@ -1542,7 +1551,7 @@ R_SH_VAR_ADD(MAIN_LDFLAGS, [${main_ldflags}]) - : ${CPICFLAGS="${cpicflags}"} - if test -z "${CPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - AC_MSG_WARN([I could not determine CPICFLAGS.]) -@@ -1554,7 +1563,7 @@ fi - : ${FPICFLAGS="${fpicflags}"} - if test -z "${FPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - AC_MSG_WARN([I could not determine FPICFLAGS.]) -@@ -1566,7 +1575,7 @@ fi - : ${CXXPICFLAGS="${cxxpicflags}"} - if test -n "${CXX}" -a -z "${CXXPICFLAGS}"; then - case "${host_os}" in -- aix*|mingw*) -+ aix*|cygwin*|mingw*) - ;; - *) - warn_cxxpicflags="I could not determine CXXPICFLAGS." -diff --git a/src/library/tools/R/install.R b/src/library/tools/R/install.R -index 6f1e9d7..662556b 100644 ---- a/src/library/tools/R/install.R -+++ b/src/library/tools/R/install.R -@@ -841,7 +841,7 @@ - setwd(owd) - test_archs <- archs - for(arch in archs) { -- if (arch == "R") { -+ if (arch == "R" || arch == "R.exe") { - ## top-level, so one arch without subdirs - has_error <- run_shlib(pkg_name, srcs, instdir, "") - } else { --- -2.16.1 - diff --git a/build/pkgs/r/patches/hardcoded_dirs.patch b/build/pkgs/r/patches/hardcoded_dirs.patch deleted file mode 100644 index e76ce4f607b..00000000000 --- a/build/pkgs/r/patches/hardcoded_dirs.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 4dc58ff28b6cc21dc9edc03b76277affc0da2bd6 Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:37 +0100 -Subject: [PATCH 3/9] hardcoded_dirs - -Make R_HOME_DIR relative to SAGE_LOCAL by setting -R_HOME_DIR to "${SAGE_LOCAL}/lib/R/" when running R. - -Also remove the sed scripts hardcoding R_*_DIR's in the "frontend" R script. -See Sage trac #9668. - -This allows to move Sage install tree. - ---- - src/scripts/Makefile.in | 7 +------ - src/scripts/R.sh.in | 8 ++++++++ - 2 files changed, 9 insertions(+), 6 deletions(-) - -diff --git a/src/scripts/Makefile.in b/src/scripts/Makefile.in -index a7fa60d..ce504a0 100644 ---- a/src/scripts/Makefile.in -+++ b/src/scripts/Makefile.in -@@ -89,12 +89,7 @@ $(top_builddir)/libtool: - - install: installdirs install-cmds - @rm -f $(DESTDIR)$(bindir)/R -- @(d=`$(ECHO) '$(rhome)' | sed 's,/,\\\/,g';`; \ -- d2=`$(ECHO) '$(rsharedir)' | sed 's,/,\\\/,g';`; \ -- d3=`$(ECHO) '$(rincludedir)' | sed 's,/,\\\/,g';`; \ -- d4=`$(ECHO) '$(rdocdir)' | sed 's,/,\\\/,g';`; \ -- sed -e "1,/R_HOME_DIR=/s/\\(R_HOME_DIR=\\).*/\\1$${d}/;" -e "s/\\(R_SHARE_DIR=\\).*/\\1$${d2}/;" -e "s/\\(R_INCLUDE_DIR=\\).*/\\1$${d3}/;" -e "s/\\(R_DOC_DIR=\\).*/\\1$${d4}/;"\ -- < R.fe > "$(DESTDIR)$(Rexecbindir)/R") -+ @cat R.fe > "$(DESTDIR)$(Rexecbindir)/R" - @$(INSTALL_SCRIPT) "$(DESTDIR)$(Rexecbindir)/R" "$(DESTDIR)$(bindir)/R" - @chmod 755 "$(DESTDIR)$(bindir)/R" "$(DESTDIR)$(Rexecbindir)/R" - ## why of all the scripts does this alone chmod just one copy? -diff --git a/src/scripts/R.sh.in b/src/scripts/R.sh.in -index 674d5e0..11bfede 100644 ---- a/src/scripts/R.sh.in -+++ b/src/scripts/R.sh.in -@@ -26,6 +26,14 @@ if test "${R_HOME_DIR}" = "@prefix@/@LIBnn@/R"; then - esac - fi - -+# Make R_HOME_DIR relative to SAGE_LOCAL (if SAGE_LOCAL is set) -+# unless SAGE_BUILDING_R is set (as spkg-install does). -+if test -n "$SAGE_LOCAL"; then -+ if test -z "$SAGE_BUILDING_R"; then -+ R_HOME_DIR="$SAGE_LOCAL/lib/R/" -+ fi -+fi -+ - if test -n "${R_HOME}" && \ - test "${R_HOME}" != "${R_HOME_DIR}"; then - echo "WARNING: ignoring environment value of R_HOME" --- -2.16.1 - diff --git a/build/pkgs/r/patches/libcurl_https_support.patch b/build/pkgs/r/patches/libcurl_https_support.patch deleted file mode 100644 index 01c3c066232..00000000000 --- a/build/pkgs/r/patches/libcurl_https_support.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 996ded767d76952d9aae596219f8fb1b9469ef57 Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:37 +0100 -Subject: [PATCH 4/9] libcurl_https_support - -Don't check for HTTPS support in libcurl; see https://trac.sagemath.org/ticket/20523 - ---- - configure | 43 +------------------------------------------ - m4/R.m4 | 23 ++--------------------- - 2 files changed, 3 insertions(+), 63 deletions(-) - -diff --git a/configure b/configure -index fadb84e..02e210e 100755 ---- a/configure -+++ b/configure -@@ -41069,47 +41069,6 @@ if test "x${r_cv_have_curl722}" = xno; then - have_libcurl=no - fi - --if test "x${have_libcurl}" = "xyes"; then --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libcurl supports https" >&5 --$as_echo_n "checking if libcurl supports https... " >&6; } --if ${r_cv_have_curl_https+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- if test "$cross_compiling" = yes; then : -- r_cv_have_curl_https=no --else -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#include --#include --int main() --{ -- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); -- const char * const *p = data->protocols; -- int found = 0; -- for (; *p; p++) -- if(strcmp(*p, "https") == 0) {found = 1; break;} -- exit(found ? 0 : 1); --} -- --_ACEOF --if ac_fn_c_try_run "$LINENO"; then : -- r_cv_have_curl_https=yes --else -- r_cv_have_curl_https=no --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -- conftest.$ac_objext conftest.beam conftest.$ac_ext --fi -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $r_cv_have_curl_https" >&5 --$as_echo "$r_cv_have_curl_https" >&6; } --fi --if test "x${r_cv_have_curl_https}" = xno; then -- have_libcurl=no --fi - if test "x${have_libcurl}" = xyes; then - - $as_echo "#define HAVE_LIBCURL 1" >>confdefs.h -@@ -41119,7 +41078,7 @@ $as_echo "#define HAVE_LIBCURL 1" >>confdefs.h - - - else -- as_fn_error $? "libcurl >= 7.22.0 library and headers are required with support for https" "$LINENO" 5 -+ as_fn_error $? "libcurl >= 7.22.0 library and headers are required" "$LINENO" 5 - fi - - -diff --git a/m4/R.m4 b/m4/R.m4 -index 3fe8b27..fb35a5f 100644 ---- a/m4/R.m4 -+++ b/m4/R.m4 -@@ -4205,33 +4205,14 @@ if test "x${r_cv_have_curl722}" = xno; then - have_libcurl=no - fi - --if test "x${have_libcurl}" = "xyes"; then --AC_CACHE_CHECK([if libcurl supports https], [r_cv_have_curl_https], --[AC_RUN_IFELSE([AC_LANG_SOURCE([[ --#include --#include --int main() --{ -- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); -- const char * const *p = data->protocols; -- int found = 0; -- for (; *p; p++) -- if(strcmp(*p, "https") == 0) {found = 1; break;} -- exit(found ? 0 : 1); --} --]])], [r_cv_have_curl_https=yes], [r_cv_have_curl_https=no], [r_cv_have_curl_https=no])]) --fi --if test "x${r_cv_have_curl_https}" = xno; then -- have_libcurl=no --fi - if test "x${have_libcurl}" = xyes; then -- AC_DEFINE(HAVE_LIBCURL, 1, [Define if your system has libcurl >= 7.22.0 with support for https.]) -+ AC_DEFINE(HAVE_LIBCURL, 1, [Define if your system has libcurl >= 7.22.0.]) - CPPFLAGS="${r_save_CPPFLAGS}" - LIBS="${r_save_LIBS}" - AC_SUBST(CURL_CPPFLAGS) - AC_SUBST(CURL_LIBS) - else -- AC_MSG_ERROR([libcurl >= 7.22.0 library and headers are required with support for https]) -+ AC_MSG_ERROR([libcurl >= 7.22.0 library and headers are required]) - fi - ])# R_LIBCURL - --- -2.16.1 - diff --git a/build/pkgs/r/patches/link_all_shared_libs.patch b/build/pkgs/r/patches/link_all_shared_libs.patch deleted file mode 100644 index 980b6842ad3..00000000000 --- a/build/pkgs/r/patches/link_all_shared_libs.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 9250c9e75137e78091da1cf1c25b3dbe40c7e4bf Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:37 +0100 -Subject: [PATCH 5/9] link_all_shared_libs - ---- - etc/Makeconf.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/etc/Makeconf.in b/etc/Makeconf.in -index e7d9fbd..3eccb2c 100644 ---- a/etc/Makeconf.in -+++ b/etc/Makeconf.in -@@ -150,7 +150,7 @@ ALL_OBJCFLAGS = $(PKG_OBJCFLAGS) $(CPICFLAGS) $(SHLIB_CFLAGS) $(OBJCFLAGS) - ALL_OBJCXXFLAGS = $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS) - ALL_FFLAGS = $(R_XTRA_FFLAGS) $(PKG_FFLAGS) $(FPICFLAGS) $(SHLIB_FFLAGS) $(FFLAGS) - ## LIBR here as a couple of packages use this without SHLIB_LINK --ALL_LIBS = $(PKG_LIBS) $(SHLIB_LIBADD) $(LIBR)@DYLIB_UNDEFINED_ALLOWED_FALSE@ $(LIBINTL) -+ALL_LIBS = $(PKG_LIBS) $(SHLIB_LIBADD) $(LIBR)@DYLIB_UNDEFINED_ALLOWED_FALSE@ $(LIBINTL) $(LIBS) - - .SUFFIXES: - .SUFFIXES: .c .cc .cpp .d .f .f90 .f95 .m .mm .M .o --- -2.16.1 - diff --git a/build/pkgs/r/patches/m4_macro_bug.patch b/build/pkgs/r/patches/m4_macro_bug.patch deleted file mode 100644 index bf96351c131..00000000000 --- a/build/pkgs/r/patches/m4_macro_bug.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0b4ac9b9ff60a82f57bf3852056548274cbde09d Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:37 +0100 -Subject: [PATCH 7/9] m4_macro_bug - -Fix bug in R_PCRE autoconf macro which leads to 'configure' losing '-lz' -and/or '-lbz2' from LIBS (under certain circumstances, and only relevant -if "system" versions of these libraries are used). (cf. #18229) - ---- - configure | 2 +- - m4/R.m4 | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/configure b/configure -index 02e210e..682b8cd 100755 ---- a/configure -+++ b/configure -@@ -40799,7 +40799,6 @@ fi - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $r_cv_have_pcre820" >&5 - $as_echo "$r_cv_have_pcre820" >&6; } --fi - if test "x${r_cv_have_pcre820}" != xyes; then - have_pcre=no - LIBS="${r_save_LIBS}" -@@ -40844,6 +40843,7 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $r_cv_have_pcre832" >&5 - $as_echo "$r_cv_have_pcre832" >&6; } - fi -+fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PCRE support suffices" >&5 - $as_echo_n "checking whether PCRE support suffices... " >&6; } -diff --git a/m4/R.m4 b/m4/R.m4 -index fb35a5f..67cdd07 100644 ---- a/m4/R.m4 -+++ b/m4/R.m4 -@@ -3190,7 +3190,6 @@ int main() { - #endif - } - ]])], [r_cv_have_pcre820=yes], [r_cv_have_pcre820=no], [r_cv_have_pcre820=no])]) --fi - if test "x${r_cv_have_pcre820}" != xyes; then - have_pcre=no - LIBS="${r_save_LIBS}" -@@ -3213,6 +3212,7 @@ int main() { - } - ]])], [r_cv_have_pcre832=yes], [r_cv_have_pcre832=no], [r_cv_have_pcre832=no])]) - fi -+fi - - AC_MSG_CHECKING([whether PCRE support suffices]) - if test "x${r_cv_have_pcre820}" != xyes; then --- -2.16.1 - diff --git a/build/pkgs/r/patches/rcmd_exec.patch b/build/pkgs/r/patches/rcmd_exec.patch deleted file mode 100644 index f743e4791c5..00000000000 --- a/build/pkgs/r/patches/rcmd_exec.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 746b6908518c9725fece85270c587b5b110c08d3 Mon Sep 17 00:00:00 2001 -From: Emmanuel Charpentier -Date: Wed, 14 Mar 2018 19:30:37 +0100 -Subject: [PATCH 9/9] rcmd_exec - -On Cygwin some of the scripts in $R_HOME/bin can fail to be recognized -as executable, because they do no contain a shebang line and, depending -on the ACL settings in the Cygwin mount, may not have an executable flag -either. This results in the scripts not being run properly. It's fine -to just check that they exist. See https://trac.sagemath.org/ticket/20655 - ---- - src/scripts/Rcmd.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/scripts/Rcmd.in b/src/scripts/Rcmd.in -index 76d78d5..4b92483 100644 ---- a/src/scripts/Rcmd.in -+++ b/src/scripts/Rcmd.in -@@ -50,7 +50,7 @@ case "${1}" in - exit 1 - ;; - *) -- if test -x "${R_HOME}/bin/${1}"; then -+ if test -f "${R_HOME}/bin/${1}"; then - cmd="${R_HOME}/bin/${1}" - else - cmd="${1}" --- -2.16.1 - diff --git a/build/pkgs/r/spkg-check.in b/build/pkgs/r/spkg-check.in deleted file mode 100644 index 27cd9419538..00000000000 --- a/build/pkgs/r/spkg-check.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -$MAKE check diff --git a/build/pkgs/r/spkg-install.in b/build/pkgs/r/spkg-install.in deleted file mode 100644 index c63ff768f5b..00000000000 --- a/build/pkgs/r/spkg-install.in +++ /dev/null @@ -1,123 +0,0 @@ -# r uses grep output during its build -unset GREP_OPTIONS - -# Make sure CPPFLAGS and LDFLAGS are set to something (even the empty -# string) to prevent R from overriding them. Note: LDFLAGS is set by default. -# The --with-readline configure option only understands yes/no -# and cannot be used to pass this path. -CPPFLAGS="$CPPFLAGS" - -# #29170: Compilation errors caused by a silently failing configure check -# "for type of 'hidden' Fortran character lengths" -# on ubuntu-bionic-minimal, ubuntu-eoan/focal-minimal, debian-buster/bullseye/sid-minimal, -# linuxmint-19.3-minimal, archlinux-latest-minimal -CFLAGS="$CFLAGS_NON_NATIVE -fPIC" -FCFLAGS="$FCFLAGS_NON_NATIVE -fPIC" - -export CFLAGS CPPFLAGS FCFLAGS LDFLAGS - -if [ "$UNAME" = "Darwin" ]; then - # Put fake java on the PATH for OSX - export PATH="$(pwd)/bin:$PATH" -fi - -# Note by Karl-Dieter Crisman, April 12th 2010. X support would be nice -# to have in OSX, but see -# http://CRAN.R-project.org/bin/macosx/RMacOSX-FAQ.html#X11-window-server-_0028optional_0029 -# for how differently this would have to be handled on different OSX -# versions, none trivially. In any case, aqua, which we enable, -# performs the same function on OSX. -# -# Also, see #12172: for now, anyway, we disable X support on OS X. -# -# Note by David Kirkby, Feb 16th 2010. /usr/include/X11/Xwindows.h does -# not exist on Solaris, but R configures OK with X support. Hence I've added -# a more specific test on Solaris, by testing for a library. That library -# exists both on Solaris 10 03/2005 (SPARC) and on OpenSolaris. -if [ "$UNAME" = "Darwin" ]; then - XSUPPORT=no -elif [ -f /usr/include/X11/Xwindows.h ]; then - XSUPPORT=yes -elif [ "$UNAME" = "SunOS" ] && [ -f /usr/X11/lib/libXv.so ] ; then - XSUPPORT=yes -else - XSUPPORT=no -fi - -R_CONFIGURE_BLAS="--with-blas=$(pkg-config --libs blas)" -R_CONFIGURE_LAPACK="--with-lapack=$(pkg-config --libs lapack)" -echo "R_CONFIGURE_BLAS=$R_CONFIGURE_BLAS" -echo "R_CONFIGURE_LAPACK=$R_CONFIGURE_LAPACK" - -if [ "$UNAME" = "Darwin" ]; then - # We don't want to install R as a library framework on OSX - R_CONFIGURE="--enable-R-framework=no $R_CONFIGURE" - # OS X 10.10 and/or Xcode 6.3 and over broke the R installation. See - # http://trac.sagemath.org/ticket/18254. - if [ $MACOSX_VERSION -ge 14 ]; then - echo "OS X 10.$[$MACOSX_VERSION-4] Configuring R without aqua support." - R_CONFIGURE="--with-aqua=no $R_CONFIGURE" - fi - if [ $MACOSX_VERSION -ge 16 ]; then - echo "OS X 10.$[$MACOSX_VERSION-4] Building with clang." - CC=clang - fi -fi - -if [ "$SAGE_FAT_BINARY" = yes ]; then - echo "Disabling ICU, OpenMP for a binary build" - R_CONFIGURE="--without-ICU --disable-openmp $R_CONFIGURE" -elif [ "$UNAME" = "SunOS" ]; then - # Note by David Kirkby, 16th Feb 2010. Even after adding the iconv library - # R would not build properly on Solaris 10, complaining of undefined symbols - # uiter_setUTF8 and ucol_strcollIter - # After an email to r-help@r-project.org, Ei-ji Nakama (rim.nakama@gmail.com) - # emailed me and said the option --without-ICU might help, which it did. I don't see - # this option documented, but for now at least, it does allow R to build. - - echo "Disabling ICU on Solaris, using an undocumented option --without-ICU" - echo "since the ICU library is not included on Solaris." - R_CONFIGURE="--without-ICU $R_CONFIGURE" -fi - -cd src - -if [ "$UNAME" = "Darwin" ]; then - # Fixing install_name(s) - sed -i -e 's:\"-install_name :\"-install_name ${libdir}/R/lib/:' configure - sed -i -e "/SHLIB_EXT/s/\.so/.dylib/" configure -fi - -# Don't override R_HOME_DIR in local/bin/R while building R. -# See patches/R.sh.patch -export SAGE_BUILDING_R=yes - -R_HOME="$SAGE_LOCAL"/lib/R -# Set LDFLAGS as it is done in sage-env for $SAGE_LOCAL/lib -LDFLAGS="-L$R_HOME/lib -Wl,-rpath,$R_HOME/lib $LDFLAGS" -if [ "$UNAME" = "Linux" ]; then - LDFLAGS="-Wl,-rpath-link,$R_HOME/lib $LDFLAGS" -fi -export LDFLAGS - -config() { - sdh_configure --enable-R-shlib --with-recommended-packages \ - --with-readline=yes --with-x=$XSUPPORT \ - "$R_CONFIGURE_BLAS" "$R_CONFIGURE_LAPACK" \ - $R_CONFIGURE -} - -if ! (config); then - echo "Configuring R without X11" - export XSUPPORT=no - config -fi - -# Build R -sdh_make R - -# needed for help system -sdh_make vignettes - -# Install new version -sdh_make_install diff --git a/build/pkgs/r/spkg-legacy-uninstall b/build/pkgs/r/spkg-legacy-uninstall deleted file mode 100755 index 32892b79a91..00000000000 --- a/build/pkgs/r/spkg-legacy-uninstall +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash -# Remove old install -rm -rf "$SAGE_LOCAL"/lib/r -rm -rf "$SAGE_LOCAL"/lib/R -rm -rf "$SAGE_LOCAL"/lib/R.old -rm -rf "$SAGE_LOCAL"/lib/libRblas.* "$SAGE_LOCAL"/lib/libRlapack.* "$SAGE_LOCAL"/lib/libR.* -rm -f "$SAGE_LOCAL"/bin/R* diff --git a/build/pkgs/r/spkg-src b/build/pkgs/r/spkg-src deleted file mode 100755 index 23ce98c4702..00000000000 --- a/build/pkgs/r/spkg-src +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -## What do we want ? -VERSION=$(cat package-version.txt | sed -re "s/^(.*)\\.p.+$/\\1/") -TARGET_TARBALL=r-$VERSION.tar.gz -SOURCE_TARBALL=R-$VERSION.tar.gz - -set -e - -wget http://cran.r-project.org/src/base/R-3/$SOURCE_TARBALL -mv $SOURCE_TARBALL $SAGE_ROOT/upstream/$TARGET_TARBALL - -sage --package fix-checksum From cbcff37cf7e95a51bfa511a6aeb342ced2989e2e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 11:40:36 -0700 Subject: [PATCH 044/350] build/pkgs/rpy2: Mark as not required when there is no R --- build/pkgs/r/dependencies | 4 ++++ build/pkgs/r/type | 2 +- build/pkgs/rpy2/spkg-configure.m4 | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/r/dependencies create mode 100644 build/pkgs/rpy2/spkg-configure.m4 diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies new file mode 100644 index 00000000000..c34daf966bd --- /dev/null +++ b/build/pkgs/r/dependencies @@ -0,0 +1,4 @@ +$(BLAS) gfortran iconv readline bzip2 liblzma pcre curl | pkgconf + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/r/type b/build/pkgs/r/type index a6a7b9cd726..134d9bc32d5 100644 --- a/build/pkgs/r/type +++ b/build/pkgs/r/type @@ -1 +1 @@ -standard +optional diff --git a/build/pkgs/rpy2/spkg-configure.m4 b/build/pkgs/rpy2/spkg-configure.m4 new file mode 100644 index 00000000000..c9831c6b60a --- /dev/null +++ b/build/pkgs/rpy2/spkg-configure.m4 @@ -0,0 +1,14 @@ +SAGE_SPKG_CONFIGURE([rpy2], [ + sage_spkg_install_rpy2=yes + ], [dnl REQUIRED-CHECK + AC_REQUIRE([SAGE_SPKG_CONFIGURE_R]) + dnl rpy2 is only needed when there is a usable system R + AS_VAR_IF([sage_spkg_install_r], [yes], [dnl + AS_VAR_IF([sage_use_system_r], [installed], [dnl + dnl Legacy SPKG installation of r + AS_VAR_SET([SPKG_REQUIRE], [yes]) + ], [dnl No system package, no legacy SPKG installation + AS_VAR_SET([SPKG_REQUIRE], [no]) + ]) + ]) +]) From 004bac5988061dcdcae9a2634fb71811e73127c0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 11:43:54 -0700 Subject: [PATCH 045/350] build/pkgs/r: Restore spkg-legacy-uninstall as spkg-uninstall script --- build/pkgs/r/spkg-uninstall | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 build/pkgs/r/spkg-uninstall diff --git a/build/pkgs/r/spkg-uninstall b/build/pkgs/r/spkg-uninstall new file mode 100755 index 00000000000..32892b79a91 --- /dev/null +++ b/build/pkgs/r/spkg-uninstall @@ -0,0 +1,7 @@ +#! /usr/bin/env bash +# Remove old install +rm -rf "$SAGE_LOCAL"/lib/r +rm -rf "$SAGE_LOCAL"/lib/R +rm -rf "$SAGE_LOCAL"/lib/R.old +rm -rf "$SAGE_LOCAL"/lib/libRblas.* "$SAGE_LOCAL"/lib/libRlapack.* "$SAGE_LOCAL"/lib/libR.* +rm -f "$SAGE_LOCAL"/bin/R* From 77a2474551a0761253a5a59e609a32a8de560f10 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 11:52:29 -0700 Subject: [PATCH 046/350] build/make/Makefile.in: When uninstalling script packages, remove all versions of stamp files --- build/make/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 7ea00813a55..9ba8f4b9b75 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -650,7 +650,7 @@ $(1)-$(4)-no-deps: SAGE_SPKG_WHEELS=$$($(4))/var/lib/sage/wheels \ SAGE_INST_LOCAL=$$($(4)) \ sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ - rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-*" && \ + rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)"-* && \ touch "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2)"; \ else ( \ echo; \ @@ -677,7 +677,7 @@ $(1)-$(4)-uninstall: . '$$(SAGE_ROOT)/build/bin/sage-build-env-config' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env' && \ '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-uninstall' - -rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2)" + -rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)"-* $(1)-uninstall: $(1)-$(4)-uninstall From 7069512f71d1ca689f0d3e34a22d7d04c27a2adb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 12:00:02 -0700 Subject: [PATCH 047/350] build/pkgs/rpy2: Update to 3.5.3 --- build/pkgs/rpy2/checksums.ini | 6 +++--- build/pkgs/rpy2/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/rpy2/checksums.ini b/build/pkgs/rpy2/checksums.ini index 00cd4c4f123..0481937131e 100644 --- a/build/pkgs/rpy2/checksums.ini +++ b/build/pkgs/rpy2/checksums.ini @@ -1,5 +1,5 @@ tarball=rpy2-VERSION.tar.gz -sha1=6436fc9bfc3118d6551c0e2a06d9ec2eb389c28a -md5=fd789967d3e46744cb1b2c4e55f47839 -cksum=906818309 +sha1=40cc7ab04bdb81e027e1a61c041a401ea116e812 +md5=22d7611a65f5c05c734d40545b955a9c +cksum=2952551865 upstream_url=https://pypi.io/packages/source/r/rpy2/rpy2-VERSION.tar.gz diff --git a/build/pkgs/rpy2/package-version.txt b/build/pkgs/rpy2/package-version.txt index 9c25013dbb8..444877d48fb 100644 --- a/build/pkgs/rpy2/package-version.txt +++ b/build/pkgs/rpy2/package-version.txt @@ -1 +1 @@ -3.3.6 +3.5.3 From 5e3e4bee3dfddd012cc734afb94863d19566e63b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 12:06:54 -0700 Subject: [PATCH 048/350] build/pkgs/r/spkg-configure.m4: Remove depcheck --- build/pkgs/r/spkg-configure.m4 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/pkgs/r/spkg-configure.m4 b/build/pkgs/r/spkg-configure.m4 index dafa9113ece..7440a495117 100644 --- a/build/pkgs/r/spkg-configure.m4 +++ b/build/pkgs/r/spkg-configure.m4 @@ -1,7 +1,6 @@ SAGE_SPKG_CONFIGURE([r], [ m4_pushdef([SAGE_R_MINVER],["3.4.4"]) - SAGE_SPKG_DEPCHECK([openblas iconv readline bzip2 liblzma pcre curl], [ - AS_CASE([$host], + AS_CASE([$host], [*-*-cygwin*], [ dnl #29486: rpy2 2.8.x does not build against system R on cygwin. sage_spkg_install_r=yes @@ -16,7 +15,6 @@ SAGE_SPKG_CONFIGURE([r], [ sage_spkg_install_r=no ]) ], [sage_spkg_install_r=yes]) - ]) ]) m4_popdef([SAGE_R_MINVER]) ]) From 54c0b55c40f4989ad9ecce535205f6a9322f40c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 12:11:24 -0700 Subject: [PATCH 049/350] build/pkgs/rpy2/patches/716.patch: Remove (upstreamed) --- build/pkgs/rpy2/patches/716.patch | 89 ------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 build/pkgs/rpy2/patches/716.patch diff --git a/build/pkgs/rpy2/patches/716.patch b/build/pkgs/rpy2/patches/716.patch deleted file mode 100644 index 8446b281633..00000000000 --- a/build/pkgs/rpy2/patches/716.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 87d0f82e2f4be94893881913018ca9085c0ff8e5 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Fri, 3 Jul 2020 12:47:41 -0700 -Subject: [PATCH] setup.py: Print CFFI configuration messages only on build - ---- - setup.py | 44 ++++++++++++++++++++++++++------------------ - 1 file changed, 26 insertions(+), 18 deletions(-) - -diff --git a/setup.py b/setup.py -index e4337838..7fead893 100755 ---- a/setup.py -+++ b/setup.py -@@ -21,6 +21,7 @@ - from rpy2 import situation - - from setuptools import setup -+from distutils.command.build import build as du_build - - PACKAGE_NAME = 'rpy2' - pack_version = __import__('rpy2').__version__ -@@ -111,7 +112,6 @@ def get_r_c_extension_status(): - - - cffi_mode = situation.get_cffi_mode() --print('cffi mode: %s' % cffi_mode) - c_extension_status = get_r_c_extension_status() - if cffi_mode == situation.CFFI_MODE.ABI: - cffi_modules = ['rpy2/_rinterface_cffi_build.py:ffibuilder_abi'] -@@ -135,6 +135,30 @@ def get_r_c_extension_status(): - # This should never happen. - raise ValueError('Invalid value for cffi_mode') - -+class build(du_build): -+ -+ def run(self): -+ print('cffi mode: %s' % cffi_mode) -+ -+ du_build.run(self) -+ -+ print('---') -+ print(cffi_mode) -+ if cffi_mode in (situation.CFFI_MODE.ABI, -+ situation.CFFI_MODE.BOTH, -+ situation.CFFI_MODE.ANY): -+ print('ABI mode interface built.') -+ if cffi_mode in (situation.CFFI_MODE.API, -+ situation.CFFI_MODE.BOTH): -+ print('API mode interface built.') -+ if cffi_mode == situation.CFFI_MODE.ANY: -+ if c_extension_status == COMPILATION_STATUS.OK: -+ print('API mode interface built.') -+ else: -+ print('API mode interface not built because: %s' % c_extension_status) -+ print('To change the API/ABI build mode, set or modify the environment ' -+ 'variable RPY2_CFFI_MODE.') -+ - LONG_DESCRIPTION = """ - Python interface to the R language. - -@@ -168,6 +192,7 @@ def get_r_c_extension_status(): - install_requires=requires + ['cffi>=1.10.0'], - setup_requires=['cffi>=1.10.0'], - cffi_modules=cffi_modules, -+ cmdclass = dict(build=build), - package_dir=pack_dir, - packages=([PACKAGE_NAME] + - ['{pack_name}.{x}'.format(pack_name=PACKAGE_NAME, x=x) -@@ -193,20 +218,3 @@ def get_r_c_extension_status(): - package_data={'rpy2': ['rinterface_lib/R_API.h', - 'rinterface_lib/R_API_eventloop.h']} - ) -- -- print('---') -- print(cffi_mode) -- if cffi_mode in (situation.CFFI_MODE.ABI, -- situation.CFFI_MODE.BOTH, -- situation.CFFI_MODE.ANY): -- print('ABI mode interface built and installed.') -- if cffi_mode in (situation.CFFI_MODE.API, -- situation.CFFI_MODE.BOTH): -- print('API mode interface built and installed.') -- if cffi_mode == situation.CFFI_MODE.ANY: -- if c_extension_status == COMPILATION_STATUS.OK: -- print('API mode interface built and installed.') -- else: -- print('API mode interface not build because: %s' % c_extension_status) -- print('To change the API/ABI build mode, set or modify the environment ' -- 'variable RPY2_CFFI_MODE.') From 9887c7e2ebf8082eb9dd17e8c2c1987b912b6d19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 12:13:38 -0700 Subject: [PATCH 050/350] build/pkgs/rpy2/patches/setup-no-pytest.patch: Remove, obsolete --- build/pkgs/rpy2/patches/setup-no-pytest.patch | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 build/pkgs/rpy2/patches/setup-no-pytest.patch diff --git a/build/pkgs/rpy2/patches/setup-no-pytest.patch b/build/pkgs/rpy2/patches/setup-no-pytest.patch deleted file mode 100644 index 91cb5127572..00000000000 --- a/build/pkgs/rpy2/patches/setup-no-pytest.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/setup.py b/setup.py -index a9f96f8..7ba69a1 100755 ---- a/setup.py -+++ b/setup.py -@@ -142,7 +142,7 @@ ipython. - if __name__ == '__main__': - pack_dir = {PACKAGE_NAME: os.path.join(package_prefix, 'rpy2')} - -- requires = ['pytest', 'jinja2', 'pytz', 'tzlocal'] -+ requires = ['jinja2', 'pytz', 'tzlocal'] - - setup( - name=PACKAGE_NAME, From e54b60c3ac14235792f3ffec9528da7032256eb6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 12:51:53 -0700 Subject: [PATCH 051/350] build/pkgs/r/spkg-configure.m4: Bump required r version for rpy2 --- build/pkgs/r/spkg-configure.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/pkgs/r/spkg-configure.m4 b/build/pkgs/r/spkg-configure.m4 index 7440a495117..b31f6bef2ec 100644 --- a/build/pkgs/r/spkg-configure.m4 +++ b/build/pkgs/r/spkg-configure.m4 @@ -1,5 +1,6 @@ SAGE_SPKG_CONFIGURE([r], [ - m4_pushdef([SAGE_R_MINVER],["3.4.4"]) + dnl https://rpy2.github.io/doc/v3.4.x/html/overview.html#requirements + m4_pushdef([SAGE_R_MINVER],["3.5"]) AS_CASE([$host], [*-*-cygwin*], [ dnl #29486: rpy2 2.8.x does not build against system R on cygwin. From 83a751a186e9ed0f38d549b69b16bb28e0126e70 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 13:05:47 -0700 Subject: [PATCH 052/350] build/pkgs/rpy2: Downgrade to 3.4.5 --- build/pkgs/rpy2/checksums.ini | 6 +++--- build/pkgs/rpy2/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/rpy2/checksums.ini b/build/pkgs/rpy2/checksums.ini index 0481937131e..ece539eec53 100644 --- a/build/pkgs/rpy2/checksums.ini +++ b/build/pkgs/rpy2/checksums.ini @@ -1,5 +1,5 @@ tarball=rpy2-VERSION.tar.gz -sha1=40cc7ab04bdb81e027e1a61c041a401ea116e812 -md5=22d7611a65f5c05c734d40545b955a9c -cksum=2952551865 +sha1=7d236c0c6982333b20b6a126f0c17a5481fea64b +md5=8842b153925a2eca21e2552e964facbb +cksum=1249008138 upstream_url=https://pypi.io/packages/source/r/rpy2/rpy2-VERSION.tar.gz diff --git a/build/pkgs/rpy2/package-version.txt b/build/pkgs/rpy2/package-version.txt index 444877d48fb..4f5e69734c9 100644 --- a/build/pkgs/rpy2/package-version.txt +++ b/build/pkgs/rpy2/package-version.txt @@ -1 +1 @@ -3.5.3 +3.4.5 From 328db20fe8f2cc1aa50abfd8322aa127de3f2e21 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Mon, 8 Aug 2022 14:13:44 +0100 Subject: [PATCH 053/350] Allow DFS starting from root_vertex --- src/sage/graphs/edge_connectivity.pyx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 071b148433e..3a5a4d2655c 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -364,6 +364,12 @@ cdef class GabowEdgeConnectivity: cdef int njoins = 0 cdef int z + + # There's only one f-tree, so we already have a complete k-intersection + # We save the edges and advance to the next iteration + if self.num_start_f_trees <= 1: + self.re_init(tree) + # There are several f-trees, and we try to join them while njoins < self.num_start_f_trees-1: # Get the root of an active subtree or INT_MAX if none exists z = self.choose_root() @@ -422,7 +428,7 @@ cdef class GabowEdgeConnectivity: self.root[j] = j self.forests[j] = True - self.num_start_f_trees = 1 + self.num_start_f_trees = 0 # Initialize T_k to be a DFS spanning forest of G \ T self.compute_dfs_tree() @@ -448,9 +454,6 @@ cdef class GabowEdgeConnectivity: for i in range(self.n): self.visited[i] = False - # Avoid considering the root - self.visited[self.root_vertex] = True - for r in range(self.n): if not self.visited[r]: # Make this vertex the root of the following dfs tree @@ -479,8 +482,9 @@ cdef class GabowEdgeConnectivity: # Visit outgoing arcs of current vertex for e_id in self.g_out[u]: v = self.my_to[e_id] - # Ensure a vertex is not visited and does not a proven k-intersection edge - if not self.visited[v] and not self.T[e_id]: + # Ensure a vertex is not visited, is not a proven k-intersection edge + # and root_vertex remains deficient + if not self.visited[v] and not self.T[e_id] and v != self.root_vertex: # Make current vertex belong to the f_tree rooted at r self.root[v] = r self.forests[v] = False @@ -934,7 +938,6 @@ cdef class GabowEdgeConnectivity: for j in range(self.m): if self.my_edge_state[j] != self.UNUSED: self.tree_edges[self.my_edge_state[j]].push_back(j) - # All True edges in T correspond to the proven complete (k−1)-intersection of G self.T[j] = True for j in range(tree + 1): From 0158e181079e17d015ccb2b9330cf74de73c4ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nadia=20Lafreni=C3=A8re?= Date: Tue, 9 Aug 2022 11:04:01 -0400 Subject: [PATCH 054/350] Improvements to from_lehmer_cocode: accepts a tuple, reduces number of subtractions --- src/sage/combinat/permutation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index f7b95088c0a..e80e4f05a5c 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -7517,12 +7517,12 @@ def from_lehmer_cocode(lehmer, parent=Permutations()): [2, 1, 5, 4, 3] """ p = [] - i = 1 - lehmer.reverse() - open_spots = list(range(1,len(lehmer)+1)) - for ivi in lehmer: - p.append(open_spots.pop(len(lehmer)-i-ivi)) - i += 1 + ell = len(lehmer) + i = ell-1 + open_spots = list(range(1, ell+1)) + for ivi in reversed(lehmer): + p.append(open_spots.pop(i-ivi)) + i -= 1 p.reverse() return parent(p) From 0912bd041fdf28e80f9b47115ef72433518a96c6 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 20 Aug 2022 14:45:35 +0200 Subject: [PATCH 055/350] trac #34394: clean src/sage/graphs/generic_graph.py - part 6 --- src/sage/graphs/generic_graph.py | 235 +++++++++++++++++-------------- 1 file changed, 127 insertions(+), 108 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 23e66648fb2..218612d145f 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -8165,9 +8165,9 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, - solver=None, constraint_generation=None, - verbose=0, verbose_constraints=False, - *, integrality_tolerance=1e-3): + solver=None, constraint_generation=None, + verbose=0, verbose_constraints=False, + *, integrality_tolerance=1e-3): r""" Solve the traveling salesman problem (TSP) @@ -8392,9 +8392,11 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, # Associating a weight to a label if use_edge_labels: - weight = lambda l: 1 if l is None else l + def weight(label): + return 1 if label is None else label else: - weight = lambda l: 1 + def weight(label): + return 1 ######################## # 0 or 1 vertex graphs # @@ -8408,7 +8410,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, ##################### if self.order() == 2: - uu,vv = list(self) + uu, vv = list(self) if self.is_directed(): if self.has_edge(uu, vv) and self.has_edge(vv, uu): if self.allows_multiple_edges(): @@ -8433,7 +8435,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, edges = self.edges(sort=True, key=weight)[:2] answer = self.subgraph(edges=edges, immutable=self.is_immutable()) answer.set_pos(self.get_pos()) - answer.name("TSP from "+self.name()) + answer.name("TSP from " + self.name()) return answer raise EmptySetError("the given graph is not Hamiltonian") @@ -8466,7 +8468,6 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, else: g = self - if constraint_generation is None: if g.density() > .7: constraint_generation = False @@ -8495,13 +8496,13 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, # Objective function if use_edge_labels: - p.set_objective(p.sum(weight(l)*b[u,v] for u,v,l in g.edge_iterator())) + p.set_objective(p.sum(weight(l) * b[u, v] for u, v, l in g.edge_iterator())) # All the vertices have in-degree 1 and out-degree 1 for v in g: - p.add_constraint(p.sum(b[u,v] for u in g.neighbor_in_iterator(v)), + p.add_constraint(p.sum(b[u, v] for u in g.neighbor_in_iterator(v)), min=1, max=1) - p.add_constraint(p.sum(b[v,u] for u in g.neighbor_out_iterator(v)), + p.add_constraint(p.sum(b[v, u] for u in g.neighbor_out_iterator(v)), min=1, max=1) # Initial Solve @@ -8514,9 +8515,9 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, # We build the DiGraph representing the current solution h = DiGraph() b_val = p.get_values(b, convert=bool, tolerance=integrality_tolerance) - for u,v,l in g.edge_iterator(): - if b_val[u,v]: - h.add_edge(u,v,l) + for u, v, l in g.edge_iterator(): + if b_val[u, v]: + h.add_edge(u, v, l) # If there is only one circuit, we are done ! cc = h.connected_components(sort=False) @@ -8527,12 +8528,11 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, for c in cc: if verbose_constraints: print("Adding a constraint on set", c) - p.add_constraint(p.sum(b[u,v] for u,v in - g.edge_boundary(c, labels=False)), - min=1) + p.add_constraint(p.sum(b[u, v] for u, v in g.edge_boundary(c, labels=False)), + min=1) try: - p.solve(log = verbose) + p.solve(log=verbose) except MIPSolverException: raise EmptySetError("the given graph is not Hamiltonian") @@ -8545,16 +8545,16 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, # Objective function if use_edge_labels: - p.set_objective(p.sum(weight(l) * b[frozenset((u,v))] for u,v,l in g.edge_iterator())) + p.set_objective(p.sum(weight(l) * b[frozenset((u, v))] for u, v, l in g.edge_iterator())) # All the vertices have degree 2 for v in g: - p.add_constraint(p.sum(b[frozenset((u,v))] for u in g.neighbor_iterator(v)), + p.add_constraint(p.sum(b[frozenset((u, v))] for u in g.neighbor_iterator(v)), min=2, max=2) # Initial Solve try: - p.solve(log = verbose) + p.solve(log=verbose) except MIPSolverException: raise EmptySetError("the given graph is not Hamiltonian") @@ -8562,7 +8562,7 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, # We build the DiGraph representing the current solution h = Graph() b_val = p.get_values(b, convert=bool, tolerance=integrality_tolerance) - h.add_edges((u,v,l) for u,v,l in g.edge_iterator() if b_val[frozenset((u,v))]) + h.add_edges((u, v, l) for u, v, l in g.edge_iterator() if b_val[frozenset((u, v))]) # If there is only one circuit, we are done ! cc = h.connected_components(sort=False) @@ -8573,8 +8573,8 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, for c in cc: if verbose_constraints: print("Adding a constraint on set", c) - p.add_constraint(p.sum(b[frozenset((u,v))] for u,v in g.edge_boundary(c, labels=False)), - min=2) + p.add_constraint(p.sum(b[frozenset((u, v))] for u, v in g.edge_boundary(c, labels=False)), + min=2) try: p.solve(log=verbose) @@ -8602,27 +8602,27 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, if g.is_directed(): # All the vertices have in-degree 1 and out-degree 1 for v in g: - p.add_constraint(p.sum(f[u,v] for u in g.neighbor_in_iterator(v)), + p.add_constraint(p.sum(f[u, v] for u in g.neighbor_in_iterator(v)), min=1, max=1) - p.add_constraint(p.sum(f[v,u] for u in g.neighbor_out_iterator(v)), + p.add_constraint(p.sum(f[v, u] for u in g.neighbor_out_iterator(v)), min=1, max=1) # r is greater than f vertex_to_int = {u: i for i, u in enumerate(g)} - for u,v in g.edge_iterator(labels=None): - if g.has_edge(v,u): + for u, v in g.edge_iterator(labels=None): + if g.has_edge(v, u): if vertex_to_int[u] < vertex_to_int[v]: - p.add_constraint(r[u,v] + r[v,u]- f[u,v] - f[v,u], min=0) + p.add_constraint(r[u, v] + r[v, u] - f[u, v] - f[v, u], min=0) # no 2-cycles - p.add_constraint(f[u,v] + f[v,u], max=1) + p.add_constraint(f[u, v] + f[v, u], max=1) else: - p.add_constraint(r[u,v] + r[v,u] - f[u,v], min=0) + p.add_constraint(r[u, v] + r[v, u] - f[u, v], min=0) if use_edge_labels: - p.set_objective(p.sum(weight(l) * f[u,v] for u,v,l in g.edge_iterator())) + p.set_objective(p.sum(weight(l) * f[u, v] for u, v, l in g.edge_iterator())) # defining the answer when g is directed from sage.graphs.digraph import DiGraph @@ -8631,44 +8631,42 @@ def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, else: # All the vertices have degree 2 for v in g: - p.add_constraint(p.sum(f[frozenset((u,v))] for u in g.neighbor_iterator(v)), + p.add_constraint(p.sum(f[frozenset((u, v))] for u in g.neighbor_iterator(v)), min=2, max=2) # r is greater than f - for u,v in g.edge_iterator(labels = None): - p.add_constraint( r[u,v] + r[v,u] - f[frozenset((u,v))], min=0) + for u, v in g.edge_iterator(labels=None): + p.add_constraint(r[u, v] + r[v, u] - f[frozenset((u, v))], min=0) if use_edge_labels: - p.set_objective(p.sum(weight(l) * f[frozenset((u,v))] for u,v,l in g.edge_iterator())) + p.set_objective(p.sum(weight(l) * f[frozenset((u, v))] for u, v, l in g.edge_iterator())) from sage.graphs.graph import Graph # defining the answer when g is not directed tsp = Graph() - # no cycle which does not contain x for v in g: if v != x: - p.add_constraint(p.sum(r[u,v] for u in g.neighbor_iterator(v)), max=1-eps) + p.add_constraint(p.sum(r[u, v] for u in g.neighbor_iterator(v)), max=1 - eps) try: p.solve(log=verbose) f_val = p.get_values(f, convert=bool, tolerance=integrality_tolerance) tsp.add_vertices(g.vertex_iterator()) tsp.set_pos(g.get_pos()) - tsp.name("TSP from "+g.name()) + tsp.name("TSP from " + g.name()) if g.is_directed(): - tsp.add_edges((u,v,l) for u,v,l in g.edge_iterator() if f_val[u,v] == 1) + tsp.add_edges((u, v, l) for u, v, l in g.edge_iterator() if f_val[u, v] == 1) else: - tsp.add_edges((u,v,l) for u,v,l in g.edge_iterator() if f_val[frozenset((u,v))] == 1) + tsp.add_edges((u, v, l) for u, v, l in g.edge_iterator() if f_val[frozenset((u, v))] == 1) return tsp except MIPSolverException: raise EmptySetError("the given graph is not Hamiltonian") - def hamiltonian_cycle(self, algorithm='tsp', solver=None, constraint_generation=None, verbose=0, verbose_constraints=False, *, integrality_tolerance=1e-3): @@ -8943,7 +8941,7 @@ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, # It would be a pity to start a LP if the graph is already acyclic if ((not self.is_directed() and self.is_forest()) or - ( self.is_directed() and self.is_directed_acyclic())): + (self.is_directed() and self.is_directed_acyclic())): if value_only: return 0 return [] @@ -9003,9 +9001,9 @@ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, else: - ###################################### - # Ordering-based MILP Implementation # - ###################################### + ###################################### + # Ordering-based MILP Implementation # + ###################################### p = MixedIntegerLinearProgram(maximization=False, solver=solver) @@ -9014,7 +9012,7 @@ def feedback_vertex_set(self, value_only=False, solver=None, verbose=0, n = self.order() # The removed vertices cover all the back arcs ( third condition ) - for u,v in self.edge_iterator(labels=None): + for u, v in self.edge_iterator(labels=None): p.add_constraint(d[u] - d[v] + n * (b[u] + b[v]), min=1) for u in self: @@ -9222,14 +9220,15 @@ def capacity(z): algorithm = "FF" if (algorithm == "FF"): - return self._ford_fulkerson(x,y, value_only=value_only, integer=integer, use_edge_labels=use_edge_labels) + return self._ford_fulkerson(x, y, value_only=value_only, integer=integer, use_edge_labels=use_edge_labels) elif (algorithm == 'igraph'): vertices = list(self) x_int = vertices.index(x) y_int = vertices.index(y) if use_edge_labels: g_igraph = self.igraph_graph(vertex_list=vertices, - edge_attrs={'capacity':[float(capacity(e[2])) for e in self.edge_iterator()]}) + edge_attrs={'capacity': [float(capacity(e[2])) + for e in self.edge_iterator()]}) maxflow = g_igraph.maxflow(x_int, y_int, 'capacity') else: g_igraph = self.igraph_graph(vertex_list=vertices) @@ -9263,7 +9262,6 @@ def capacity(z): raise ValueError("the algorithm argument has to be equal to either " "\"FF\", \"LP\", \"igraph\", or None") - from sage.numerical.mip import MixedIntegerLinearProgram g = self p = MixedIntegerLinearProgram(maximization=True, solver=solver) @@ -9272,24 +9270,30 @@ def capacity(z): if g.is_directed(): # This function return the balance of flow at X - flow_sum = lambda X: (p.sum(flow[X,v] for u,v in g.outgoing_edge_iterator([X], labels=None)) - - p.sum(flow[u,X] for u,v in g.incoming_edge_iterator([X], labels=None))) + def flow_sum(X): + return (p.sum(flow[X, v] for u, v in g.outgoing_edge_iterator([X], labels=None)) + - p.sum(flow[u, X] for u, v in g.incoming_edge_iterator([X], labels=None))) # The flow leaving x - flow_leaving = lambda X: p.sum(flow[uu,vv] for uu,vv in g.outgoing_edge_iterator([X], labels=None)) + def flow_leaving(X): + return p.sum(flow[uu, vv] for uu, vv in g.outgoing_edge_iterator([X], labels=None)) # The flow to be considered when defining the capacity constraints - capacity_sum = lambda u,v: flow[u,v] + def capacity_sum(u, v): + return flow[u, v] else: # This function return the balance of flow at X - flow_sum = lambda X: p.sum(flow[X,v] - flow[v,X] for v in g[X]) + def flow_sum(X): + return p.sum(flow[X, v] - flow[v, X] for v in g[X]) # The flow leaving x - flow_leaving = lambda X: p.sum(flow[X,vv] for vv in g[X]) + def flow_leaving(X): + return p.sum(flow[X, vv] for vv in g[X]) # The flow to be considered when defining the capacity constraints - capacity_sum = lambda u,v: flow[u,v] + flow[v,u] + def capacity_sum(u, v): + return flow[u, v] + flow[v, u] # Maximizes the flow leaving x p.add_constraint(flow_sum(x) == obj[0]) @@ -9301,8 +9305,8 @@ def capacity(z): p.add_constraint(flow_sum(v), min=0, max=0) # Capacity constraints - for u,v,w in g.edge_iterator(): - p.add_constraint(capacity_sum(u,v), max=capacity(w)) + for u, v, w in g.edge_iterator(): + p.add_constraint(capacity_sum(u, v), max=capacity(w)) # No vertex except the sources can send more than 1 if vertex_bound: @@ -9477,7 +9481,7 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler ValueError: parameter 'k' must be at least 2 """ if k is None: - k = 6 # See [Sey1981]_ + k = 6 # See [Sey1981]_ elif k < 2: raise ValueError("parameter 'k' must be at least 2") @@ -9496,8 +9500,8 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler return solution # If the (di)graph has bridges, the problem is not feasible - if ( (self.is_directed() and not self.is_strongly_connected() and next(self.to_undirected().bridges(), False)) - or (not self.is_directed() and next(self.bridges(), False)) ): + if ((self.is_directed() and not self.is_strongly_connected() and next(self.to_undirected().bridges(), False)) + or (not self.is_directed() and next(self.bridges(), False))): raise EmptySetError("(di)graphs with bridges have no feasible solution") # @@ -9507,13 +9511,13 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler G = copy(self) if self.is_directed() else next(self.orientations()) # We assign flow 1 to loops, if any - solution = DiGraph([list(G), [(u,v,1) for u,v in G.loops(labels=0)]], + solution = DiGraph([list(G), [(u, v, 1) for u, v in G.loops(labels=False)]], loops=G.has_loops(), multiedges=G.has_multiple_edges()) G.allow_loops(False) # We ensure that multiple edges have distinct labels - multiedges = {(u,v,i) for i,(u,v) in enumerate(G.multiple_edges(labels=0))} + multiedges = {(u, v, i) for i, (u, v) in enumerate(G.multiple_edges(labels=0))} G.delete_edges(G.multiple_edges()) G.add_edges(multiedges) @@ -9527,20 +9531,20 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler # # We use a MIP formulation to solve the problem # - from sage.numerical.mip import MixedIntegerLinearProgram,MIPSolverException + from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException p = MixedIntegerLinearProgram(solver=solver) f = p.new_variable(nonnegative=False, integer=True) b = p.new_variable(nonnegative=True, binary=True) # flow conservation constraints for u in G: - p.add_constraint( p.sum(f[e] for e in G.incoming_edge_iterator(u)) - == p.sum(f[e] for e in G.outgoing_edge_iterator(u))) + p.add_constraint(p.sum(f[e] for e in G.incoming_edge_iterator(u)) == + p.sum(f[e] for e in G.outgoing_edge_iterator(u))) # The flow on edge e has value in {-k+1,..., -1, 1, ..., k-1} for e in G.edge_iterator(): - p.add_constraint(p.sum(b[e,i] for i in range(-k+1, k) if i) == 1) - p.add_constraint(f[e] == p.sum(i * b[e,i] for i in range(-k+1, k) if i)) + p.add_constraint(p.sum(b[e, i] for i in range(1 - k, k) if i) == 1) + p.add_constraint(f[e] == p.sum(i * b[e, i] for i in range(1 - k, k) if i)) # We solve the MIP. try: @@ -9551,7 +9555,7 @@ def nowhere_zero_flow(self, k=None, solver=None, verbose=0, *, integrality_toler # Extract and return the solution. If the graph is not directed, we # reverse edges with a negative flow to obtain a positive k-NZF f_val = p.get_values(f, convert=True, tolerance=integrality_tolerance) - for (u,v,_), val in f_val.items(): + for (u, v, _), val in f_val.items(): if self.is_directed() or val > 0: solution.add_edge(u, v, val) else: @@ -9631,9 +9635,11 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only # Whether we should consider the edges labeled if use_edge_labels: - l_capacity=lambda x: 1 if (x is None or x == {}) else (floor(x) if integer else x) + def l_capacity(x): + return 1 if (x is None or x == {}) else (floor(x) if integer else x) else: - l_capacity=lambda x: 1 + def l_capacity(x): + return 1 directed = self.is_directed() @@ -9652,7 +9658,7 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only # Initializing the variables if directed: - for u,v,l in self.edge_iterator(): + for u, v, l in self.edge_iterator(): if l_capacity(l) > 0: capacity[u, v] = l_capacity(l) + capacity.get((u, v), 0) capacity[v, u] = capacity.get((v, u), 0) @@ -9660,7 +9666,7 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only flow[u, v] = 0 flow[v, u] = 0 else: - for u,v,l in self.edge_iterator(): + for u, v, l in self.edge_iterator(): if l_capacity(l) > 0: capacity[u, v] = l_capacity(l) + capacity.get((u, v), 0) capacity[v, u] = l_capacity(l) + capacity.get((v, u), 0) @@ -9671,11 +9677,14 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only # Rewrites a path as a list of edges : # ex : [0,1,2,3,4,5] becomes [(0,1), (1,2), (2,3), (3,4), (4,5)] - path_to_edges = lambda P: zip(P[:-1], P[1:]) + def path_to_edges(P): + return zip(P[:-1], P[1:]) # Rewrites a path as a list of edges labeled with their # available capacity - path_to_labelled_edges = lambda P : [(x_y[0], x_y[1], capacity[x_y[0], x_y[1]] - flow[x_y[0], x_y[1]] + flow[x_y[1], x_y[0]]) for x_y in path_to_edges(P)] + def path_to_labelled_edges(P): + return [(x_y[0], x_y[1], capacity[x_y[0], x_y[1]] - flow[x_y[0], x_y[1]] + flow[x_y[1], x_y[0]]) + for x_y in path_to_edges(P)] # Total flow going from s to t flow_intensity = 0 @@ -9697,7 +9706,7 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only flow_intensity = flow_intensity + epsilon # Updating variables - for uu,vv,ll in edges: + for uu, vv, ll in edges: # The flow on the back arc other = flow[vv, uu] @@ -9817,7 +9826,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, # defining the set of terminals set_terminals = set() - for s,t,_ in terminals: + for s, t, _ in terminals: set_terminals.add(s) set_terminals.add(t) @@ -9827,34 +9836,42 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, # Whether to use edge labels if use_edge_labels: from sage.rings.real_mpfr import RR - capacity = lambda x: x if x in RR else 1 + + def capacity(x): + return x if x in RR else 1 else: - capacity = lambda x: 1 + def capacity(x): + return 1 if g.is_directed(): # This function return the balance of flow at X - flow_sum = lambda i,X: (p.sum(flow[i,(X,v)] for u,v in g.outgoing_edge_iterator([X], labels=None)) - - p.sum(flow[i,(u,X)] for u,v in g.incoming_edge_iterator([X], labels=None))) + def flow_sum(i, X): + return (p.sum(flow[i, (X, v)] for u, v in g.outgoing_edge_iterator([X], labels=None)) + - p.sum(flow[i, (u, X)] for u, v in g.incoming_edge_iterator([X], labels=None))) # The flow leaving x - flow_leaving = lambda i,X: p.sum(flow[i,(uu,vv)] for uu,vv in g.outgoing_edge_iterator([X], labels=None)) + def flow_leaving(i, X): + return p.sum(flow[i, (uu, vv)] for uu, vv in g.outgoing_edge_iterator([X], labels=None)) # the flow to consider when defining the capacity constraints - capacity_sum = lambda i,u,v: flow[i,(u,v)] + def capacity_sum(i, u, v): + return flow[i, (u, v)] else: # This function return the balance of flow at X - flow_sum = lambda i,X: p.sum(flow[i,(X,v)] - flow[i,(v,X)] for v in g.neighbor_iterator(X)) + def flow_sum(i, X): + return p.sum(flow[i, (X, v)] - flow[i, (v, X)] for v in g.neighbor_iterator(X)) # The flow leaving x - flow_leaving = lambda i, X: p.sum(flow[i,(X,vv)] for vv in g.neighbor_iterator(X)) + def flow_leaving(i, X): + return sum(flow[i, (X, vv)] for vv in g.neighbor_iterator(X)) # the flow to consider when defining the capacity constraints - capacity_sum = lambda i,u,v: flow[i,(u,v)] + flow[i,(v,u)] - + def capacity_sum(i, u, v): + return flow[i, (u, v)] + flow[i, (v, u)] # Flow constraints - for i,(s,t,l) in enumerate(terminals): + for i, (s, t, l) in enumerate(terminals): for v in g: if v == s: p.add_constraint(flow_sum(i, v), min=l, max=l) @@ -9864,7 +9881,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, p.add_constraint(flow_sum(i, v), min=0, max=0) # Capacity constraints - for u,v,w in g.edge_iterator(): + for u, v, w in g.edge_iterator(): p.add_constraint(p.sum(capacity_sum(i, u, v) for i in range(len(terminals))), max=capacity(w)) if vertex_bound: @@ -9874,7 +9891,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, # which is an endpoint if v in set_terminals: - for i,(s,t,_) in enumerate(terminals): + for i, (s, t, _) in enumerate(terminals): # only tolerates the commodities of which it is an endpoint if not (v == s or v == t): @@ -9883,7 +9900,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, # which is not an endpoint else: # can stand at most 1 unit of flow through itself - p.add_constraint(p.sum(flow_leaving(i,v) for i in range(len(terminals))), max=1) + p.add_constraint(p.sum(flow_leaving(i, v) for i in range(len(terminals))), max=1) p.set_objective(None) @@ -9900,7 +9917,7 @@ def multicommodity_flow(self, terminals, integer=True, use_edge_labels=False, flow = p.get_values(flow, convert=True, tolerance=integrality_tolerance) # building clean flow digraphs - flow_graphs = [g._build_flow_graph({e: f for (ii,e),f in flow.items() if ii == i}, integer=integer) + flow_graphs = [g._build_flow_graph({e: f for (ii, e), f in flow.items() if ii == i}, integer=integer) for i in range(len(terminals))] # which could be .. graphs ! @@ -9959,7 +9976,7 @@ def _build_flow_graph(self, flow, integer): g = DiGraph() # add significant edges - for (u,v),l in flow.items(): + for (u, v), l in flow.items(): if l: g.add_edge(u, v, l) @@ -10338,10 +10355,10 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, algorithm = algorithm.lower() if algorithm == 'networkx' or algorithm == 'scipy': import networkx - return networkx.pagerank(self.networkx_graph - (weight_function=weight_function), alpha=alpha, - personalization=personalization, weight=weight, - dangling=dangling) + gnx = self.networkx_graph(weight_function=weight_function) + return networkx.pagerank(gnx, alpha=alpha, + personalization=personalization, + weight=weight, dangling=dangling) elif algorithm == 'igraph': # An error will be raised if igraph is not installed if personalization: @@ -10358,7 +10375,7 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, else: raise NotImplementedError("only 'NetworkX', 'Scipy', and 'igraph' are supported") - ### Vertex handlers + # Vertex handlers def add_vertex(self, name=None): r""" @@ -10493,7 +10510,7 @@ def delete_vertex(self, vertex, in_order=False): if in_order: vertex = self.vertices(sort=True)[vertex] if vertex not in self: - raise ValueError("vertex (%s) not in the graph"%str(vertex)) + raise ValueError("vertex (%s) not in the graph" % str(vertex)) # TODO: remove this update from this method which should be as fast # as possible @@ -10544,7 +10561,7 @@ def delete_vertices(self, vertices): vertices = list(vertices) for v in vertices: if v not in self: - raise ValueError("vertex (%s) not in the graph"%str(v)) + raise ValueError("vertex (%s) not in the graph" % str(v)) # TODO: remove this update from this method which should be as fast # as possible @@ -11226,7 +11243,6 @@ def neighbors(self, vertex, closed=False): __getitem__ = neighbors - def merge_vertices(self, vertices): r""" Merge vertices. @@ -11324,14 +11340,14 @@ def merge_vertices(self, vertices): if self.is_directed(): out_edges = self.edge_boundary(vertices) in_edges = self.edge_boundary([v for v in self - if v not in vertices]) + if v not in vertices]) self.delete_vertices(vertices[1:]) self.add_edges((u, v0, l) for (u0, v0, l) in out_edges if u0 != u) self.add_edges((v0, u, l) for (v0, u0, l) in in_edges if u0 != u) else: edges = self.edge_boundary(vertices) self.delete_vertices(vertices[1:]) - add_edges=[] + add_edges = [] for u0, v0, l in edges: if v0 in vertices and v0 != u: add_edges.append((u, u0, l)) @@ -11339,7 +11355,7 @@ def merge_vertices(self, vertices): add_edges.append((u, v0, l)) self.add_edges(add_edges) - ### Edge handlers + # Edge handlers def add_edge(self, u, v=None, label=None): r""" @@ -11518,7 +11534,10 @@ def subdivide_edge(self, *args): sage: g.subdivide_edge(1, 2, "label2", 5) sage: print(g.edges(sort=True)) - [(0, 3, 'label1'), (1, 5, 'label1'), (1, 6, 'label2'), (2, 10, 'label2'), (3, 4, 'label1'), (4, 5, 'label1'), (6, 7, 'label2'), (7, 8, 'label2'), (8, 9, 'label2'), (9, 10, 'label2')] + [(0, 3, 'label1'), (1, 5, 'label1'), (1, 6, 'label2'), + (2, 10, 'label2'), (3, 4, 'label1'), (4, 5, 'label1'), + (6, 7, 'label2'), (7, 8, 'label2'), (8, 9, 'label2'), + (9, 10, 'label2')] If too many arguments are given, an exception is raised :: @@ -11816,8 +11835,8 @@ def contract_edge(self, u, v=None, label=None): if u == v: return - if (self.allows_loops() and (self.allows_multiple_edges() or - not self.has_edge(u, u))): + if (self.allows_loops() and + (self.allows_multiple_edges() or not self.has_edge(u, u))): # add loops for x, y, l in self.edges_incident(v): if set([x, y]) == set([u, v]): From f17f51c2e1f6874cf424aff1384d5deb7bf3064d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 20 Aug 2022 15:18:58 +0200 Subject: [PATCH 056/350] trac #34395: clean src/sage/graphs/generic_graph.py - part 7 --- src/sage/graphs/generic_graph.py | 184 +++++++++++++++---------------- 1 file changed, 86 insertions(+), 98 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 218612d145f..d4e476fe7e3 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -7196,13 +7196,13 @@ def vertex_cut(self, s, t, value_only=True, vertices=False, solver=None, verbose if g.is_directed(): # adjacent vertices belong to the same part except if one of them # belongs to the cut - for x,y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=None): p.add_constraint(v[x] + b[y] - v[y], min=0) else: # adjacent vertices belong to the same part except if one of them # belongs to the cut - for x,y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=None): p.add_constraint(v[x] + b[y] >= v[y]) p.add_constraint(v[y] + b[x] >= v[x]) @@ -7228,7 +7228,6 @@ def vertex_cut(self, s, t, value_only=True, vertices=False, solver=None, verbose answer.append([l0, l1]) return tuple(answer) - def multiway_cut(self, vertices, value_only=False, use_edge_labels=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" @@ -7337,29 +7336,29 @@ def weight(l): p.set_objective(p.sum(weight(l) * cut[good_edge((u, v))] for u, v, l in self.edge_iterator())) if self.is_directed(): - for s,t in chain(combinations(vertices, 2), [(y, x) for x, y in combinations(vertices, 2)]): + for s, t in chain(combinations(vertices, 2), [(y, x) for x, y in combinations(vertices, 2)]): # For each commodity, the source is at height 0 # and the destination is at height 1 - p.add_constraint(height[(s,t),s], min=0, max=0) - p.add_constraint(height[(s,t),t], min=1, max=1) + p.add_constraint(height[(s, t), s], min=0, max=0) + p.add_constraint(height[(s, t), t], min=1, max=1) # given a commodity (s,t), the height of two adjacent vertices u,v # can differ of at most the value of the edge between them - for u,v in self.edge_iterator(labels=False): - p.add_constraint(height[(s,t),u] - height[(s,t),v] - cut[good_edge((u, v))], max=0) + for u, v in self.edge_iterator(labels=False): + p.add_constraint(height[(s, t), u] - height[(s, t), v] - cut[good_edge((u, v))], max=0) else: - for s,t in combinations(vertices, 2): + for s, t in combinations(vertices, 2): # For each commodity, the source is at height 0 # and the destination is at height 1 - p.add_constraint(height[(s,t),s], min=0, max=0) - p.add_constraint(height[(s,t),t], min=1, max=1) + p.add_constraint(height[(s, t), s], min=0, max=0) + p.add_constraint(height[(s, t), t], min=1, max=1) # given a commodity (s,t), the height of two adjacent vertices u,v # can differ of at most the value of the edge between them - for u,v in self.edge_iterator(labels=False): - p.add_constraint(height[(s,t),u] - height[(s,t),v] - cut[good_edge((u,v))], max=0) - p.add_constraint(height[(s,t),v] - height[(s,t),u] - cut[good_edge((u,v))], max=0) + for u, v in self.edge_iterator(labels=False): + p.add_constraint(height[(s, t), u] - height[(s, t), v] - cut[good_edge((u, v))], max=0) + p.add_constraint(height[(s, t), v] - height[(s, t), u] - cut[good_edge((u, v))], max=0) p.solve(log=verbose) cut = p.get_values(cut, convert=bool, tolerance=integrality_tolerance) @@ -7372,7 +7371,6 @@ def weight(l): return [e for e in self.edge_iterator() if cut[good_edge((e[0], e[1]))]] - def max_cut(self, value_only=True, use_edge_labels=False, vertices=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" @@ -7469,30 +7467,30 @@ def good_edge(e): # A vertex has to be in some set for v in g: - p.add_constraint(in_set[0,v] + in_set[1,v], max=1, min=1) + p.add_constraint(in_set[0, v] + in_set[1, v], max=1, min=1) # There is no empty set - p.add_constraint(p.sum(in_set[1,v] for v in g), min=1) - p.add_constraint(p.sum(in_set[0,v] for v in g), min=1) + p.add_constraint(p.sum(in_set[1, v] for v in g), min=1) + p.add_constraint(p.sum(in_set[0, v] for v in g), min=1) if g.is_directed(): # There is no edge from set 0 to set 1 which is not in the cut. # Besides, an edge can only be in the cut if its vertices # belong to different sets - for u,v in g.edge_iterator(labels=None): - p.add_constraint(in_set[0,u] + in_set[1,v] - in_cut[u,v], max=1) - p.add_constraint(in_set[0,u] + in_set[0,v] + in_cut[u,v], max=2) - p.add_constraint(in_set[1,u] + in_set[1,v] + in_cut[u,v], max=2) + for u, v in g.edge_iterator(labels=None): + p.add_constraint(in_set[0, u] + in_set[1, v] - in_cut[u, v], max=1) + p.add_constraint(in_set[0, u] + in_set[0, v] + in_cut[u, v], max=2) + p.add_constraint(in_set[1, u] + in_set[1, v] + in_cut[u, v], max=2) else: # Two adjacent vertices are in different sets if and only if # the edge between them is in the cut - for u,v in g.edge_iterator(labels=None): + for u, v in g.edge_iterator(labels=None): fuv = good_edge((u, v)) - p.add_constraint(in_set[0,u] + in_set[1,v] - in_cut[fuv], max=1) - p.add_constraint(in_set[1,u] + in_set[0,v] - in_cut[fuv], max=1) - p.add_constraint(in_set[0,u] + in_set[0,v] + in_cut[fuv], max=2) - p.add_constraint(in_set[1,u] + in_set[1,v] + in_cut[fuv], max=2) + p.add_constraint(in_set[0, u] + in_set[1, v] - in_cut[fuv], max=1) + p.add_constraint(in_set[1, u] + in_set[0, v] - in_cut[fuv], max=1) + p.add_constraint(in_set[0, u] + in_set[0, v] + in_cut[fuv], max=2) + p.add_constraint(in_set[1, u] + in_set[1, v] + in_cut[fuv], max=2) p.set_objective(p.sum(weight(l) * in_cut[good_edge((u, v))] for u, v, l in g.edge_iterator())) @@ -7515,11 +7513,11 @@ def good_edge(e): a = [] b = [] for v in g: - if in_set[0,v]: + if in_set[0, v]: a.append(v) else: b.append(v) - val.append([a,b]) + val.append([a, b]) return val @@ -7764,9 +7762,11 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", # Associating a weight to a label if use_edge_labels: - weight = lambda x: x if (x is not None and x != {}) else 1 + def weight(x): + return x if (x is not None and x != {}) else 1 else: - weight = lambda x: 1 + def weight(x): + return 1 from sage.numerical.mip import MixedIntegerLinearProgram p = MixedIntegerLinearProgram(solver=solver) @@ -7786,62 +7786,54 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", # if edge uv is used, vu cannot be for u, v in self.edge_iterator(labels=False): if self.has_edge(v, u): - p.add_constraint(edge_used[u,v] + edge_used[v,u] <= 1) + p.add_constraint(edge_used[u, v] + edge_used[v, u] <= 1) # A vertex is used if one of its incident edges is - for u,v in self.edge_iterator(labels=False): - p.add_constraint(vertex_used[v] >= edge_used[u,v]) - p.add_constraint(vertex_used[u] >= edge_used[u,v]) + for u, v in self.edge_iterator(labels=False): + p.add_constraint(vertex_used[v] >= edge_used[u, v]) + p.add_constraint(vertex_used[u] >= edge_used[u, v]) # A path is a tree. If n vertices are used, at most n-1 edges are - p.add_constraint( - p.sum(vertex_used[v] for v in self) - - p.sum(edge_used[e] for e in self.edge_iterator(labels=False)) - == 1) + p.add_constraint(p.sum(vertex_used[v] for v in self) + - p.sum(edge_used[e] for e in self.edge_iterator(labels=False)) + == 1) # A vertex has at most one incoming used edge and at most # one outgoing used edge for v in self: - p.add_constraint( - p.sum(edge_used[u,v] for u in self.neighbor_in_iterator(v)) <= 1) - p.add_constraint( - p.sum(edge_used[v,u] for u in self.neighbor_out_iterator(v)) <= 1) + p.add_constraint(p.sum(edge_used[u, v] for u in self.neighbor_in_iterator(v)) <= 1) + p.add_constraint(p.sum(edge_used[v, u] for u in self.neighbor_out_iterator(v)) <= 1) # r_edge_used is "more" than edge_used, though it ignores # the direction - for u,v in self.edge_iterator(labels=False): - p.add_constraint(r_edge_used[u,v] + r_edge_used[v,u] - >= edge_used[u,v]) + for u, v in self.edge_iterator(labels=False): + p.add_constraint(r_edge_used[u, v] + r_edge_used[v, u] + >= edge_used[u, v]) # No cycles for v in self: - p.add_constraint( - p.sum(r_edge_used[u,v] for u in self.neighbor_iterator(v)) - <= 1-epsilon) + p.add_constraint(p.sum(r_edge_used[u, v] for u in self.neighbor_iterator(v)) + <= 1 - epsilon) # Enforcing the source if asked.. If s is set, it has no # incoming edge and exactly one son if s is not None: - p.add_constraint( - p.sum(edge_used[u,s] for u in self.neighbor_in_iterator(s)), - max=0, min=0) - p.add_constraint( - p.sum(edge_used[s,u] for u in self.neighbor_out_iterator(s)), - min=1, max=1) + p.add_constraint(p.sum(edge_used[u, s] for u in self.neighbor_in_iterator(s)), + max=0, min=0) + p.add_constraint(p.sum(edge_used[s, u] for u in self.neighbor_out_iterator(s)), + min=1, max=1) # Enforcing the destination if asked.. If t is set, it has # no outgoing edge and exactly one parent if t is not None: - p.add_constraint( - p.sum(edge_used[u,t] for u in self.neighbor_in_iterator(t)), - min=1, max=1) - p.add_constraint( - p.sum(edge_used[t,u] for u in self.neighbor_out_iterator(t)), - max=0, min=0) + p.add_constraint(p.sum(edge_used[u, t] for u in self.neighbor_in_iterator(t)), + min=1, max=1) + p.add_constraint(p.sum(edge_used[t, u] for u in self.neighbor_out_iterator(t)), + max=0, min=0) # Defining the objective - p.set_objective( - p.sum(weight(l) * edge_used[u,v] for u, v, l in self.edge_iterator())) + p.set_objective(p.sum(weight(l) * edge_used[u, v] + for u, v, l in self.edge_iterator())) else: # We use edge_used[frozenset((u, v))] to avoid having two different # variables for edge (u, v) @@ -7849,40 +7841,37 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", # A vertex is used if one of its incident edges is for v in self: for u in self.neighbor_iterator(v): - p.add_constraint(vertex_used[v] - edge_used[frozenset((u,v))], min=0) + p.add_constraint(vertex_used[v] - edge_used[frozenset((u, v))], min=0) # A path is a tree. If n vertices are used, at most n-1 edges are - p.add_constraint( - p.sum(vertex_used[v] for v in self) - - p.sum(edge_used[frozenset((u,v))] for u, v in self.edge_iterator(labels=False)), - min=1, max=1) + p.add_constraint(p.sum(vertex_used[v] for v in self) + - p.sum(edge_used[frozenset((u, v))] + for u, v in self.edge_iterator(labels=False)), + min=1, max=1) # A vertex has at most two incident edges used for v in self: - p.add_constraint( - p.sum(edge_used[frozenset((u,v))] for u in self.neighbor_iterator(v)), max=2) + p.add_constraint(p.sum(edge_used[frozenset((u, v))] for u in self.neighbor_iterator(v)), + max=2) # r_edge_used is "more" than edge_used for u, v in self.edge_iterator(labels=False): - p.add_constraint(r_edge_used[u,v] - + r_edge_used[v,u] - - edge_used[frozenset((u,v))], + p.add_constraint(r_edge_used[u, v] + + r_edge_used[v, u] + - edge_used[frozenset((u, v))], min=0) # No cycles for v in self: - p.add_constraint( - p.sum(r_edge_used[u,v] for u in self.neighbor_iterator(v)), - max=1-epsilon) + p.add_constraint(p.sum(r_edge_used[u, v] for u in self.neighbor_iterator(v)), + max=1 - epsilon) # Enforcing the destination if asked.. If s or t are set, # they have exactly one incident edge if s is not None: - p.add_constraint( - p.sum(edge_used[frozenset((s,u))] for u in self.neighbor_iterator(s)), - max=1, min=1) + p.add_constraint(p.sum(edge_used[frozenset((s, u))] for u in self.neighbor_iterator(s)), + max=1, min=1) if t is not None: - p.add_constraint( - p.sum(edge_used[frozenset((t,u))] for u in self.neighbor_iterator(t)), - max=1, min=1) + p.add_constraint(p.sum(edge_used[frozenset((t, u))] for u in self.neighbor_iterator(t)), + max=1, min=1) # Defining the objective - p.set_objective(p.sum(weight(l) * edge_used[frozenset((u,v))] - for u, v, l in self.edge_iterator())) + p.set_objective(p.sum(weight(l) * edge_used[frozenset((u, v))] + for u, v, l in self.edge_iterator())) # Computing the result. No exception has to be raised, as this # problem always has a solution (there is at least one edge, @@ -7891,15 +7880,14 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", edge_used = p.get_values(edge_used, convert=bool, tolerance=integrality_tolerance) vertex_used = p.get_values(vertex_used, convert=bool, tolerance=integrality_tolerance) if self._directed: - g = self.subgraph( - vertices=(v for v in self if vertex_used[v]), - edges=((u,v,l) for u, v, l in self.edge_iterator() - if edge_used[u,v])) + g = self.subgraph(vertices=(v for v in self if vertex_used[v]), + edges=((u, v, l) for u, v, l in self.edge_iterator() + if edge_used[u, v])) else: g = self.subgraph( vertices=(v for v in self if vertex_used[v]), - edges=((u,v,l) for u, v, l in self.edge_iterator() - if edge_used[frozenset((u,v))])) + edges=((u, v, l) for u, v, l in self.edge_iterator() + if edge_used[frozenset((u, v))])) if use_edge_labels: return sum(map(weight, g.edge_labels())), g else: @@ -8058,7 +8046,6 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, else: g = self.copy(immutable=False) - new_s, new_t = s, t if g.is_directed(): # @@ -8098,7 +8085,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, # Set new_s and new_t if possible if new_s is None and new_t is None: - new_s,new_t = ones + new_s, new_t = ones elif new_s is not None and new_t is None: new_t = ones[1] if new_s == ones[0] else ones[0] elif new_s is None and new_t is not None: @@ -8128,7 +8115,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, # source and an edge from it to each vertex of the (di)graph. new_s = g.add_vertex() extra_vertices.append(new_s) - for u in self: # in original set of vertices + for u in self: # in original set of vertices g.add_edge(new_s, u, 0) if new_t is None: @@ -8152,17 +8139,18 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, from sage.categories.sets_cat import EmptySetError try: tsp = g.traveling_salesman_problem(use_edge_labels=use_edge_labels, - maximize=maximize, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) + maximize=maximize, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) except EmptySetError: return (0, None) if use_edge_labels else None tsp.delete_vertices(extra_vertices) tsp.name("Hamiltonian path from {}".format(self.name())) - weight = lambda l: 1 if l is None else l - return (sum(map(weight,tsp.edge_labels())), tsp) if use_edge_labels else tsp + def weight(label): + return 1 if label is None else label + return (sum(map(weight, tsp.edge_labels())), tsp) if use_edge_labels else tsp def traveling_salesman_problem(self, use_edge_labels=False, maximize=False, solver=None, constraint_generation=None, From 7dd7266835fb8922dee1ae87d93029356769ac46 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 20 Aug 2022 16:04:24 +0200 Subject: [PATCH 057/350] trac #34396: clean src/sage/graphs/generic_graph.py - part 8 --- src/sage/graphs/generic_graph.py | 133 ++++++++++++++++--------------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index d4e476fe7e3..f2c94041c51 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -3450,7 +3450,7 @@ def multiple_edges(self, to_undirected=False, labels=True, sort=False): else: multi_edges.extend((u, v) for _ in L_uv) multi_edges.extend((v, u) for _ in L_vu) - + elif not self.has_edge(v, u): L = self.edge_label(u, v) if len(L) > 1: @@ -3773,7 +3773,7 @@ def weighted(self, new=None): else: return bool(self._weighted) - ### Properties + # Properties def antisymmetric(self): r""" @@ -3928,8 +3928,9 @@ def is_bipartite(self, certificate=False): return False color = {} - tree = {} # inheritance of colors along the DFS to recover an odd - # cycle when certificate=True + # inheritance of colors along the DFS to recover an odd + # cycle when certificate=True + tree = {} # For any uncolored vertex in the graph (to ensure we do the right job # when the graph is not connected !) @@ -3989,7 +3990,6 @@ def is_bipartite(self, certificate=False): else: return True - def is_eulerian(self, path=False): r""" Check whether the graph is Eulerian. @@ -4077,7 +4077,7 @@ def is_eulerian(self, path=False): else: # if there was another vertex with the same sign of difference... if uv[(diff + 1) // 2] is not None: - return False # ... the graph is not semi-Eulerian + return False # ... the graph is not semi-Eulerian else: uv[(diff + 1) // 2] = v else: @@ -4140,7 +4140,7 @@ def size(self): num_edges = size - ### Orientations + # Orientations def eulerian_orientation(self): r""" @@ -4376,8 +4376,9 @@ def eulerian_circuit(self, return_vertices=False, labels=True, path=False): else: next_edge = next(g_edge_iter(v)) - if next_edge[0] == v: # in the undirected case we want to - # save the direction of traversal + if next_edge[0] == v: + # in the undirected case we want to save the + # direction of traversal next_edge_new = (next_edge[1], next_edge[0], next_edge[2]) else: next_edge_new = next_edge @@ -4654,7 +4655,10 @@ def wfunction_float(e): # contains fringe_vertex: (weight, vertex_in_tree) for each # fringe vertex. fringe_list = {e[0] if e[0] != v else e[1]: (wfunction_float(e), v) for e in self.edges_incident(v)} - cmp_fun = lambda x: fringe_list[x][0] + + def cmp_fun(x): + return fringe_list[x][0] + for i in range(self.order() - 1): # find the smallest-weight fringe vertex u = min(fringe_list, key=cmp_fun) @@ -4667,7 +4671,7 @@ def wfunction_float(e): fringe_list.pop(u) # update fringe list for e in self.edges_incident(u): - neighbor = e[0] if e[0] !=u else e[1] + neighbor = e[0] if e[0] != u else e[1] if neighbor in tree: continue w = wfunction_float(e) @@ -4712,7 +4716,7 @@ def wfunction_float(e): G = networkx.Graph([(e[0], e[1], {'weight': wfunction_float(e)}) for e in self.edge_iterator()]) E = networkx.minimum_spanning_edges(G, data=False) return [(u, v, self.edge_label(u, v)) if hash(u) < hash(v) else (v, u, self.edge_label(u, v)) - for u, v in E] + for u, v in E] else: raise NotImplementedError("minimum spanning tree algorithm '%s' is not implemented" % algorithm) @@ -4780,9 +4784,7 @@ def spanning_trees_count(self, root_vertex=None): 1 sage: D.spanning_trees_count(2) 2 - """ - if not self.order(): return 0 @@ -4797,7 +4799,7 @@ def spanning_trees_count(self, root_vertex=None): root_vertex = vertices[0] index = 0 elif root_vertex not in vertices: - raise ValueError("vertex (%s) not in the graph"%root_vertex) + raise ValueError("vertex (%s) not in the graph" % root_vertex) else: index = vertices.index(root_vertex) @@ -4934,8 +4936,7 @@ def cycle_basis(self, output='vertex'): raise ValueError('output must be either vertex or edge') if self.is_directed(): - raise NotImplementedError('not implemented for directed ' - 'graphs') + raise NotImplementedError('not implemented for directed graphs') if self.allows_multiple_edges(): if not self.is_connected(): @@ -5064,7 +5065,7 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa else: raise NotImplementedError("only 'NetworkX' and Cython implementation is supported") - ### Planarity + # Planarity def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, set_pos=False): r""" @@ -5237,8 +5238,8 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se """ # Quick check first if (on_embedding is None and not kuratowski and not set_embedding and not set_pos - and not self.allows_loops() and not self.allows_multiple_edges() - and not self.is_directed()): + and not self.allows_loops() and not self.allows_multiple_edges() + and not self.is_directed()): if self.order() > 4 and self.size() > 3 * self.order() - 6: return False @@ -5249,7 +5250,7 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se return self.to_simple().is_planar(kuratowski=kuratowski) if on_embedding is not None: - self._check_embedding_validity(on_embedding,boolean=False) + self._check_embedding_validity(on_embedding, boolean=False) return (0 == self.genus(minimal=False, set_embedding=False, on_embedding=on_embedding)) else: from sage.graphs.planarity import is_planar @@ -5403,8 +5404,8 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, # Quick check first if (on_embedding is None and not kuratowski and set_embedding and - boundary is None and not ordered and not set_pos and - not self.allows_loops() and not self.allows_multiple_edges()): + boundary is None and not ordered and not set_pos and + not self.allows_loops() and not self.allows_multiple_edges()): if self.order() > 3 and self.size() > 2 * self.order() - 3: return False @@ -5630,11 +5631,11 @@ def layout_planar(self, set_embedding=False, on_embedding=None, embedding = dict() if len(G) >= 1: v1 = next(verts) - pos[v1] = [0,0] + pos[v1] = [0, 0] embedding[v1] = [] if len(G) == 2: v2 = next(verts) - pos[v2] = [0,1] + pos[v2] = [0, 1] embedding[v1] = [v2] embedding[v2] = [v1] if set_embedding: @@ -5666,25 +5667,29 @@ def layout_planar(self, set_embedding=False, on_embedding=None, embedding_copy = None if set_embedding: if not G.is_planar(set_embedding=True): - raise ValueError('%s is not a planar graph'%self) + raise ValueError('%s is not a planar graph' % self) embedding_copy = {v: neighbors[:] for v, neighbors in G._embedding.items()} else: if on_embedding is not None: G._check_embedding_validity(on_embedding, boolean=False) if not G.is_planar(on_embedding=on_embedding): - raise ValueError('provided embedding is not a planar embedding for %s'%self ) + raise ValueError('provided embedding is not a planar ' + 'embedding for %s' % self) G.set_embedding(on_embedding) else: - if hasattr(G,'_embedding'): + if hasattr(G, '_embedding'): if G._check_embedding_validity(): if not G.is_planar(on_embedding=G._embedding): - raise ValueError('%s has nonplanar _embedding attribute. Try putting set_embedding=True'%self) + raise ValueError('%s has nonplanar _embedding attribute. ' + 'Try putting set_embedding=True' % self) embedding_copy = {v: neighbors[:] for v, neighbors in G._embedding.items()} else: - raise ValueError('provided embedding is not a valid embedding for %s. Try putting set_embedding=True'%self) + raise ValueError('provided embedding is not a valid ' + 'embedding for %s. Try putting ' + 'set_embedding=True' % self) else: if not G.is_planar(set_embedding=True): - raise ValueError('%s is not a planar graph'%self) + raise ValueError('%s is not a planar graph' % self) if external_face: if not self.has_edge(external_face): @@ -5698,11 +5703,12 @@ def layout_planar(self, set_embedding=False, on_embedding=None, if test: if G._check_embedding_validity(): if not G.is_planar(on_embedding=G._embedding): - raise ValueError('%s has nonplanar _embedding attribute. Try putting set_embedding=True' % self) + raise ValueError('%s has nonplanar _embedding attribute. ' + 'Try putting set_embedding=True' % self) test_faces = G.faces(G._embedding) for face in test_faces: if len(face) != 3: - raise RuntimeError('BUG: Triangulation returned face: %s'%face) + raise RuntimeError('BUG: Triangulation returned face: %s' % face) faces = G.faces(G._embedding) outer_face = faces[0] @@ -5780,7 +5786,7 @@ def is_drawn_free_of_edge_crossings(self): t = (da * Rational(p1[1] - q1[1]) + db * Rational(q1[0] - p1[0])) / (db * dx - da * dy) if 0 <= s and s <= 1 and 0 <= t and t <= 1: - print('fail on', p1, p2, ' : ',q1, q2) + print('fail on', p1, p2, ' : ', q1, q2) print(edge1, edge2) return False return True @@ -5938,7 +5944,7 @@ def genus(self, set_embedding=True, on_embedding=None, minimal=True, maximal=Fal verts += 1 extra_edges = [] - if ordered: # WHEEL + if ordered: # WHEEL for e in zip(boundary[-1], boundary[1:]): if not G.has_edge(e): G.add_edge(e) @@ -5963,14 +5969,14 @@ def genus(self, set_embedding=True, on_embedding=None, minimal=True, maximal=Fal except AttributeError: raise AttributeError('graph must have attribute _embedding set to compute current (embedded) genus') return (2 - verts + edges - faces) // 2 - else: # then compute either maximal or minimal genus of all embeddings + else: # then compute either maximal or minimal genus of all embeddings from . import genus if set_embedding: if self.has_loops() or self.is_directed() or self.has_multiple_edges(): raise NotImplementedError("cannot work with embeddings of non-simple graphs") if minimal: - B,C = G.blocks_and_cut_vertices() + B, C = G.blocks_and_cut_vertices() embedding = {} g = 0 for block in B: @@ -5991,7 +5997,7 @@ def genus(self, set_embedding=True, on_embedding=None, minimal=True, maximal=Fal if maximal and (self.has_multiple_edges() or self.has_loops()): raise NotImplementedError("cannot compute the maximal genus of a graph with loops or multiple edges") if minimal: - B,C = G.blocks_and_cut_vertices() + B, C = G.blocks_and_cut_vertices() g = 0 for block in B: H = G.subgraph(block) @@ -6207,7 +6213,7 @@ def faces(self, embedding=None): # Establish set of possible edges edgeset = set() - for u,v in self.edge_iterator(labels=0): + for u, v in self.edge_iterator(labels=0): edgeset.add((u, v)) edgeset.add((v, u)) @@ -6219,7 +6225,7 @@ def faces(self, embedding=None): # Trace faces while edgeset: - u,v = path[-1] + u, v = path[-1] neighbors = embedding[v] next_node = neighbors[(neighbors.index(u) + 1) % len(neighbors)] e = (v, next_node) @@ -6417,8 +6423,7 @@ def planar_dual(self, embedding=None): edges.append([v1, v2, self.edge_label(e[0], e[1])]) return Graph([verts, edges]) - - ### Connectivity + # Connectivity def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): @@ -6520,7 +6525,9 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, cc = g.connected_component_containing_vertex(vertices[0]) if any(v not in cc for v in vertices): from sage.categories.sets_cat import EmptySetError - raise EmptySetError("the given vertices do not all belong to the same connected component. This problem has no solution !") + raise EmptySetError("the given vertices do not all belong to the " + "same connected component. This problem has " + "no solution !") # Can it be solved using the min spanning tree algorithm ? if not weighted: @@ -6551,22 +6558,22 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, p.add_constraint(p.sum(edges[frozenset(e)] for e in g.edges_incident(v, labels=False)), min=1) # The number of edges is equal to the number of vertices in our tree minus 1 - p.add_constraint( p.sum(vertex[v] for v in g) - - p.sum(edges[frozenset(e)] for e in g.edge_iterator(labels=False)), max=1, min=1) + p.add_constraint(p.sum(vertex[v] for v in g) + - p.sum(edges[frozenset(e)] for e in g.edge_iterator(labels=False)), max=1, min=1) # There are no cycles in our graph - for u,v in g.edge_iterator(labels=False): - p.add_constraint(r_edges[u,v]+ r_edges[v,u] - edges[frozenset((u,v))], min=0) + for u, v in g.edge_iterator(labels=False): + p.add_constraint(r_edges[u, v] + r_edges[v, u] - edges[frozenset((u, v))], min=0) - eps = 1/(5*Integer(g.order())) + eps = 1 / (5 * Integer(g.order())) for v in g: - p.add_constraint(p.sum(r_edges[u,v] for u in g.neighbor_iterator(v)), max=1-eps) - + p.add_constraint(p.sum(r_edges[u, v] for u in g.neighbor_iterator(v)), max=1 - eps) # Objective if weighted: - p.set_objective(p.sum((l if l is not None else 1)*edges[frozenset((u,v))] for u,v,l in g.edge_iterator())) + p.set_objective(p.sum((l if l is not None else 1) * edges[frozenset((u, v))] + for u, v, l in g.edge_iterator())) else: p.set_objective(p.sum(edges[frozenset(e)] for e in g.edge_iterator(labels=False))) @@ -6574,13 +6581,13 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, edges = p.get_values(edges, convert=bool, tolerance=integrality_tolerance) - st = g.subgraph(edges=[e for e in g.edge_iterator(labels=False) if edges[frozenset(e)]], - immutable=False) + st = g.subgraph(edges=[e for e in g.edge_iterator(labels=False) if edges[frozenset(e)]], + immutable=False) st.delete_vertices(v for v in g if not st.degree(v)) return st def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None, verbose=0, - *, integrality_tolerance=1e-3): + *, integrality_tolerance=1e-3): r""" Return the desired number of edge-disjoint spanning trees/arborescences. @@ -6815,8 +6822,8 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None # A vertex has at least one incident edge for u in D: p.add_constraint(p.sum(edge[e, c] for e in D.incoming_edge_iterator(u, labels=False)) - + p.sum(edge[e, c] for e in D.outgoing_edge_iterator(u, labels=False)) - >= 1) + + p.sum(edge[e, c] for e in D.outgoing_edge_iterator(u, labels=False)) + >= 1) # We use the Miller-Tucker-Zemlin subtour elimination constraints # combined with the Desrosiers-Langevin strengthening constraints @@ -6824,7 +6831,7 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None if D.has_edge(v, u): # DL p.add_constraint(pos[u, c] + (n - 1)*edge[(u, v), c] + (n - 3)*edge[(v, u), c] - <= pos[v, c] + n - 2) + <= pos[v, c] + n - 2) else: # MTZ: If edge uv is selected, v is after u in the partial ordering p.add_constraint(pos[u, c] + 1 - n * (1 - edge[(u, v), c]) <= pos[v, c]) @@ -7021,10 +7028,10 @@ def weight(x): flow_value, flow_graph = self.flow(s, t, value_only=value_only, use_edge_labels=use_edge_labels, algorithm=algorithm) - for u,v,l in flow_graph.edge_iterator(): + for u, v, l in flow_graph.edge_iterator(): g.add_edge(v, u) if (not use_edge_labels or - (weight(g.edge_label(u, v)) == weight(l))): + weight(g.edge_label(u, v)) == weight(l)): g.delete_edge(u, v) return_value = [flow_value] @@ -7067,22 +7074,22 @@ def good_edge(e): # Adjacent vertices can belong to different parts only if the # edge that connects them is part of the cut - for x,y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=None): p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0) else: # we minimize the number of edges - p.set_objective(p.sum(weight(w) * b[good_edge((x,y))] for x, y, w in g.edge_iterator())) + p.set_objective(p.sum(weight(w) * b[good_edge((x, y))] for x, y, w in g.edge_iterator())) # Adjacent vertices can belong to different parts only if the # edge that connects them is part of the cut - for x,y in g.edge_iterator(labels=None): + for x, y in g.edge_iterator(labels=None): p.add_constraint(v[x] + b[good_edge((x, y))] - v[y], min=0) p.add_constraint(v[y] + b[good_edge((x, y))] - v[x], min=0) p.solve(log=verbose) b = p.get_values(b, convert=bool, tolerance=integrality_tolerance) if use_edge_labels: - obj = sum(weight(w) for x, y, w in g.edge_iterator() if b[good_edge((x,y))]) + obj = sum(weight(w) for x, y, w in g.edge_iterator() if b[good_edge((x, y))]) else: obj = Integer(sum(1 for e in g.edge_iterator(labels=False) if b[good_edge(e)])) From 362659b303ff8a14a90813aefc7780b3fea7d326 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Sun, 21 Aug 2022 21:21:10 +0100 Subject: [PATCH 058/350] Fix infinite loop issue --- src/sage/graphs/edge_connectivity.pyx | 46 +++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 3a5a4d2655c..e968d4f827d 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -120,6 +120,7 @@ cdef class GabowEdgeConnectivity: cdef vector[vector[int]] g_out cdef vector[vector[int]] g_in cdef vector[vector[int]] my_g # either g_out or g_in + cdef vector[vector[int]] my_g_reversed # either g_out or g_in # values associated to edges cdef int* tail # source of edge j @@ -343,6 +344,7 @@ cdef class GabowEdgeConnectivity: if reverse: # Search for a spanning tree in g-reversed self.my_g = self.g_out + self.my_g_reversed = self.g_in self.my_from = self.head self.my_to = self.tail self.my_parent = self.parent_2 @@ -352,6 +354,7 @@ cdef class GabowEdgeConnectivity: else: # Search for a spanning tree in g using incoming arcs self.my_g = self.g_in + self.my_g_reversed = self.g_out self.my_from = self.tail self.my_to = self.head self.my_parent = self.parent_1 @@ -367,28 +370,29 @@ cdef class GabowEdgeConnectivity: # There's only one f-tree, so we already have a complete k-intersection # We save the edges and advance to the next iteration - if self.num_start_f_trees <= 1: + if self.num_start_f_trees < self.n-1: self.re_init(tree) - # There are several f-trees, and we try to join them - while njoins < self.num_start_f_trees-1: - # Get the root of an active subtree or INT_MAX if none exists - z = self.choose_root() - while z != INT_MAX: - if self.search_joining(z): - # We have augmented the root of the corresponding f_tree - njoins += 1 - else: - # We cannot find a tree - return False - + else: + # There are several f-trees, and we try to join them + while njoins < self.num_start_f_trees-1: + # Get the root of an active subtree or INT_MAX if none exists z = self.choose_root() - - # Trace the paths in order to transfer the edges to the appropriate - # tree Ti - self.augmentation_algorithm() - # Reinitialize data structures and make all f_trees active for next round - self.re_init(tree) - sig_check() + while z != INT_MAX: + if self.search_joining(z): + # We have augmented the root of the corresponding f_tree + njoins += 1 + else: + # We cannot find a tree + return False + + z = self.choose_root() + + # Trace the paths in order to transfer the edges to the appropriate + # tree Ti + self.augmentation_algorithm() + # Reinitialize data structures and make all f_trees active for next round + self.re_init(tree) + sig_check() return True @@ -480,7 +484,7 @@ cdef class GabowEdgeConnectivity: self.visited[u] = True # Visit outgoing arcs of current vertex - for e_id in self.g_out[u]: + for e_id in self.my_g_reversed[u]: v = self.my_to[e_id] # Ensure a vertex is not visited, is not a proven k-intersection edge # and root_vertex remains deficient From 7ab9370968a0eb0a24ab50f987d1c7dbfec70664 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 21 Aug 2022 21:16:41 -0700 Subject: [PATCH 059/350] build/pkgs/rpy2/install-requires.txt: Remove upper version bound --- build/pkgs/rpy2/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/rpy2/install-requires.txt b/build/pkgs/rpy2/install-requires.txt index 7e5dc5f160a..769d7e61e92 100644 --- a/build/pkgs/rpy2/install-requires.txt +++ b/build/pkgs/rpy2/install-requires.txt @@ -1 +1 @@ -rpy2 >=3.3, <3.4 +rpy2 >=3.3 From 5d664320bc03e6177192caa9a4442c9d70401386 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 22 Aug 2022 09:54:23 -0700 Subject: [PATCH 060/350] src/setup.cfg.m4: Move rpy2 from install-requires to extras-require --- src/setup.cfg.m4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index a69b69924c5..ae2a5bfe9a9 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -68,7 +68,6 @@ dnl From Makefile.in: DOC_DEPENDENCIES | sed "2,\$s/^/ /;"')dnl' dnl Other Python packages that are standard spkg, used in doctests esyscmd(`sage-get-system-packages install-requires \ - rpy2 \ fpylll \ | sed "2,\$s/^/ /;"')dnl' dnl pycryptosat # Sage distribution installs it as part of cryptominisat. According to its README on https://pypi.org/project/pycryptosat/: "The pycryptosat python package compiles while compiling CryptoMiniSat. It cannot be compiled on its own, it must be compiled at the same time as CryptoMiniSat." @@ -160,3 +159,8 @@ sage = ext_data/magma/sage/* ext_data/valgrind/* ext_data/threejs/* + +[options.extras_require] +R = esyscmd(`sage-get-system-packages install-requires \ + rpy2 \ + | sed "2,\$s/^/ /;"')dnl' From 1e8f69dfeab7f92a5579fbcb488f6759cedc569f Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 24 Aug 2022 23:11:11 +0200 Subject: [PATCH 061/350] remove LazyPowerSeries and Stream --- src/sage/combinat/species/all.py | 9 - .../combinat/species/composition_species.py | 7 - src/sage/combinat/species/cycle_species.py | 1 - src/sage/combinat/species/empty_species.py | 13 - .../combinat/species/generating_series.py | 746 +------ src/sage/combinat/species/library.py | 4 +- .../combinat/species/linear_order_species.py | 1 - .../combinat/species/partition_species.py | 1 - .../combinat/species/permutation_species.py | 8 +- .../combinat/species/recursive_species.py | 23 +- src/sage/combinat/species/series.py | 1832 ----------------- src/sage/combinat/species/series_order.py | 294 --- src/sage/combinat/species/set_species.py | 1 - src/sage/combinat/species/species.py | 4 +- src/sage/combinat/species/stream.py | 501 ----- src/sage/combinat/species/subset_species.py | 1 - src/sage/rings/lazy_series.py | 6 +- 17 files changed, 67 insertions(+), 3385 deletions(-) delete mode 100644 src/sage/combinat/species/series.py delete mode 100644 src/sage/combinat/species/series_order.py delete mode 100644 src/sage/combinat/species/stream.py diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 65e18ade5d2..95c495603bb 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -11,14 +11,6 @@ - :ref:`section-examples-catalan` - :ref:`section-generic-species` -Lazy Power Series ------------------ - -- :ref:`sage.combinat.species.stream` -- :ref:`sage.combinat.species.series_order` -- :ref:`sage.combinat.species.series` -- :ref:`sage.combinat.species.generating_series` - Basic Species ------------- @@ -52,6 +44,5 @@ from sage.misc.namespace_package import install_doc install_doc(__package__, __doc__) -from .series import LazyPowerSeriesRing from .recursive_species import CombinatorialSpecies from . import library as species diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index 56736f7bc6a..9050b8d89f0 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -207,7 +207,6 @@ def _itgs(self, series_ring, base_ring): sage: L.isotype_generating_series()[:10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - raise NotImplementedError() cis = self.cycle_index_series(base_ring) return cis.isotype_generating_series() @@ -251,12 +250,6 @@ def _cis(self, series_ring, base_ring): """ f_cis = self._F.cycle_index_series(base_ring) g_cis = self._G.cycle_index_series(base_ring) - - #If G is a weighted species, then we can't use the default - #algorithm for the composition of the cycle index series - #since we must raise the weighting to the power. - if self._G.is_weighted(): - return f_cis.weighted_composition(self._G) return f_cis(g_cis) def weight_ring(self): diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index cb95fb6afad..ced61ed4471 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -14,7 +14,6 @@ from .species import GenericCombinatorialSpecies from .structure import GenericSpeciesStructure -from .generating_series import _integers_from from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ from sage.arith.all import divisors, euler_phi diff --git a/src/sage/combinat/species/empty_species.py b/src/sage/combinat/species/empty_species.py index 6057732f490..5fd8081d1f8 100644 --- a/src/sage/combinat/species/empty_species.py +++ b/src/sage/combinat/species/empty_species.py @@ -16,7 +16,6 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from .species import GenericCombinatorialSpecies -from .series_order import inf from sage.structure.unique_representation import UniqueRepresentation class EmptySpecies(GenericCombinatorialSpecies, UniqueRepresentation): @@ -114,18 +113,6 @@ def _gs(self, series_ring, base_ring): _itgs = _gs _cis = _gs - def _order(self): - """ - Returns the order of the generating series. - - EXAMPLES:: - - sage: F = species.EmptySpecies() - sage: F._order() - Infinite series order - """ - return inf - def _structures(self, structure_class, labels): """ Thanks to the counting optimisation, this is never called... Otherwise diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index e7d612d2c13..c6191b97960 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -15,37 +15,11 @@ TESTS:: - sage: from sage.combinat.species.stream import Stream, _integers_from sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ, 'z') - -:: - - sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) - sage: geo2 = CIS((p([2])^i for i in _integers_from(0))) - sage: s = geo1 * geo2 - sage: s[0] - p[] - sage: s[1] - p[1] + p[2] - sage: s[2] - p[1, 1] + p[2, 1] + p[2, 2] - sage: s[3] - p[1, 1, 1] + p[2, 1, 1] + p[2, 2, 1] + p[2, 2, 2] - -Whereas the coefficients of the above test are homogeneous with -respect to total degree, the following test groups with respect to -weighted degree where each variable x_i has weight i. - -:: - - sage: def g(): - ....: for i in _integers_from(0): - ....: yield p([2])^i - ....: yield p(0) - sage: geo1 = CIS((p([1])^i for i in _integers_from(0))) - sage: geo2 = CIS(g()) + sage: CIS = CycleIndexSeriesRing(QQ) + sage: geo1 = CIS(lambda i: p([1])^i) + sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) sage: s = geo1 * geo2 sage: s[0] p[] @@ -55,8 +29,6 @@ p[1, 1] + p[2] sage: s[3] p[1, 1, 1] + p[2, 1] - sage: s[4] - p[1, 1, 1, 1] + p[2, 1, 1] + p[2, 2] REFERENCES: @@ -77,9 +49,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.lazy_laurent_series import LazyTaylorSeries, LazySymmetricFunction -from sage.rings.lazy_laurent_series_ring import LazyTaylorSeriesRing, LazySymmetricFunctions -from .stream import Stream, _integers_from +from sage.rings.lazy_series import LazyTaylorSeries, LazySymmetricFunction +from sage.rings.lazy_series_ring import LazyTaylorSeriesRing, LazySymmetricFunctions from sage.rings.integer import Integer from sage.rings.rational_field import RationalField from sage.arith.all import moebius, gcd, lcm, divisors @@ -94,14 +65,13 @@ class OrdinaryGeneratingSeries(LazyTaylorSeries): r""" A class for ordinary generating series. - Note that it is just a - :class:`LazyTaylorSeries` whose elements have - some extra methods. + Note that it is just a :class:`LazyTaylorSeries` whose elements + have some extra methods. EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(lambda n: n) sage: f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) @@ -118,7 +88,7 @@ def count(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.count(10) 10 @@ -134,7 +104,7 @@ def counts(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.counts(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -154,7 +124,7 @@ class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z'); R + sage: R = OrdinaryGeneratingSeriesRing(QQ); R Lazy Taylor Series Ring in z over Rational Field sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] @@ -165,14 +135,15 @@ class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): TESTS: - We test to make sure that caching works. + We test to make sure that caching works.:: - :: - - sage: R is OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: R is OrdinaryGeneratingSeriesRing(QQ) True """ + def __init__(self, base_ring): + super().__init__(base_ring, names="z") + Element = OrdinaryGeneratingSeries @@ -187,7 +158,7 @@ class ExponentialGeneratingSeries(LazyTaylorSeries): EXAMPLES:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing - sage: R = OrdinaryGeneratingSeriesRing(QQ, 'z') + sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: f = R(lambda n: n) sage: f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) @@ -200,7 +171,7 @@ def count(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') + sage: R = ExponentialGeneratingSeriesRing(QQ) sage: f = R(lambda n: 1) sage: [f.count(i) for i in range(7)] [1, 1, 2, 6, 24, 120, 720] @@ -216,7 +187,7 @@ def counts(self, n): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ, 'z') + sage: R = ExponentialGeneratingSeriesRing(QQ) sage: f = R(range(20)) sage: f.counts(5) [0, 1, 4, 18, 96] @@ -248,34 +219,18 @@ def functorial_composition(self, y): sage: [g.coefficient(i) for i in range(10)] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] - """ - P = self.parent() - return P(lambda n: self._functorial_compose_gen(y, n), 0) - - def _functorial_compose_gen(self, y, n): - """ - Returns the ``n``th coefficient of the functorial - composition of self with y. - - INPUT: - - - ``y`` -- the other series - - ``n`` -- the nth term of the functorial composition - - EXAMPLES:: - sage: E = species.SetSpecies() sage: E2 = E.restricted(min=2, max=3) sage: WP = species.SubsetSpecies() sage: P2 = E2*E sage: g1 = WP.generating_series() sage: g2 = P2.generating_series() - sage: [g1._functorial_compose_gen(g2, i) for i in range(10)] + sage: g1.functorial_composition(g2)[:10] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] """ - return self.count(y.count(n)) / factorial(n) - + P = self.parent() + return P(lambda n: self.count(y.count(n)) / factorial(n), 0) class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): r""" @@ -288,7 +243,7 @@ class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing - sage: R = ExponentialGeneratingSeriesRing(QQ, 'z'); R + sage: R = ExponentialGeneratingSeriesRing(QQ); R Lazy Taylor Series Ring in z over Rational Field sage: [R(lambda n: 1).coefficient(i) for i in range(4)] [1, 1, 1, 1] @@ -301,32 +256,14 @@ class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): :: - sage: R is ExponentialGeneratingSeriesRing(QQ, 'z') + sage: R is ExponentialGeneratingSeriesRing(QQ) True """ - Element = ExponentialGeneratingSeries + def __init__(self, base_ring): + super().__init__(base_ring, names="z") - -def factorial_gen(): - """ - A generator for the factorials starting at 0. - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import factorial_gen - sage: g = factorial_gen() - sage: [next(g) for i in range(5)] - [1, 1, 2, 6, 24] - """ - z = Integer(1) - yield z - yield z - n = Integer(2) - while True: - z *= n - yield z - n += 1 + Element = ExponentialGeneratingSeries class CycleIndexSeries(LazySymmetricFunction): @@ -339,7 +276,7 @@ def count(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ, 'z') + sage: CIS = CycleIndexSeriesRing(QQ) sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) sage: f.count([1]) 1 @@ -359,7 +296,7 @@ def coefficient_cycle_type(self, t): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ, 'z') + sage: CIS = CycleIndexSeriesRing(QQ) sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) sage: f.coefficient_cycle_type([1]) 1 @@ -372,59 +309,6 @@ def coefficient_cycle_type(self, t): p = self.coefficient(t.size()) return p.coefficient(t) - def stretch(self, k): - r""" - Return the stretch of the cycle index series ``self`` by a positive - integer `k`. - - If - - .. MATH:: - - f = \sum_{n=0}^{\infty} f_n(p_1, p_2, p_3, \ldots ), - - then the stretch `g` of `f` by `k` is - - .. MATH:: - - g = \sum_{n=0}^{\infty} f_n(p_k, p_{2k}, p_{3k}, \ldots ). - - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ, 'z') - sage: f = CIS([p([]), p([1]), p([2]), p.zero()]) - sage: f.stretch(3)[0:10] - [p[], 0, 0, p[3], 0, 0, p[6], 0, 0, 0] - """ - P = self.parent() - return P(lambda n: self._stretch_gen(k, n), k * self._coeff_stream._approximate_order) - - def _stretch_gen(self, k, n): - """ - EXAMPLES:: - - sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() - sage: CIS = CycleIndexSeriesRing(QQ, 'z') - sage: f = CIS([p([1])]) # This is the power series whose all coefficients - ....: # are p[1]. Not combinatorially meaningful! - sage: [f._stretch_gen(2, i) for i in range(10)] - [p[2], 0, p[2], 0, p[2], 0, p[2], 0, p[2], 0] - """ - from sage.combinat.partition import Partition - BR = self.base_ring() - zero = BR.zero() - - stretch_k = lambda p: Partition([k*i for i in p]) - - if n == 0: - return self.coefficient(0).map_support(stretch_k) - elif n % k: - return zero - return self.coefficient(n//k).map_support(stretch_k) - def isotype_generating_series(self): """ EXAMPLES:: @@ -435,44 +319,10 @@ def isotype_generating_series(self): sage: f[:10] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] """ - R = self.base_ring().base_ring() - OGS = OrdinaryGeneratingSeriesRing(R, 'z') + R = self.base_ring() + OGS = OrdinaryGeneratingSeriesRing(R) return OGS(lambda n: self._ogs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) - def expand_as_sf(self, n, alphabet='x'): - """ - Returns the expansion of a cycle index series as a symmetric function in - ``n`` variables. - - Specifically, this returns a :class:`~sage.combinat.species.series.LazyTaylorSeries` whose - ith term is obtained by calling :meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.expand` - on the ith term of ``self``. - - This relies on the (standard) interpretation of a cycle index series as a symmetric function - in the power sum basis. - - INPUT: - - - ``self`` -- a cycle index series - - - ``n`` -- a positive integer - - - ``alphabet`` -- a variable for the expansion (default: `x`) - - EXAMPLES:: - - sage: from sage.combinat.species.set_species import SetSpecies - sage: SetSpecies().cycle_index_series().expand_as_sf(2)[:4] - [1, x0 + x1, x0^2 + x0*x1 + x1^2, x0^3 + x0^2*x1 + x0*x1^2 + x1^3] - - """ - expanded_poly_ring = self.coefficient(0).expand(n, alphabet).parent() - LPSR = LazyTaylorSeriesRing(expanded_poly_ring) - - expander_gen = (LPSR.term(self.coefficient(i).expand(n, alphabet), i) for i in _integers_from(0)) - - return LPSR.sum_generator(expander_gen) - def _ogs_gen(self, n, ao): """ Returns a generator for the coefficients of the ordinary generating @@ -488,10 +338,6 @@ def _ogs_gen(self, n, ao): if n < ao: return 0 return sum(self.coefficient(n).coefficients()) - # for i in range(ao): - # yield 0 - # for i in _integers_from(ao): - # yield sum( self.coefficient(i).coefficients() ) def generating_series(self): """ @@ -503,8 +349,8 @@ def generating_series(self): sage: f[:5] [1, 1, 1, 5/6, 5/8] """ - R = self.base_ring().base_ring() - EGS = ExponentialGeneratingSeriesRing(R, 'z') + R = self.base_ring() + EGS = ExponentialGeneratingSeriesRing(R) return EGS(lambda n: self._egs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) def _egs_gen(self, n, ao): @@ -523,7 +369,6 @@ def _egs_gen(self, n, ao): return 0 return self.coefficient(n).coefficient([1]*n) - def __invert__(self): r""" Return the multiplicative inverse of ``self``. @@ -552,288 +397,14 @@ def __invert__(self): AUTHORS: - Andrew Gainer-Dewar - """ - if self.coefficient(0) == 0: - raise ValueError("constant term must be non-zero") - - def multinv_builder(i): - return self.coefficient(0)**(-i-1) * (self.coefficient(0) + (-1)*self)**i - return self.parent().sum_generator(multinv_builder(i) for i in _integers_from(0)) - - def _div_(self, y): - """ TESTS:: sage: E = species.SetSpecies().cycle_index_series() sage: (E / E)[:6] [p[], 0, 0, 0, 0, 0] """ - return self*(~y) - - def functorial_composition(self, g): - r""" - Returns the functorial composition of ``self`` and ``g``. - - If `F` and `G` are species, their functorial composition is the species - `F \Box G` obtained by setting `(F \Box G) [A] = F[ G[A] ]`. - In other words, an `(F \Box G)`-structure on a set `A` of labels is an - `F`-structure whose labels are the set of all `G`-structures on `A`. - - It can be shown (as in section 2.2 of [BLL]_) that there is a - corresponding operation on cycle indices: - - .. MATH:: - - Z_{F} \Box Z_{G} = \sum_{n \geq 0} \frac{1}{n!} - \sum_{\sigma \in \mathfrak{S}_{n}} - \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] - \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots. - - This method implements that operation on cycle index series. - - EXAMPLES: - - The species `G` of simple graphs can be expressed in terms of a functorial - composition: `G = \mathfrak{p} \Box \mathfrak{p}_{2}`, where - `\mathfrak{p}` is the :class:`~sage.combinat.species.subset_species.SubsetSpecies`. - This is how it is implemented in - :meth:`~sage.combinat.species.library.SimpleGraphSpecies`:: - - sage: S = species.SimpleGraphSpecies() - sage: S.cycle_index_series()[:5] - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - # return self._new(partial(self._functorial_compose_gen, g), lambda a,b: 0, self, g) - P = self.parent() - return P(lambda n: self._functorial_compose_gen(g, n, self._coeff_stream._approximate_order), 0) - def _functorial_compose_gen(self, g, n, ao): - """ - Return a generator for the coefficients of the functorial - composition of ``self`` with ``g``. - - EXAMPLES:: - - sage: E = species.SetSpecies() - sage: E2 = species.SetSpecies(size=2) - sage: WP = species.SubsetSpecies() - sage: P2 = E2*E - sage: P2_cis = P2.cycle_index_series() - sage: WP_cis = WP.cycle_index_series() - sage: [WP_cis._functorial_compose_gen(P2_cis, i, 0) for i in range(5)] - [p[], - p[1], - p[1, 1] + p[2], - 4/3*p[1, 1, 1] + 2*p[2, 1] + 2/3*p[3], - 8/3*p[1, 1, 1, 1] + 4*p[2, 1, 1] + 2*p[2, 2] + 4/3*p[3, 1] + p[4]] - """ - p = self.parent().base_ring() - res = p(0) - print(n) - print(res) - for s in Partitions(n): - print(s) - t = g._cycle_type(s) - print(t) - q = self.count(t) / s.aut() - print(q) - res += q * p(s) - print(res) - return res - # p = self.parent().base_ring() - # m = 0 - # print(p) - # print(m) - # while True: - # res = p(0) - # print(res) - # for s in Partitions(m): - # print(s) - # t = g._cycle_type(s) - # print(t) - # q = self.count(t) / s.aut() - # print(q) - # res += q*p(s) - # print(res) - # yield res - # m += 1 - - def arithmetic_product(self, g, check_input = True): - r""" - Return the arithmetic product of ``self`` with ``g``. - - For species `M` and `N` such that `M[\\varnothing] = N[\\varnothing] = \\varnothing`, - their arithmetic product is the species `M \\boxdot N` of "`M`-assemblies of cloned `N`-structures". - This operation is defined and several examples are given in [MM]_. - - The cycle index series for `M \\boxdot N` can be computed in terms of the component series `Z_M` and `Z_N`, - as implemented in this method. - - INPUT: - - - ``g`` -- a cycle index series having the same parent as ``self``. - - - ``check_input`` -- (default: ``True``) a Boolean which, when set - to ``False``, will cause input checks to be skipped. - - OUTPUT: - - The arithmetic product of ``self`` with ``g``. This is a cycle - index series defined in terms of ``self`` and ``g`` such that - if ``self`` and ``g`` are the cycle index series of two species - `M` and `N`, their arithmetic product is the cycle index series - of the species `M \\boxdot N`. - - EXAMPLES: - - For `C` the species of (oriented) cycles and `L_{+}` the species of nonempty linear orders, `C \\boxdot L_{+}` corresponds - to the species of "regular octopuses"; a `(C \\boxdot L_{+})`-structure is a cycle of some length, each of whose elements - is an ordered list of a length which is consistent for all the lists in the structure. :: - - sage: C = species.CycleSpecies().cycle_index_series() - sage: Lplus = species.LinearOrderSpecies(min=1).cycle_index_series() - sage: RegularOctopuses = C.arithmetic_product(Lplus) - sage: RegOctSpeciesSeq = RegularOctopuses.generating_series().counts(8) - sage: RegOctSpeciesSeq - [0, 1, 3, 8, 42, 144, 1440, 5760] - - It is shown in [MM]_ that the exponential generating function for regular octopuses satisfies - `(C \\boxdot L_{+}) (x) = \\sum_{n \geq 1} \\sigma (n) (n - 1)! \\frac{x^{n}}{n!}` (where `\\sigma (n)` is - the sum of the divisors of `n`). :: - - sage: RegOctDirectSeq = [0] + [sum(divisors(i))*factorial(i-1) for i in range(1,8)] - sage: RegOctDirectSeq == RegOctSpeciesSeq - True - - AUTHORS: - - - Andrew Gainer-Dewar (2013) - - REFERENCES: - - .. [MM] \M. Maia and M. Mendez. "On the arithmetic product of combinatorial species". - Discrete Mathematics, vol. 308, issue 23, 2008, pp. 5407-5427. - :arxiv:`math/0503436v2`. - - """ - from itertools import product, repeat, chain - - p = self.base_ring() - - if check_input: - assert self.coefficient(0) == p.zero() - assert g.coefficient(0) == p.zero() - - # We first define an operation `\\boxtimes` on partitions as in Lemma 2.1 of [MM]_. - def arith_prod_of_partitions(l1, l2): - # Given two partitions `l_1` and `l_2`, we construct a new partition `l_1 \\boxtimes l_2` by - # the following procedure: each pair of parts `a \\in l_1` and `b \\in l_2` contributes - # `\\gcd (a, b)`` parts of size `\\lcm (a, b)` to `l_1 \\boxtimes l_2`. If `l_1` and `l_2` - # are partitions of integers `n` and `m`, respectively, then `l_1 \\boxtimes l_2` is a - # partition of `nm`. - term_iterable = chain.from_iterable(repeat(lcm(pair), gcd(pair)) - for pair in product(l1, l2)) - return Partition(sorted(term_iterable, reverse=True)) - - # We then extend this to an operation on symmetric functions as per eq. (52) of [MM]_. - # (Maia and Mendez, in [MM]_, are talking about polynomials instead of symmetric - # functions, but this boils down to the same: Their x_i corresponds to the i-th power - # sum symmetric function.) - def arith_prod_sf(x, y): - ap_sf_wrapper = lambda l1, l2: p(arith_prod_of_partitions(l1, l2)) - return p._apply_multi_module_morphism(x, y, ap_sf_wrapper) - - # Sage stores cycle index series by degree. - # Thus, to compute the arithmetic product `Z_M \\boxdot Z_N` it is useful - # to compute all terms of a given degree `n` at once. - def arith_prod_coeff(n): - if n == 0: - res = p.zero() - else: - index_set = ((d, n // d) for d in divisors(n)) - res = sum(arith_prod_sf(self.coefficient(i), g.coefficient(j)) for i,j in index_set) - - # Build a list which has res in the `n`th slot and 0's before and after - # to feed to sum_generator - res_in_seq = [p.zero()]*n + [res, p.zero()] - - return self.parent(res_in_seq) - - # Finally, we use the sum_generator method to assemble these results into a single - # LazyTaylorSeries object. - return self.parent().sum_generator(arith_prod_coeff(n) for n in _integers_from(0)) - - def _cycle_type(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] - sage: cis = species.PermutationSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[3, 1, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1]] - sage: cis = species.SetSpecies().cycle_index_series() - sage: [cis._cycle_type(p) for p in Partitions(3)] - [[1], [1], [1]] - """ - if s == []: - return self._card(0) - res = [] - for k in range(1, self._upper_bound_for_longest_cycle(s)+1): - e = 0 - for d in divisors(k): - m = moebius(d) - if m == 0: - continue - u = s.power(k/d) - e += m*self.count(u) - res.extend([k]*int(e/k)) - res.reverse() - return Partition(res) - - def _upper_bound_for_longest_cycle(self, s): - """ - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._upper_bound_for_longest_cycle([4]) - 4 - sage: cis._upper_bound_for_longest_cycle([3,1]) - 3 - sage: cis._upper_bound_for_longest_cycle([2,2]) - 2 - sage: cis._upper_bound_for_longest_cycle([2,1,1]) - 2 - sage: cis._upper_bound_for_longest_cycle([1,1,1,1]) - 1 - """ - if s == []: - return 1 - return min(self._card(sum(s)), lcm(list(s))) - - def _card(self, n): - r""" - Return the number of structures on an underlying set of size ``n`` for - the species associated with ``self``. - - This is just ``n!`` times the coefficient of ``p[1]n`` in ``self``. - - EXAMPLES:: - - sage: cis = species.PartitionSpecies().cycle_index_series() - sage: cis._card(4) - 15 - """ - p = self.coefficient(n) - return factorial(n) * p.coefficient([1] * n) - - def _compose_gen(self, y, ao): """ Return a generator for the coefficients of the composition of this cycle index series and the cycle index series ``y``. This overrides @@ -849,19 +420,7 @@ def _compose_gen(self, y, ao): sage: g = E_cis._compose_gen(C.cycle_index_series(),0) sage: [next(g) for i in range(4)] [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - assert y.coefficient(0) == 0 - y_powers = Stream(y._power_gen()) - - parent = self.parent() - res = parent.sum_generator(self._compose_term(self.coefficient(i), y_powers) - for i in _integers_from(0)) - for i in _integers_from(0): - yield res.coefficient(i) - - def _compose_term(self, p, y_powers): - r""" Return the composition of one term in ``self`` with `y`. INPUT: @@ -872,7 +431,6 @@ def _compose_term(self, p, y_powers): EXAMPLES:: - sage: from sage.combinat.species.stream import Stream sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: E_cis = E.cycle_index_series() sage: C_cis = C.cycle_index_series() @@ -882,171 +440,7 @@ def _compose_term(self, p, y_powers): sage: E_cis._compose_term(p2, c_powers)[:4] [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] """ - parent = self.parent() - if p == 0: - return parent(0) - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent.term(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * y_powers[v-1].stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def weighted_composition(self, y_species): - r""" - Return the composition of this cycle index series with the cycle - index series of the weighted species ``y_species``. - - Note that this is basically the same algorithm as composition - except we can not use the optimization that the powering of cycle - index series commutes with 'stretching'. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: E_cis.weighted_composition(C)[:4] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - sage: E(C).cycle_index_series()[:4] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - base_ring = self.base_ring() - y = y_species.cycle_index_series(base_ring) - assert y.coefficient(0) == 0 - return self._new(partial(self._weighted_compose_gen, y_species), lambda a,b:a*b, self, y) - - def _weighted_compose_gen(self, y_species, ao): - r""" - Return an iterator for the composition of this cycle index series - and the cycle index series of the weighted species ``y_species``. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._weighted_compose_gen(C,0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - """ - parent = self.parent() - res = parent.sum_generator(self._weighted_compose_term(self.coefficient(i), y_species) - for i in _integers_from(0)) - - for i in _integers_from(0): - yield res.coefficient(i) - - def _weighted_compose_term(self, p, y_species): - r""" - Return the weighted composition of one term in ``self`` with ``y``. - - INPUT: - - - ``p`` -- a term in ``self`` - - ``y_species`` -- a species - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._weighted_compose_term(p2, C)[:4] - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - parent = self.parent() - if p == 0: - return parent(0) - - base_ring = self.base_ring().base_ring() - - res = [] - #Go through all the partition, coefficient pairs in the term p - for m, c in p: - res_t = parent(c, 0) - - for e,v in enumerate(m.to_exp()): - if v == 0: - continue - res_t = res_t * (y_species.weighted(y_species._weight**(e+1)).cycle_index_series(base_ring)**v).stretch(e+1) - res.append(res_t) - - return parent.sum(res) - - def compositional_inverse(self): - r""" - Return the compositional inverse of ``self`` if possible. - - (Specifically, if ``self`` is of the form `0 + p_{1} + \cdots`.) - - The compositional inverse is the inverse with respect to - plethystic substitution. This is the operation on cycle index - series which corresponds to substitution, a.k.a. partitional - composition, on the level of species. See Section 2.2 of - [BLL]_ for a definition of this operation. - - EXAMPLES:: - - sage: Eplus = species.SetSpecies(min=1).cycle_index_series() - sage: Eplus(Eplus.compositional_inverse())[:8] - [0, p[1], 0, 0, 0, 0, 0, 0] - - TESTS:: - - sage: Eplus = species.SetSpecies(min=2).cycle_index_series() - sage: Eplus.compositional_inverse() - Traceback (most recent call last): - ... - ValueError: not an invertible series - - ALGORITHM: - - Let `F` be a species satisfying `F = 0 + X + F_2 + F_3 + \cdots` for - `X` the species of singletons. (Equivalently, `\lvert F[\varnothing] - \rvert = 0` and `\lvert F[\{1\}] \rvert = 1`.) Then there exists a - (virtual) species `G` satisfying `F \circ G = G \circ F = X`. - - It follows that `(F - X) \circ G = F \circ G - X \circ G = X - G`. - Rearranging, we obtain the recursive equation `G = X - (F - X) \circ G`, - which can be solved using iterative methods. - - .. WARNING:: - - This algorithm is functional but can be very slow. - Use with caution! - - .. SEEALSO:: - - The compositional inverse `\Omega` of the species `E_{+}` - of nonempty sets can be handled much more efficiently - using specialized methods. See - :func:`~sage.combinat.species.generating_series.LogarithmCycleIndexSeries` - - AUTHORS: - - - Andrew Gainer-Dewar - """ - cisr = self.parent() - sfa = cisr._base - - X = cisr([0, sfa([1]), 0]) - if self[:2] != X[:2]: - raise ValueError('not an invertible series') - - res = cisr() - # res.define(X - (self - X).compose(res)) - res.define(X - (self - X)(res)) - - return res - - def derivative(self, order=1): r""" Return the species-theoretic `n`-th derivative of ``self``, where `n` is ``order``. @@ -1075,24 +469,7 @@ def derivative(self, order=1): sage: L[:8] == C.derivative()[:8] True """ - # Make sure that order is integral - order = Integer(order) - - if order < 0: - raise ValueError("Order must be a non-negative integer") - - elif order == 0: - return self - - elif order == 1: - parent = self.parent() - derivative_term = lambda n: parent.term(self.coefficient(n+1).derivative_with_respect_to_p1(), n) - return parent.sum_generator(derivative_term(i) for i in _integers_from(0)) - - else: - return self.derivative(order-1) - def pointing(self): r""" Return the species-theoretic pointing of ``self``. @@ -1114,40 +491,7 @@ def pointing(self): True """ - p1 = self.base_ring()([1]) - X = self.parent()([0, p1, 0]) - return X*self.derivative() - - def integral(self, *args): - r""" - Given a cycle index `G`, it is not in general possible to recover a - single cycle index `F` such that `F' = G` (even up to addition of a - constant term). - - More broadly, it may be the case that there are many non-isomorphic - species `S` such that `S' = T` for a given species `T`. - For example, the species `3 C_{3}` of 3-cycles from three distinct - classes and the species `X^{3}` of 3-sets are not isomorphic, but - `(3 C_{3})' = (X^{3})' = 3 X^{2}`. - - EXAMPLES:: - - sage: C3 = species.CycleSpecies(size=3).cycle_index_series() - sage: X = species.SingletonSpecies().cycle_index_series() - sage: (3*C3).derivative()[:8] == (3*X^2)[:8] - True - sage: (X^3).derivative()[:8] == (3*X^2)[:8] - True - - .. WARNING:: - - This method has no implementation and exists only to prevent you from - doing something strange. Calling it raises a ``NotImplementedError``! - """ - raise NotImplementedError - - def exponential(self): r""" Return the species-theoretic exponential of ``self``. @@ -1192,7 +536,7 @@ def logarithm(self): sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: CG = LogarithmCycleIndexSeries().compose(G) + sage: CG = LogarithmCycleIndexSeries()(G) sage: CG.isotype_generating_series()[:8] [0, 1, 1, 2, 6, 21, 112, 853] """ @@ -1236,11 +580,11 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ, 'z'); R + sage: R = CycleIndexSeriesRing(QQ); R Cycle Index Series Ring over Rational Field - sage: [R(lambda n: 1).coefficient(i) for i in range(4)] # This is not combinatorially - ....: # meaningful. - [1, 1, 1, 1] + sage: p = SymmetricFunctions(QQ).p() + sage: R(lambda n: p[n]) + p[] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + O^7 TESTS: @@ -1248,21 +592,25 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): :: - sage: R is CycleIndexSeriesRing(QQ, 'z') + sage: R is CycleIndexSeriesRing(QQ) True """ Element = CycleIndexSeries + def __init__(self, base_ring, sparse=True): + p = SymmetricFunctions(base_ring).power() + super().__init__(p) + def __repr__(self): """ EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ, 'z') + sage: CycleIndexSeriesRing(QQ) Cycle Index Series Ring over Rational Field """ - return "Cycle Index Series Ring over %s"%self.base_ring() + return "Cycle Index Series Ring over %s" % self.base_ring() @cached_function @@ -1300,7 +648,7 @@ def ExponentialCycleIndexSeries(R = RationalField()): + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] """ - CIS = CycleIndexSeriesRing(R, 'z') + CIS = CycleIndexSeriesRing(R) return CIS(lambda n: _exp_term(n)) @@ -1355,5 +703,5 @@ def LogarithmCycleIndexSeries(R = RationalField()): sage: LogarithmCycleIndexSeries()(Eplus)[:4] [0, p[1], 0, 0] """ - CIS = CycleIndexSeriesRing(R, 'z') + CIS = CycleIndexSeriesRing(R) return CIS(lambda n: _cl_term(n)) diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index cade34fcaca..4b63b1a4730 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -103,9 +103,9 @@ def BinaryTreeSpecies(): sage: oeis(seq)[0] # optional -- internet A000108: Catalan numbers: ... """ - B = CombinatorialSpecies() + B = CombinatorialSpecies(min=1) X = SingletonSpecies() - B.define(X+B*B) + B.define(X + B*B) return B @cached_function diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 2b8a9540b8a..6ae435b4e22 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -17,7 +17,6 @@ #***************************************************************************** from .species import GenericCombinatorialSpecies from .structure import GenericSpeciesStructure -from .generating_series import _integers_from from sage.structure.unique_representation import UniqueRepresentation from sage.combinat.species.misc import accept_size diff --git a/src/sage/combinat/species/partition_species.py b/src/sage/combinat/species/partition_species.py index cf64b1f9a58..cc8d1818821 100644 --- a/src/sage/combinat/species/partition_species.py +++ b/src/sage/combinat/species/partition_species.py @@ -17,7 +17,6 @@ #***************************************************************************** from .species import GenericCombinatorialSpecies -from .generating_series import _integers_from from sage.arith.misc import factorial from .subset_species import SubsetSpeciesStructure from .set_species import SetSpecies diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index aabcaa59b0c..4485e19477a 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -18,7 +18,6 @@ from .species import GenericCombinatorialSpecies from .structure import GenericSpeciesStructure -from .generating_series import _integers_from from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ from sage.combinat.permutation import Permutation, Permutations @@ -225,8 +224,6 @@ def _cis(self, series_ring, base_ring): \prod{n=1}^\infty \frac{1}{1-x_n}. - - EXAMPLES:: sage: P = species.PermutationSpecies() @@ -238,8 +235,11 @@ def _cis(self, series_ring, base_ring): p[1, 1, 1] + p[2, 1] + p[3], p[1, 1, 1, 1] + p[2, 1, 1] + p[2, 2] + p[3, 1] + p[4]] """ + from sage.combinat.sf.sf import SymmetricFunctions + from sage.combinat.partition import Partitions + p = SymmetricFunctions(base_ring).p() CIS = series_ring - return CIS.product_generator( CIS(self._cis_gen(base_ring, i)) for i in _integers_from(ZZ(1)) ) + return CIS(lambda n: sum(p(la) for la in Partitions(n))) def _cis_gen(self, base_ring, m, n): """ diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 22d081bfe59..2e3e8cd895c 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -25,7 +25,7 @@ class CombinatorialSpeciesStructure(SpeciesStructureWrapper): class CombinatorialSpecies(GenericCombinatorialSpecies): - def __init__(self): + def __init__(self, min=None): """ EXAMPLES:: @@ -48,10 +48,7 @@ def __init__(self): self._generating_series = {} self._isotype_generating_series = {} self._cycle_index_series = {} - self._min = None - self._max = None - self._weight = 1 - GenericCombinatorialSpecies.__init__(self, min=None, max=None, weight=None) + GenericCombinatorialSpecies.__init__(self, min=min, max=None, weight=None) _default_structure_class = CombinatorialSpeciesStructure @@ -236,7 +233,7 @@ def _gs(self, series_ring, base_ring): Uninitialized Lazy Laurent Series """ if base_ring not in self._generating_series: - self._generating_series[base_ring] = series_ring(None) + self._generating_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min)) res = self._generating_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): @@ -253,7 +250,7 @@ def _itgs(self, series_ring, base_ring): Uninitialized Lazy Laurent Series """ if base_ring not in self._isotype_generating_series: - self._isotype_generating_series[base_ring] = series_ring(None) + self._isotype_generating_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min)) res = self._isotype_generating_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): @@ -270,7 +267,7 @@ def _cis(self, series_ring, base_ring): Uninitialized Lazy Laurent Series """ if base_ring not in self._cycle_index_series: - self._cycle_index_series[base_ring] = series_ring(None) + self._cycle_index_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min)) res = self._cycle_index_series[base_ring] if hasattr(self, "_reference") and not hasattr(res, "_reference"): @@ -364,7 +361,7 @@ def define(self, x): :: - sage: A = CombinatorialSpecies() + sage: A = CombinatorialSpecies(min=1) sage: A.define(X+A*A) sage: A.generating_series()[0:6] [0, 1, 1, 2, 5, 14] @@ -381,14 +378,12 @@ def define(self, x): sage: X2 = X*X sage: X5 = X2*X2*X - sage: A = CombinatorialSpecies() - sage: B = CombinatorialSpecies() - sage: C = CombinatorialSpecies() + sage: A = CombinatorialSpecies(min=1) + sage: B = CombinatorialSpecies(min=1) + sage: C = CombinatorialSpecies(min=1) sage: A.define(X5+B*B) sage: B.define(X5+C*C) sage: C.define(X2+C*C+A*A) - sage: A.generating_series()[Integer(0):Integer(10) - [0, 0, 0, 0, 0, 1, 0, 0, 1, 2] sage: A.generating_series()[0:15] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] sage: B.generating_series()[0:15] diff --git a/src/sage/combinat/species/series.py b/src/sage/combinat/species/series.py deleted file mode 100644 index 37e3e6e19ed..00000000000 --- a/src/sage/combinat/species/series.py +++ /dev/null @@ -1,1832 +0,0 @@ -""" -Lazy Power Series - -This file provides an implementation of lazy univariate power -series, which uses the stream class for its internal data -structure. The lazy power series keep track of their approximate -order as much as possible without forcing the computation of any -additional coefficients. This is required for recursively defined -power series. - -This code is based on the work of Ralf Hemmecke and Martin Rubey's -Aldor-Combinat, which can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html. -In particular, the relevant section for this file can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse9.html. -""" -# **************************************************************************** -# Copyright (C) 2008 Mike Hansen , -# -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# -# https://www.gnu.org/licenses/ -# **************************************************************************** - -import builtins - -from collections.abc import Iterable -from .stream import Stream, Stream_class -from .series_order import bounded_decrement, increment, inf, unk -from sage.rings.integer import Integer -from sage.misc.misc_c import prod -from functools import partial -from sage.misc.misc import is_iterator -from sage.misc.repr import repr_lincomb -from sage.misc.cachefunc import cached_method - -from sage.rings.ring import Algebra -from sage.structure.parent import Parent -from sage.categories.all import Rings -from sage.structure.element import Element, parent, AlgebraElement - - -class LazyPowerSeriesRing(Algebra): - def __init__(self, R, names=None, element_class=None): - """ - TESTS:: - - sage: from sage.combinat.species.series import LazyPowerSeriesRing - sage: L = LazyPowerSeriesRing(QQ) - - Equality testing is undecidable in general, and not much - efforts are done at this stage to implement equality when - possible. Hence the failing tests below:: - - sage: TestSuite(L).run() - Failure in ... - The following tests failed: _test_additive_associativity, _test_associativity, _test_distributivity, _test_elements, _test_one, _test_prod, _test_zero - - :: - - sage: LazyPowerSeriesRing(QQ, 'z').gen() - z - sage: LazyPowerSeriesRing(QQ, ['z']).gen() - z - sage: LazyPowerSeriesRing(QQ, ['x', 'z']) - Traceback (most recent call last): - ... - NotImplementedError: only univariate lazy power series rings are supported - """ - #Make sure R is a ring with unit element - if R not in Rings(): - raise TypeError("argument R must be a ring") - - #Take care of the names - if names is None: - names = 'x' - elif isinstance(names, (list, tuple)): - if len(names) != 1: - raise NotImplementedError( - 'only univariate lazy power series rings are supported') - names = names[0] - else: - names = str(names) - - self._element_class = element_class if element_class is not None else LazyPowerSeries - self._order = None - self._name = names - self._zero_base_ring = R.zero() - Parent.__init__(self, R, category=Rings()) - - def ngens(self): - """ - EXAMPLES:: - - sage: LazyPowerSeriesRing(QQ).ngens() - 1 - """ - return 1 - - def __repr__(self): - """ - EXAMPLES:: - - sage: LazyPowerSeriesRing(QQ) - Lazy Power Series Ring over Rational Field - """ - return "Lazy Power Series Ring over %s" % self.base_ring() - - def __eq__(self, x): - """ - Check whether ``self`` is equal to ``x``. - - EXAMPLES:: - - sage: LQ = LazyPowerSeriesRing(QQ) - sage: LZ = LazyPowerSeriesRing(ZZ) - sage: LQ == LQ - True - sage: LZ == LQ - False - """ - if not isinstance(x, LazyPowerSeriesRing): - return False - return self.base_ring() == x.base_ring() - - def __ne__(self, other): - """ - Check whether ``self`` is not equal to ``other``. - - EXAMPLES:: - - sage: LQ = LazyPowerSeriesRing(QQ) - sage: LZ = LazyPowerSeriesRing(ZZ) - sage: LQ != LQ - False - sage: LZ != LQ - True - """ - return not (self == other) - - def __hash__(self): - """ - Return the hash of ``self``. - - EXAMPLES:: - - sage: LQ = LazyPowerSeriesRing(QQ) - sage: LZ = LazyPowerSeriesRing(ZZ) - sage: hash(LQ) == hash(LQ) - True - sage: hash(LZ) == hash(LQ) - False - """ - # with a random number, so that the hash is not that of the base ring - return hash((16079305, self.base_ring())) - - def _coerce_impl(self, x): - """ - EXAMPLES:: - - sage: L1 = LazyPowerSeriesRing(QQ) - sage: L2 = LazyPowerSeriesRing(RR) - sage: L2.has_coerce_map_from(L1) - True - sage: L1.has_coerce_map_from(L2) - False - - :: - - sage: a = L1([1]) + L2([1]) - sage: a.coefficients(3) - [2.00000000000000, 2.00000000000000, 2.00000000000000] - """ - return self(x) - - def __call__(self, x=None, order=unk): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: L() - Uninitialized lazy power series - sage: L(1) - 1 - sage: L(ZZ).coefficients(10) - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5] - sage: L(iter(ZZ)).coefficients(10) - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5] - sage: L(Stream(ZZ)).coefficients(10) - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5] - - :: - - sage: a = L([1,2,3]) - sage: a.coefficients(3) - [1, 2, 3] - sage: L(a) is a - True - sage: L_RR = LazyPowerSeriesRing(RR) - sage: b = L_RR(a) - sage: b.coefficients(3) - [1.00000000000000, 2.00000000000000, 3.00000000000000] - sage: L(b) - Traceback (most recent call last): - ... - TypeError: do not know how to coerce ... into self - - TESTS:: - - sage: L(pi) - Traceback (most recent call last): - ... - TypeError: do not know how to coerce pi into self - """ - cls = self._element_class - BR = self.base_ring() - - if x is None: - res = cls(self, stream=None, order=unk, aorder=unk, - aorder_changed=True, is_initialized=False) - res.compute_aorder = uninitialized - return res - - if isinstance(x, LazyPowerSeries): - x_parent = x.parent() - if x_parent.__class__ != self.__class__: - raise ValueError - - if x_parent.base_ring() == self.base_ring(): - return x - else: - if self.base_ring().has_coerce_map_from(x_parent.base_ring()): - return x._new(partial(x._change_ring_gen, self.base_ring()), lambda ao: ao, x, parent=self) - - - if BR.has_coerce_map_from(parent(x)): - x = BR(x) - return self.term(x, 0) - - if isinstance(x, Iterable) and not isinstance(x, Stream_class): - x = iter(x) - - if is_iterator(x): - x = Stream(x) - - if isinstance(x, Stream_class): - aorder = order if order != unk else 0 - return cls(self, stream=x, order=order, aorder=aorder, - aorder_changed=False, is_initialized=True) - elif not isinstance(x, Element): - x = BR(x) - return self.term(x, 0) - - raise TypeError("do not know how to coerce %s into self" % x) - - @cached_method - def zero(self): - """ - Return the zero power series. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: L.zero() - 0 - """ - return self.term(self._zero_base_ring, 0) - - def identity_element(self): - """ - Return the one power series. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: L.identity_element() - 1 - """ - return self(self.base_ring()(1)) - - def gen(self, i=0): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: L.gen().coefficients(5) - [0, 1, 0, 0, 0] - """ - res = self._new_initial(1, Stream([0,1,0])) - res._name = self._name - return res - - def term(self, r, n): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: L.term(0,0) - 0 - sage: L.term(3,2).coefficients(5) - [0, 0, 3, 0, 0] - """ - if n < 0: - raise ValueError("n must be non-negative") - BR = self.base_ring() - if r == 0: - res = self._new_initial(inf, Stream([0])) - res._name = "0" - else: - zero = BR(0) - s = [zero]*n+[BR(r),zero] - res = self._new_initial(n, Stream(s)) - - if n == 0: - res._name = repr(r) - elif n == 1: - res._name = repr(r) + "*" + self._name - else: - res._name = "%s*%s^%s" % (repr(r), self._name, n) - - return res - - def _new_initial(self, order, stream): - """ - Return a new power series with specified order. - - INPUT: - - - - ``order`` - a non-negative integer - - - ``stream`` - a Stream object - - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: L._new_initial(0, Stream([1,2,3,0])).coefficients(5) - [1, 2, 3, 0, 0] - """ - return self._element_class(self, stream=stream, order=order, aorder=order, - aorder_changed=False, is_initialized=True) - - - def _sum_gen(self, series_list): - """ - Return a generator for the coefficients of the sum of the lazy - power series in series_list. - - INPUT: - - - - ``series_list`` - a list of lazy power series - - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: series_list = [ L([1]), L([0,1]), L([0,0,1]) ] - sage: g = L._sum_gen(series_list) - sage: [next(g) for i in range(5)] - [1, 2, 3, 3, 3] - """ - last_index = len(series_list) - 1 - assert last_index >= 0 - n = 0 - while True: - r = sum( [f.coefficient(n) for f in series_list] ) - yield r - n += 1 - - def sum(self, a): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: l = [L(ZZ)]*3 - sage: L.sum(l).coefficients(10) - [0, 3, -3, 6, -6, 9, -9, 12, -12, 15] - """ - return self( self._sum_gen(a) ) - - #Potentially infinite sum - def _sum_generator_gen(self, g): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L([1]) - sage: def f(): - ....: while True: - ....: yield s - sage: g = L._sum_generator_gen(f()) - sage: [next(g) for i in range(10)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - """ - s = Stream(g) - n = 0 - while True: - r = s[n].coefficient(n) - for i in range(len(s)-1): - r += s[i].coefficient(n) - yield r - n += 1 - - def sum_generator(self, g): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: g = [L([1])]*6 + [L(0)] - sage: t = L.sum_generator(g) - sage: t.coefficients(10) - [1, 2, 3, 4, 5, 6, 6, 6, 6, 6] - - :: - - sage: s = L([1]) - sage: def g(): - ....: while True: - ....: yield s - sage: t = L.sum_generator(g()) - sage: t.coefficients(9) - [1, 2, 3, 4, 5, 6, 7, 8, 9] - """ - return self(self._sum_generator_gen(g)) - - #Potentially infinite product - def _product_generator_gen(self, g): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import _integers_from - sage: L = LazyPowerSeriesRing(QQ) - sage: g = (L([1]+[0]*i+[1]) for i in _integers_from(0)) - sage: g2 = L._product_generator_gen(g) - sage: [next(g2) for i in range(10)] - [1, 1, 2, 4, 7, 12, 20, 33, 53, 84] - """ - z = next(g) - yield z.coefficient(0) - yield z.coefficient(1) - - n = 2 - - for x in g: - z = z * x - yield z.coefficient(n) - n += 1 - - while True: - yield z.coefficient(n) - n += 1 - - def product_generator(self, g): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s1 = L([1,1,0]) - sage: s2 = L([1,0,1,0]) - sage: s3 = L([1,0,0,1,0]) - sage: s4 = L([1,0,0,0,1,0]) - sage: s5 = L([1,0,0,0,0,1,0]) - sage: s6 = L([1,0,0,0,0,0,1,0]) - sage: s = [s1, s2, s3, s4, s5, s6] - sage: def g(): - ....: for a in s: - ....: yield a - sage: p = L.product_generator(g()) - sage: p.coefficients(26) - [1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0] - - :: - - sage: def m(n): - ....: yield 1 - ....: while True: - ....: for i in range(n-1): - ....: yield 0 - ....: yield 1 - sage: def s(n): - ....: q = 1/n - ....: yield 0 - ....: while True: - ....: for i in range(n-1): - ....: yield 0 - ....: yield q - - :: - - sage: def lhs_gen(): - ....: n = 1 - ....: while True: - ....: yield L(m(n)) - ....: n += 1 - - :: - - sage: def rhs_gen(): - ....: n = 1 - ....: while True: - ....: yield L(s(n)) - ....: n += 1 - sage: lhs = L.product_generator(lhs_gen()) - sage: rhs = L.sum_generator(rhs_gen()).exponential() - sage: lhs.coefficients(10) - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - sage: rhs.coefficients(10) - [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] - """ - return self(self._product_generator_gen(g)) - - - -class LazyPowerSeries(AlgebraElement): - def __init__(self, A, stream=None, order=None, aorder=None, aorder_changed=True, is_initialized=False, name=None): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L() - sage: loads(dumps(f)) - Uninitialized lazy power series - """ - AlgebraElement.__init__(self, A) - self._stream = stream - self.order = unk if order is None else order - self.aorder = unk if aorder is None else aorder - if self.aorder == inf: - self.order = inf - self.aorder_changed = aorder_changed - self.is_initialized = is_initialized - self._name = name - - def compute_aorder(*args, **kwargs): - """ - The default compute_aorder does nothing. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L(1) - sage: a.compute_aorder() is None - True - """ - return None - - def _get_repr_info(self, x): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([1,2,3]) - sage: a.compute_coefficients(5) - sage: a._get_repr_info('x') - [('1', 1), ('x', 2), ('x^2', 3)] - """ - n = len(self._stream) - m = ['1', x] - m += [x + "^" + str(i) for i in range(2, n)] - c = [self._stream[i] for i in range(n)] - return [(mo, co) for mo, co in zip(m, c) if co != 0] - - def __repr__(self): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L(); s._name = 's'; s - s - - :: - - sage: L() - Uninitialized lazy power series - - :: - - sage: a = L([1,2,3]) - sage: a - O(1) - sage: a.compute_coefficients(2) - sage: a - 1 + 2*x + 3*x^2 + O(x^3) - sage: a.compute_coefficients(4) - sage: a - 1 + 2*x + 3*x^2 + 3*x^3 + 3*x^4 + 3*x^5 + ... - - :: - - sage: a = L([1,2,3,0]) - sage: a.compute_coefficients(5) - sage: a - 1 + 2*x + 3*x^2 - """ - if self._name is not None: - return self._name - - if self.is_initialized: - n = len(self._stream) - x = self.parent()._name - baserepr = repr_lincomb(self._get_repr_info(x)) - if self._stream.is_constant(): - if self._stream[n-1] == 0: - l = baserepr - else: - l = baserepr + " + " + repr_lincomb([(x+"^"+str(i), self._stream[n-1]) for i in range(n, n+3)]) + " + ..." - else: - l = baserepr + " + O(x^%s)" % n if n > 0 else "O(1)" - else: - l = 'Uninitialized lazy power series' - return l - - - def refine_aorder(self): - """ - Refines the approximate order of self as much as possible without - computing any coefficients. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([0,0,0,0,1]) - sage: a.aorder - 0 - sage: a.coefficient(2) - 0 - sage: a.aorder - 0 - sage: a.refine_aorder() - sage: a.aorder - 3 - - :: - - sage: a = L([0,0]) - sage: a.aorder - 0 - sage: a.coefficient(5) - 0 - sage: a.refine_aorder() - sage: a.aorder - Infinite series order - - :: - - sage: a = L([0,0,1,0,0,0]) - sage: a[4] - 0 - sage: a.refine_aorder() - sage: a.aorder - 2 - """ - #If we already know the order, then we don't have - #to worry about the approximate order - if self.order != unk: - return - - #aorder can never be infinity since order would have to - #be infinity as well - assert self.aorder != inf - - if self.aorder == unk or not self.is_initialized: - self.compute_aorder() - else: - #Try to improve the approximate order - ao = self.aorder - c = self._stream - n = c.number_computed() - - - if ao == 0 and n > 0: - while ao < n: - if self._stream[ao] == 0: - self.aorder += 1 - ao += 1 - else: - break - - #Try to recognize the zero series - if ao == n: - #For non-constant series, we cannot do anything - if not c.is_constant(): - return - if c[n-1] == 0: - self.aorder = inf - self.order = inf - return - - if ao < n: - self.order = ao - - - if hasattr(self, '_reference') and self._reference is not None: - self._reference._copy(self) - - def initialize_coefficient_stream(self, compute_coefficients): - """ - Initializes the coefficient stream. - - INPUT: compute_coefficients - - TESTS:: - - sage: from sage.combinat.species.series_order import inf, unk - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L() - sage: compute_coefficients = lambda ao: iter(ZZ) - sage: f.order = inf - sage: f.aorder = inf - sage: f.initialize_coefficient_stream(compute_coefficients) - sage: f.coefficients(5) - [0, 0, 0, 0, 0] - - :: - - sage: f = L() - sage: compute_coefficients = lambda ao: iter(ZZ) - sage: f.order = 1 - sage: f.aorder = 1 - sage: f.initialize_coefficient_stream(compute_coefficients) - sage: f.coefficients(5) - [0, 1, -1, 2, -2] - """ - ao = self.aorder - assert ao != unk - - if ao == inf: - self.order = inf - self._stream = Stream(0) - else: - self._stream = Stream(compute_coefficients(ao)) - - self.is_initialized = True - - def compute_coefficients(self, i): - """ - Computes all the coefficients of self up to i. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([1,2,3]) - sage: a.compute_coefficients(5) - sage: a - 1 + 2*x + 3*x^2 + 3*x^3 + 3*x^4 + 3*x^5 + ... - """ - self.coefficient(i) - - def coefficients(self, n): - """ - Return the first n coefficients of self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1,2,3,0]) - sage: f.coefficients(5) - [1, 2, 3, 0, 0] - """ - return [self.coefficient(i) for i in range(n)] - - def is_zero(self): - """ - Return True if and only if self is zero. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L([0,2,3,0]) - sage: s.is_zero() - False - - :: - - sage: s = L(0) - sage: s.is_zero() - True - - :: - - sage: s = L([0]) - sage: s.is_zero() - False - sage: s.coefficient(0) - 0 - sage: s.coefficient(1) - 0 - sage: s.is_zero() - True - """ - self.refine_aorder() - return self.order == inf - - def set_approximate_order(self, new_order): - """ - Sets the approximate order of self and returns True if the - approximate order has changed otherwise it will return False. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([0,0,0,3,2,1,0]) - sage: f.get_aorder() - 0 - sage: f.set_approximate_order(3) - True - sage: f.set_approximate_order(3) - False - """ - self.aorder_changed = ( self.aorder != new_order ) - self.aorder = new_order - return self.aorder_changed - - def _copy(self, x): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L.term(2, 2) - sage: g = L() - sage: g._copy(f) - sage: g.order - 2 - sage: g.aorder - 2 - sage: g.is_initialized - True - sage: g.coefficients(4) - [0, 0, 2, 0] - """ - self.order = x.order - self.aorder = x.aorder - self.aorder_changed = x.aorder_changed - self.compute_aorder = x.compute_aorder - self.is_initialized = x.is_initialized - self._stream = x._stream - - def define(self, x): - """ - EXAMPLES: Test Recursive 0 - - :: - - sage: L = LazyPowerSeriesRing(QQ) - sage: one = L(1) - sage: monom = L.gen() - sage: s = L() - sage: s._name = 's' - sage: s.define(one+monom*s) - sage: s.aorder - 0 - sage: s.order - Unknown series order - sage: [s.coefficient(i) for i in range(6)] - [1, 1, 1, 1, 1, 1] - - Test Recursive 1 - - :: - - sage: s = L() - sage: s._name = 's' - sage: s.define(one+monom*s*s) - sage: s.aorder - 0 - sage: s.order - Unknown series order - sage: [s.coefficient(i) for i in range(6)] - [1, 1, 2, 5, 14, 42] - - Test Recursive 1b - - :: - - sage: s = L() - sage: s._name = 's' - sage: s.define(monom + s*s) - sage: s.aorder - 1 - sage: s.order - Unknown series order - sage: [s.coefficient(i) for i in range(7)] - [0, 1, 1, 2, 5, 14, 42] - - Test Recursive 2 - - :: - - sage: s = L() - sage: s._name = 's' - sage: t = L() - sage: t._name = 't' - sage: s.define(one+monom*t*t*t) - sage: t.define(one+monom*s*s) - sage: [s.coefficient(i) for i in range(9)] - [1, 1, 3, 9, 34, 132, 546, 2327, 10191] - sage: [t.coefficient(i) for i in range(9)] - [1, 1, 2, 7, 24, 95, 386, 1641, 7150] - - Test Recursive 2b - - :: - - sage: s = L() - sage: s._name = 's' - sage: t = L() - sage: t._name = 't' - sage: s.define(monom + t*t*t) - sage: t.define(monom + s*s) - sage: [s.coefficient(i) for i in range(9)] - [0, 1, 0, 1, 3, 3, 7, 30, 63] - sage: [t.coefficient(i) for i in range(9)] - [0, 1, 1, 0, 2, 6, 7, 20, 75] - - Test Recursive 3 - - :: - - sage: s = L() - sage: s._name = 's' - sage: s.define(one+monom*s*s*s) - sage: [s.coefficient(i) for i in range(10)] - [1, 1, 3, 12, 55, 273, 1428, 7752, 43263, 246675] - """ - self._copy(x) - x._reference = self - - def coefficient(self, n): - """ - Return the coefficient of xn in self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L(ZZ) - sage: [f.coefficient(i) for i in range(5)] - [0, 1, -1, 2, -2] - """ - # The following line must not be written n < self.get_aorder() - # because comparison of Integer and OnfinityOrder is not implemented. - if self.get_aorder() > n: - return self.parent()._zero_base_ring - - assert self.is_initialized - - return self._stream[n] - - def get_aorder(self): - """ - Return the approximate order of self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L.gen() - sage: a.get_aorder() - 1 - """ - self.refine_aorder() - return self.aorder - - def get_order(self): - """ - Return the order of self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L.gen() - sage: a.get_order() - 1 - """ - self.refine_aorder() - return self.order - - def get_stream(self): - """ - Return self's underlying Stream object. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L.gen() - sage: s = a.get_stream() - sage: [s[i] for i in range(5)] - [0, 1, 0, 0, 0] - """ - self.refine_aorder() - return self._stream - - def _approximate_order(self, compute_coefficients, new_order, *series): - if self.is_initialized: - return - - ochanged = self.aorder_changed - - ao = new_order(*[s.aorder for s in series]) - ao = inf if ao == unk else ao - - tchanged = self.set_approximate_order(ao) - - if len(series) == 0: - must_initialize_coefficient_stream = True - tchanged = ochanged = False - elif len(series) == 1 or len(series) == 2: - must_initialize_coefficient_stream = ( self.aorder == unk or self.is_initialized is False) - else: - raise ValueError - - if ochanged or tchanged: - for s in series: - s.compute_aorder() - ao = new_order(*[s.aorder for s in series]) - tchanged = self.set_approximate_order(ao) - - if must_initialize_coefficient_stream: - self.initialize_coefficient_stream(compute_coefficients) - - if hasattr(self, '_reference') and self._reference is not None: - self._reference._copy(self) - - def _new(self, compute_coefficients, order_op, *series, **kwds): - parent = kwds['parent'] if 'parent' in kwds else self.parent() - new_fps = self.__class__(parent, stream=None, order=unk, aorder=self.aorder, - aorder_changed=True, is_initialized=False) - - new_fps.compute_aorder = lambda: new_fps._approximate_order(compute_coefficients, order_op, *series) - return new_fps - - def _add_(self, y): - """ - EXAMPLES: Test Plus 1 - - :: - - sage: from sage.combinat.species.series import * - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: gs0 = L([0]) - sage: gs1 = L([1]) - sage: sum1 = gs0 + gs1 - sage: sum2 = gs1 + gs1 - sage: sum3 = gs1 + gs0 - sage: [gs0.coefficient(i) for i in range(11)] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - sage: [gs1.coefficient(i) for i in range(11)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - sage: [sum1.coefficient(i) for i in range(11)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - sage: [sum2.coefficient(i) for i in range(11)] - [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: [sum3.coefficient(i) for i in range(11)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - - Test Plus 2 - - :: - - sage: gs1 = L([1,2,4,8,0]) - sage: gs2 = L([-1, 0,-1,-9,22,0]) - sage: sum = gs1 + gs2 - sage: sum2 = gs2 + gs1 - sage: [ sum.coefficient(i) for i in range(5) ] - [0, 2, 3, -1, 22] - sage: [ sum.coefficient(i) for i in range(5, 11) ] - [0, 0, 0, 0, 0, 0] - sage: [ sum2.coefficient(i) for i in range(5) ] - [0, 2, 3, -1, 22] - sage: [ sum2.coefficient(i) for i in range(5, 11) ] - [0, 0, 0, 0, 0, 0] - """ - return self._new(partial(self._plus_gen, y), min, self, y) - - add = _add_ - - - - def _plus_gen(self, y, ao): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: gs1 = L([1]) - sage: g = gs1._plus_gen(gs1, 0) - sage: [next(g) for i in range(5)] - [2, 2, 2, 2, 2] - - :: - - sage: g = gs1._plus_gen(gs1, 2) - sage: [next(g) for i in range(5)] - [0, 0, 2, 2, 2] - """ - base_ring = self.parent().base_ring() - zero = base_ring(0) - for n in range(ao): - yield zero - n = ao - while True: - yield self._stream[n] + y._stream[n] - n += 1 - - def _mul_(self, y): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: gs0 = L(0) - sage: gs1 = L([1]) - - :: - - sage: prod0 = gs0 * gs1 - sage: [prod0.coefficient(i) for i in range(11)] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - - :: - - sage: prod1 = gs1 * gs0 - sage: [prod1.coefficient(i) for i in range(11)] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - - :: - - sage: prod2 = gs1 * gs1 - sage: [prod2.coefficient(i) for i in range(11)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - - :: - - sage: gs1 = L([1,2,4,8,0]) - sage: gs2 = L([-1, 0,-1,-9,22,0]) - - :: - - sage: prod1 = gs1 * gs2 - sage: [prod1.coefficient(i) for i in range(11)] - [-1, -2, -5, -19, 0, 0, 16, 176, 0, 0, 0] - - :: - - sage: prod2 = gs2 * gs1 - sage: [prod2.coefficient(i) for i in range(11)] - [-1, -2, -5, -19, 0, 0, 16, 176, 0, 0, 0] - """ - - return self._new(partial(self._times_gen, y), lambda a,b:a+b, self, y) - - times = _mul_ - - def _times_gen(self, y, ao): - r""" - Return an iterator for the coefficients of self \* y. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1,1,0]) - sage: g = f._times_gen(f,0) - sage: [next(g) for i in range(5)] - [1, 2, 1, 0, 0] - """ - base_ring = self.parent().base_ring() - zero = base_ring(0) - - for n in range(ao): - yield zero - - n = ao - while True: - low = self.aorder - high = n - y.aorder - nth_coefficient = zero - - #Handle the zero series - if low == inf or high == inf: - yield zero - n += 1 - continue - - for k in range(low, high+1): - cx = self._stream[k] - if cx == 0: - continue - nth_coefficient += cx * y._stream[n-k] - yield nth_coefficient - n += 1 - - def __pow__(self, n): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1,1,0]) # 1+x - sage: g = f^3 - sage: g.coefficients(4) - [1, 3, 3, 1] - - :: - - sage: f^0 - 1 - """ - if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("n must be a nonnegative integer") - return prod([self]*n, self.parent().identity_element()) - - def __invert__(self): - """ - Return 1 over this power series, i.e. invert this power series. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: x = L.gen() - - Geometric series:: - - sage: a = ~(1-x); a.compute_coefficients(10); a - 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + O(x^11) - - (Shifted) Fibonacci numbers:: - - sage: b = ~(1-x-x^2); b.compute_coefficients(10); b - 1 + x + 2*x^2 + 3*x^3 + 5*x^4 + 8*x^5 - + 13*x^6 + 21*x^7 + 34*x^8 + 55*x^9 + 89*x^10 + O(x^11) - - Series whose constant coefficient is `0` cannot be inverted:: - - sage: ~x - Traceback (most recent call last): - .... - ZeroDivisionError: cannot invert x because constant coefficient is 0 - """ - if self.get_aorder() > 0: - raise ZeroDivisionError( - 'cannot invert {} because ' - 'constant coefficient is 0'.format(self)) - return self._new(self._invert_gen, lambda a: 0, self) - - invert = __invert__ - - def _invert_gen(self, ao): - r""" - Return an iterator for the coefficients of 1 over this power series. - - TESTS:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1, -1, 0]) - sage: g = f._invert_gen(0) - sage: [next(g) for i in range(10)] - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - """ - from itertools import count - - assert ao == 0 - - ic0 = ~self.coefficient(0) - yield ic0 - if self.order == 0: - return - - one = self.parent()(1) - base = one - ic0 * self - base.coefficient(0) - ao_base = base.get_aorder() - assert ao_base >= 1 - - current = one + base - k = 1 - for n in count(1): - while ao_base*k < n: - current = one + base * current - k += 1 - current.coefficient(n) # make sure new current is initialized - ao_base = base.get_aorder() # update this so that while above is faster - yield current.coefficient(n) * ic0 - - def _div_(self, other): - """ - Divide this power series by ``other``. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: x = L.gen() - - Fibonacci numbers:: - - sage: b = x / (1-x-x^2); b.compute_coefficients(10); b - x + x^2 + 2*x^3 + 3*x^4 + 5*x^5 + 8*x^6 - + 13*x^7 + 21*x^8 + 34*x^9 + 55*x^10 + O(x^11) - """ - return self * ~other - - div = _div_ - - def __call__(self, y): - """ - Return the composition of this power series and the power series y. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L([1]) - sage: t = L([0,0,1]) - sage: u = s(t) - sage: u.coefficients(11) - [1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34] - - Test Compose 2 - - :: - - sage: s = L([1]) - sage: t = L([0,0,1,0]) - sage: u = s(t) - sage: u.aorder - 0 - sage: u.order - Unknown series order - sage: u.coefficients(10) - [1, 0, 1, 0, 1, 0, 1, 0, 1, 0] - sage: u.aorder - 0 - sage: u.order - 0 - - Test Compose 3 s = 1/(1-x), t = x/(1-x) s(t) = (1-x)/(1-2x) - - :: - - sage: s = L([1]) - sage: t = L([0,1]) - sage: u = s(t) - sage: u.coefficients(14) - [1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096] - """ - return self._new(partial(self._compose_gen, y), lambda a,b:a*b, self, y) - - composition = __call__ - - def _compose_gen(self, y, ao): - """ - Return a iterator for the coefficients of the composition of this - power series with the power series y. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L([1]) - sage: t = L([0,1]) - sage: g = s._compose_gen(t, 0) - sage: [next(g) for i in range(10)] - [1, 1, 2, 4, 8, 16, 32, 64, 128, 256] - """ - assert y.coefficient(0) == 0 - yield self._stream[0] - z = self.tail().compose(y) * y - z.coefficient(1) - n = 1 - while True: - yield z._stream[n] - n += 1 - - def tail(self): - """ - Return the power series whose coefficients obtained by subtracting - the constant term from this series and then dividing by x. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L(range(20)) - sage: g = f.tail() - sage: g.coefficients(10) - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - """ - return self._new(lambda a0: self.iterator(1), bounded_decrement, self) - - def iterator(self, n=0, initial=None): - """ - Return an iterator for the coefficients of self starting at n. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L(range(10)) - sage: g = f.iterator(2) - sage: [next(g) for i in range(5)] - [2, 3, 4, 5, 6] - sage: g = f.iterator(2, initial=[0,0]) - sage: [next(g) for i in range(5)] - [0, 0, 2, 3, 4] - """ - if initial is not None: - for x in initial: - yield x - while True: - yield self._stream[n] - n += 1 - - compose = __call__ - - def _power_gen(self): - """ - Return a generator for all the powers self^k starting with k = 1. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1,1,0]) - sage: g = f._power_gen() - sage: next(g).coefficients(5) - [1, 1, 0, 0, 0] - sage: next(g).coefficients(5) - [1, 2, 1, 0, 0] - sage: next(g).coefficients(5) - [1, 3, 3, 1, 0] - """ - z = self - while True: - yield z - z = z*self - - def derivative(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: one = L(1) - sage: monom = L.gen() - sage: s = L([1]) - sage: u = s.derivative() - sage: u.coefficients(10) - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - - :: - - sage: s = L() - sage: s._name = 's' - sage: s.define(one+monom*s*s) - sage: u = s.derivative() - sage: u.coefficients(5) #[1*1, 2*2, 3*5, 4*14, 5*42] - [1, 4, 15, 56, 210] - - :: - - sage: s = L([1]) - sage: t = L([0,1]) - sage: u = s(t).derivative() - sage: v = (s.derivative().compose(t))*t.derivative() - sage: u.coefficients(11) - [1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264] - sage: v.coefficients(11) - [1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264] - - :: - - sage: s = L(); s._name='s' - sage: t = L(); t._name='t' - sage: s.define(monom+t*t*t) - sage: t.define(monom+s*s) - sage: u = (s*t).derivative() - sage: v = s.derivative()*t + s*t.derivative() - sage: u.coefficients(10) - [0, 2, 3, 4, 30, 72, 133, 552, 1791, 4260] - sage: v.coefficients(10) - [0, 2, 3, 4, 30, 72, 133, 552, 1791, 4260] - sage: u.coefficients(10) == v.coefficients(10) - True - - :: - - sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])) - sage: d = f.derivative() - sage: d.get_aorder() - 1 - sage: d.coefficients(5) - [0, 8, 15, 24, 0] - """ - return self._new(self._diff_gen, bounded_decrement, self) - - def _diff_gen(self, ao): - """ - Return an iterator for the coefficients of the derivative of self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1]) - sage: g = f._diff_gen(0) - sage: [next(g) for i in range(10)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - """ - n = 1 - while True: - yield n*self._stream[n] - n += 1 - - ########### - #Integrals# - ########### - def integral(self, integration_constant = 0): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: zero = L(0) - sage: s = zero - sage: t = s.integral() - sage: t.is_zero() - True - - :: - - sage: s = zero - sage: t = s.integral(1) - sage: t.coefficients(6) - [1, 0, 0, 0, 0, 0] - sage: t._stream.is_constant() - True - - :: - - sage: s = L.term(1, 0) - sage: t = s.integral() - sage: t.coefficients(6) - [0, 1, 0, 0, 0, 0] - sage: t._stream.is_constant() - True - - :: - - sage: s = L.term(1,0) - sage: t = s.integral(1) - sage: t.coefficients(6) - [1, 1, 0, 0, 0, 0] - sage: t._stream.is_constant() - True - - :: - - sage: s = L.term(1, 4) - sage: t = s.integral() - sage: t.coefficients(10) - [0, 0, 0, 0, 0, 1/5, 0, 0, 0, 0] - - :: - - sage: s = L.term(1,4) - sage: t = s.integral(1) - sage: t.coefficients(10) - [1, 0, 0, 0, 0, 1/5, 0, 0, 0, 0] - - TESTS:: - - sage: from sage.combinat.species.stream import Stream - sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])) - sage: i = f.derivative().integral() - sage: i.get_aorder() - 2 - sage: i.coefficients(5) - [0, 0, 4, 5, 6] - sage: i = f.derivative().integral(1) - sage: i.get_aorder() - 0 - sage: i.coefficients(5) - [1, 0, 4, 5, 6] - """ - if integration_constant == 0: - return self._new(self._integral_zero_gen, increment, self) - else: - L = self.parent() - return L._new_initial(0, Stream(self._integral_nonzero_gen(integration_constant))) - - def _integral_zero_gen(self, ao): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: s = L.gen() - sage: g = s._integral_zero_gen(1) - sage: [next(g) for i in range(5)] - [0, 0, 1/2, 0, 0] - """ - for n in range(ao): - yield self.parent().zero() - n = ao - while True: - #Check to see if the stream is finite - if self.is_finite(n-1): - yield self._stream[n-1] - break - else: - yield (Integer(1)/Integer(n))*self._stream[n-1] - n += 1 - - - def _integral_nonzero_gen(self, integration_constant): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L._new_initial(2, Stream([0,0,4,5,6,0])).derivative() - sage: g = f._integral_nonzero_gen(1) - sage: [next(g) for i in range(5)] - [1, 0, 4, 5, 6] - """ - yield integration_constant - ao = self.aorder - assert ao != unk - - if ao == inf: - yield self.parent()._zero_base_ring - else: - for _ in range(ao-1): - yield self.parent()._zero_base_ring - - n = max(1, ao) - while True: - self.coefficient(n - 1) - - #Check to see if the stream is finite - if self.is_finite(n-1): - yield self.coefficient(n-1) - break - else: - yield (Integer(1)/Integer(n))*self.coefficient(n-1) - n += 1 - - def is_finite(self, n=None): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([0,0,1,0,0]); a - O(1) - sage: a.is_finite() - False - sage: c = a[4] - sage: a.is_finite() - False - sage: a.is_finite(4) - False - sage: c = a[5] - sage: a.is_finite() - True - sage: a.is_finite(4) - True - """ - if self.order is inf: - return True - - s = self._stream - - if n is None: - n = len(s) - - if s.is_constant() and all(s[i] == 0 for i in range(n-1, max(n,len(s)))): - return True - - return False - - def exponential(self): - """ - TESTS:: - - sage: def inv_factorial(): - ....: q = 1 - ....: yield 0 - ....: yield q - ....: n = 2 - ....: while True: - ....: q = q / n - ....: yield q - ....: n += 1 - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L(inv_factorial()) #e^(x)-1 - sage: u = f.exponential() - sage: g = inv_factorial() - sage: z1 = [1,1,2,5,15,52,203,877,4140,21147,115975] - sage: l1 = [z*next(g) for z in z1] - sage: l1 = [1] + l1[1:] - sage: u.coefficients(11) - [1, 1, 1, 5/6, 5/8, 13/30, 203/720, 877/5040, 23/224, 1007/17280, 4639/145152] - sage: l1 == u.coefficients(11) - True - """ - base_ring = self.parent().base_ring() - s = self.parent()() - s.define( (self.derivative()*s).integral(base_ring(1)) ) - return s - - def __getitem__(self, i): - """ - Return the ith coefficient of self. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: f = L([1,2,3,0]) - sage: [f[i] for i in range(5)] - [1, 2, 3, 0, 0] - """ - return self.coefficient(i) - - - ######################### - #Min and max restriction# - ######################### - def restricted(self, min=None, max=None): - """ - Return the power series restricted to the coefficients starting at - ``min`` and going up to, but not including ``max``. - - If ``min`` is not specified, then it is assumed to be zero. If - ``max`` is not specified, then it is assumed to be infinity. - - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([1]) - sage: a.restricted().coefficients(10) - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - sage: a.restricted(min=2).coefficients(10) - [0, 0, 1, 1, 1, 1, 1, 1, 1, 1] - sage: a.restricted(max=5).coefficients(10) - [1, 1, 1, 1, 1, 0, 0, 0, 0, 0] - sage: a.restricted(min=2, max=6).coefficients(10) - [0, 0, 1, 1, 1, 1, 0, 0, 0, 0] - """ - - if ((min is None and max is None) or - (max is None and self.get_aorder() >= min)): - return self - - if min is None: - min = 0 - return self._new(partial(self._restricted_gen, min, max), - lambda ao: builtins.max(ao, min), self) - - def _restricted_gen(self, mn, mx, ao): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: a = L([1]) - sage: g = a._restricted_gen(None, None, 2) - sage: [next(g) for i in range(10)] - [0, 0, 1, 1, 1, 1, 1, 1, 1, 1] - sage: g = a._restricted_gen(1, None, 2) - sage: [next(g) for i in range(10)] - [0, 0, 1, 1, 1, 1, 1, 1, 1, 1] - sage: g = a._restricted_gen(3, None, 2) - sage: [next(g) for i in range(10)] - [0, 0, 0, 1, 1, 1, 1, 1, 1, 1] - - :: - - sage: g = a._restricted_gen(1, 5, 2) - sage: [next(g) for i in range(6)] - [0, 0, 1, 1, 1, 0] - """ - BR = self.parent().base_ring() - for n in range(max(mn,ao)): - yield BR(0) - - n = max(mn, ao) - while True: - if mx is not None and n >= mx: - yield BR(0) - break - else: - yield self._stream[n] - n += 1 - - - ############# - #Change Ring# - ############# - def _change_ring_gen(self, R, ao): - """ - EXAMPLES:: - - sage: L = LazyPowerSeriesRing(QQ) - sage: L2 = LazyPowerSeriesRing(RR) - sage: a = L([1]) - sage: b = L2(a) - sage: b.parent() - Lazy Power Series Ring over Real Field with 53 bits of precision - sage: b.coefficients(3) - [1.00000000000000, 1.00000000000000, 1.00000000000000] - """ - for n in range(ao): - yield R(0) - - n = ao - while True: - yield R(self._stream[n]) - n += 1 - -################################# - - -def uninitialized(): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series import uninitialized - sage: uninitialized() - Traceback (most recent call last): - ... - RuntimeError: we should never be here - """ - raise RuntimeError("we should never be here") diff --git a/src/sage/combinat/species/series_order.py b/src/sage/combinat/species/series_order.py deleted file mode 100644 index f4c42d032bd..00000000000 --- a/src/sage/combinat/species/series_order.py +++ /dev/null @@ -1,294 +0,0 @@ -""" -Series Order - -This file provides some utility classes which are useful when -working with unknown, known, and infinite series orders for -univariate power series. - -This code is based on the work of Ralf Hemmecke and Martin Rubey's -Aldor-Combinat, which can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html. -In particular, the relevant section for this file can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatsu30.html. -""" -from sage.rings.integer import Integer - -class SeriesOrderElement: - pass - -class InfiniteSeriesOrder(SeriesOrderElement): - def __repr__(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: o = InfiniteSeriesOrder(); o - Infinite series order - """ - return "Infinite series order" - - def __add__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: o = InfiniteSeriesOrder() - sage: o + 2 - Infinite series order - sage: o + o - Infinite series order - - :: - - sage: u = UnknownSeriesOrder() - sage: o + u - Unknown series order - - TESTS:: - - sage: o + -1 - Traceback (most recent call last): - ... - ValueError: x must be a positive integer - """ - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return self - - if isinstance(x, InfiniteSeriesOrder): - return self - - if isinstance(x, UnknownSeriesOrder): - return x - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - __radd__ = __add__ - - - def __mul__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: o = InfiniteSeriesOrder() - sage: o * 2 - Infinite series order - sage: o * o - Infinite series order - - :: - - sage: u = UnknownSeriesOrder() - sage: o * u - Unknown series order - - TESTS:: - - sage: o * -1 - Traceback (most recent call last): - ... - ValueError: x must be a positive integer - """ - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - elif x == 0: - return x - return self - - if isinstance(x, InfiniteSeriesOrder): - return self - - if isinstance(x, UnknownSeriesOrder): - return x - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - __rmul__ = __mul__ - - def __lt__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: o = InfiniteSeriesOrder() - sage: o < 2 - False - sage: o < o - False - - :: - - sage: u = UnknownSeriesOrder() - sage: o < u - False - sage: 2 < o # TODO: Not Implemented - True - """ - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return False - - if isinstance(x, InfiniteSeriesOrder): - return False - - if isinstance(x, UnknownSeriesOrder): - return False - - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - - def __gt__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: o = InfiniteSeriesOrder() - sage: o > 2 - True - """ - return True - -class UnknownSeriesOrder(SeriesOrderElement): - def __repr__(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder(); u - Unknown series order - """ - return "Unknown series order" - - def __add__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: u + 2 - Unknown series order - sage: u + u - Unknown series order - """ - - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return self - - if isinstance(x, SeriesOrderElement): - return self - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - __radd__ = __add__ - - - def __mul__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: u * 2 - Unknown series order - sage: u * u - Unknown series order - """ - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return self - - if isinstance(x, SeriesOrderElement): - return self - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - __rmul__ = __mul__ - - def __lt__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: u < 2 - True - sage: o = InfiniteSeriesOrder() - sage: u < o - True - """ - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return True - - if isinstance(x, SeriesOrderElement): - return True - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - def __gt__(self, x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: u > 2 - False - """ - return False - -def bounded_decrement(x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: bounded_decrement(u) - Unknown series order - sage: bounded_decrement(4) - 3 - sage: bounded_decrement(0) - 0 - """ - if isinstance(x, SeriesOrderElement): - return x - - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return max(0, x - 1) - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - - -def increment(x): - """ - EXAMPLES:: - - sage: from sage.combinat.species.series_order import * - sage: u = UnknownSeriesOrder() - sage: increment(u) - Unknown series order - sage: increment(2) - 3 - """ - if isinstance(x, SeriesOrderElement): - return x + 1 - - if isinstance(x, (int, Integer)): - if x < 0: - raise ValueError("x must be a positive integer") - return x+1 - - raise TypeError("x must be a positive integer or a SeriesOrderElement") - -inf = InfiniteSeriesOrder() -unk = UnknownSeriesOrder() diff --git a/src/sage/combinat/species/set_species.py b/src/sage/combinat/species/set_species.py index 71dee4a6682..64313334a2f 100644 --- a/src/sage/combinat/species/set_species.py +++ b/src/sage/combinat/species/set_species.py @@ -17,7 +17,6 @@ #***************************************************************************** from .species import GenericCombinatorialSpecies -from .generating_series import _integers_from from sage.combinat.species.structure import GenericSpeciesStructure from sage.combinat.species.misc import accept_size from sage.structure.unique_representation import UniqueRepresentation diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 797695b0bdf..ee3236f4024 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -22,7 +22,7 @@ sage: leaf = species.SingletonSpecies() sage: internal_node = species.SingletonSpecies(weight=q) sage: L = species.LinearOrderSpecies(min=1) - sage: T = species.CombinatorialSpecies() + sage: T = species.CombinatorialSpecies(min=1) sage: T.define(leaf + internal_node*L(T)) sage: T.isotype_generating_series()[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] @@ -495,7 +495,7 @@ def _get_series(self, series_ring_class, prefix, base_ring=None): def _series_helper(self, series_ring_class, prefix, base_ring=None): """ This code handles much of the common work involved in getting the - generating series for this species (such has determining the + generating series for this species (such as determining the correct base ring to pass down to the subclass, determining which method on the subclass to call to get the series object, etc.) diff --git a/src/sage/combinat/species/stream.py b/src/sage/combinat/species/stream.py deleted file mode 100644 index 56644b399ef..00000000000 --- a/src/sage/combinat/species/stream.py +++ /dev/null @@ -1,501 +0,0 @@ -""" -Streams or Infinite Arrays - -This code is based on the work of Ralf Hemmecke and Martin Rubey's -Aldor-Combinat, which can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html. -In particular, the relevant section for this file can be found at -http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse12.html. -""" -import types -from collections.abc import Iterable -from sage.structure.sage_object import SageObject - - -def _integers_from(n): - """ - Returns a generator for the integers starting at n. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import _integers_from - sage: g = _integers_from(5) - sage: [next(g) for i in range(5)] - [5, 6, 7, 8, 9] - """ - while True: - yield n - n += 1 - -def _apply_function(func, list): - """ - Returns an iterator for func(i) for i in list. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import _apply_function - sage: def square(l): - ....: l.append(l[-1]^2) - ....: return l[-1] - ... - sage: l = [2] - sage: g = _apply_function(square, l) - sage: [next(g) for i in range(5)] - [4, 16, 256, 65536, 4294967296] - """ - while True: - try: - yield func(list) - except Exception: - break - -def Stream(x=None, const=None): - """ - Returns a stream. - - EXAMPLES: We can create a constant stream by just passing a - - :: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream(const=0) - sage: [s[i] for i in range(10)] - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - """ - if const is not None: - return Stream_class(const=const) - elif isinstance(x, Iterable): - return Stream_class(iter(x)) - elif isinstance(x, (types.FunctionType, types.LambdaType)): - return Stream_class(func=x) - - return Stream_class(iter([x,0])) - -class Stream_class(SageObject): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: from builtins import zip - sage: s = Stream(const=0) - sage: len(s) - 1 - sage: [x for (x,i) in zip(s, range(4))] - [0, 0, 0, 0] - sage: len(s) - 1 - - :: - - sage: s = Stream(const=4) - sage: g = iter(s) - sage: l1 = [x for (x,i) in zip(g, range(10))] - sage: l = [4 for k in range(10)] - sage: l == l1 - True - - :: - - sage: h = lambda l: 1 if len(l) < 2 else l[-1] + l[-2] - sage: fib = Stream(h) - sage: [x for (x,i) in zip(fib, range(11))] - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] - - :: - - sage: r = [4, 3, 5, 2, 6, 1, 1, 1, 1, 1] - sage: l = [4, 3, 5, 2, 6, 1] - sage: s = Stream(l) - sage: s[3] = -1 - sage: [x for (x,i) in zip(s, r)] - [4, 3, 5, -1, 6, 1, 1, 1, 1, 1] - sage: s[5] = -2 - sage: [x for (x,i) in zip(s, r)] - [4, 3, 5, -1, 6, -2, 1, 1, 1, 1] - sage: s[6] = -3 - sage: [x for (x,i) in zip(s, r)] - [4, 3, 5, -1, 6, -2, -3, 1, 1, 1] - sage: s[8] = -4 - sage: [x for (x,i) in zip(s, r)] - [4, 3, 5, -1, 6, -2, -3, 1, -4, 1] - sage: a = Stream(const=0) - sage: a[2] = 3 - sage: [x for (x,i) in zip(a, range(4))] - [0, 0, 3, 0] - """ - - def __init__(self, gen=None, const=None, func=None): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream_class, Stream - sage: s = Stream_class(const=4) - sage: loads(dumps(s)) - - - :: - - sage: sorted(s.__dict__.items()) - [('_constant', 4), - ('_gen', None), - ('_last_index', 0), - ('_list', [4]), - ('end_reached', True)] - - :: - - sage: s = Stream(ZZ) - sage: sorted(s.__dict__.items()) - [('_constant', None), - ('_gen', ), - ('_last_index', -1), - ('_list', []), - ('end_reached', False)] - """ - #We define self._list up here so that - #_apply_function can make use of it if - #it needs to. - self._list = [] - - - if func is not None: - if gen is not None: - raise ValueError("you cannot specify both a function and a generator") - gen = _apply_function(func, self._list) - - #Constant stream - if const is not None: - self._list = [const] - self._last_index = 0 # last_index == len(self._list) - 1 - self._gen = None - self._constant = const - self.end_reached = True - else: - self._last_index = -1 # last_index == len(self._list) - 1 - self._gen = gen - self._constant = const - self.end_reached = False - - def __setitem__(self, i, t): - """ - Set the i-th entry of self to t. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - - :: - - sage: s = Stream(const=0) - sage: s[5] - 0 - sage: s.data() - [0] - sage: s[5] = 5 - sage: s[5] - 5 - sage: s.data() - [0, 0, 0, 0, 0, 5] - - :: - - sage: s = Stream(ZZ) - sage: s[10] - -5 - sage: s.data() - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5] - sage: s[10] = 10 - sage: s.data() - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5, 10] - """ - # Compute all of the coefficients up to (and including) the ith one - self[i] - - if i < len(self._list): - #If we are here, we can just change the entry in self._list - self._list[i] = t - else: - #If we are here, then the stream has become constant. We just - #extend self._list with self._constant and then change the - #last entry. - self._list += [ self._constant ] * (i+1 - len(self._list)) - self._last_index = i - self._list[i] = t - - def set_gen(self, gen): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: from builtins import zip - sage: fib = Stream() - sage: def g(): - ....: yield 1 - ....: yield 1 - ....: n = 0 - ....: while True: - ....: yield fib[n] + fib[n+1] - ....: n += 1 - - :: - - sage: fib.set_gen(g()) - sage: [x for (x,i) in zip(fib, range(11))] - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] - - :: - - sage: l = [4,3,5,2,6,1] - sage: s = Stream(l) - sage: s[3] - 2 - sage: len(s) - 4 - sage: g = iter(l) - sage: s.set_gen(g) - sage: s[5] - 3 - sage: len(s) - 6 - """ - self._gen = gen - self.end_reached = False - - def map(self, f): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream(ZZ) - sage: square = lambda x: x^2 - sage: ss = s.map(square) - sage: [ss[i] for i in range(10)] - [0, 1, 1, 4, 4, 9, 9, 16, 16, 25] - - TESTS:: - - sage: from builtins import zip - sage: f = lambda l: 0 if len(l) == 0 else l[-1] + 1 - sage: o = Stream(f) - sage: [x for (x,i) in zip(o, range(10))] - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - sage: double = lambda z: 2*z - sage: t = o.map(double) - sage: [x for (x,i) in zip(t, range(10))] - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] - - :: - - sage: double = lambda z: 2*z - sage: o = Stream([0,1,2,3]) - sage: [x for (x,i) in zip(o, range(6))] - [0, 1, 2, 3, 3, 3] - sage: t = o.map(double) - sage: [x for (x,i) in zip(t, range(6))] - [0, 2, 4, 6, 6, 6] - """ - return Stream((f(x) for x in self)) - - def __getitem__(self, i): - """ - Returns the ith entry of self. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream(ZZ) - sage: [s[i] for i in range(10)] - [0, 1, -1, 2, -2, 3, -3, 4, -4, 5] - sage: s[1] - 1 - - :: - - sage: s = Stream([1,2,3]) - sage: [s[i] for i in range(10)] - [1, 2, 3, 3, 3, 3, 3, 3, 3, 3] - - :: - - sage: s = Stream(QQ) - sage: s[10] - -3 - """ - if i <= self._last_index: - return self._list[i] - elif self.end_reached: - if self._constant is not False: - return self._constant - else: - raise IndexError("out of position") - else: - while self._last_index < i: - try: - self._list.append(next(self._gen)) - self._last_index += 1 - except StopIteration: - self.end_reached = True - self._constant = self._list[-1] - return self[i] - - return self._list[i] - - - def __iter__(self): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream([1,2,3]) - sage: g = iter(s) - sage: [next(g) for i in range(5)] - [1, 2, 3, 3, 3] - """ - i = 0 - while True: - try: - yield self[i] - except IndexError: - break - i += 1 - - def __len__(self): - """ - Returns the number of coefficients computed so far. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: l = [4,3,5,7,4,1,9,7] - sage: s = Stream(l) - sage: s[3] - 7 - sage: len(s) - 4 - sage: s[3] - 7 - sage: len(s) - 4 - sage: s[1] - 3 - sage: len(s) - 4 - sage: s[4] - 4 - sage: len(s) - 5 - - TESTS:: - - sage: l = ['Hello', ' ', 'World', '!'] - sage: s = Stream(l) - sage: len(s) - 0 - sage: s[2] - 'World' - sage: len(s) - 3 - sage: u = "" - sage: for i in range(len(s)): u += s[i] - sage: u - 'Hello World' - sage: v = "" - sage: for i in range(10): v += s[i] - sage: v - 'Hello World!!!!!!!' - sage: len(s) - 4 - """ - return len(self._list) - - number_computed = __len__ - - def data(self): - """ - Returns a list of all the coefficients computed so far. - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream, _integers_from - sage: s = Stream(_integers_from(3)) - sage: s.data() - [] - sage: s[5] - 8 - sage: s.data() - [3, 4, 5, 6, 7, 8] - """ - return self._list - - def is_constant(self): - """ - Returns True if and only if - - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream([1,2,3]) - sage: s.is_constant() - False - sage: s[3] - 3 - sage: s.data() - [1, 2, 3] - sage: s.is_constant() - True - - TESTS:: - - sage: l = [2,3,5,7,11,0] - sage: s = Stream(l) - sage: s.is_constant() - False - sage: s[3] - 7 - sage: s.is_constant() - False - sage: s[5] - 0 - sage: s.is_constant() - False - sage: s[6] - 0 - sage: s.is_constant() - True - - :: - - sage: s = Stream(const='I am constant.') - sage: s.is_constant() - True - """ - return self.end_reached - - - def stretch(self, k): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream(range(1, 10)) - sage: s2 = s.stretch(2) - sage: [s2[i] for i in range(10)] - [1, 0, 2, 0, 3, 0, 4, 0, 5, 0] - """ - return Stream(self._stretch_gen(k)) - - def _stretch_gen(self, k): - """ - EXAMPLES:: - - sage: from sage.combinat.species.stream import Stream - sage: s = Stream(range(1, 10)) - sage: g = s._stretch_gen(2) - sage: [next(g) for i in range(10)] - [1, 0, 2, 0, 3, 0, 4, 0, 5, 0] - """ - yield self[0] - for i in _integers_from(1): - for j in range(k-1): - yield 0 - yield self[i] diff --git a/src/sage/combinat/species/subset_species.py b/src/sage/combinat/species/subset_species.py index 00481adb8d6..763b8bc8053 100644 --- a/src/sage/combinat/species/subset_species.py +++ b/src/sage/combinat/species/subset_species.py @@ -19,7 +19,6 @@ from .species import GenericCombinatorialSpecies from .set_species import SetSpecies -from .generating_series import _integers_from from .structure import GenericSpeciesStructure from sage.combinat.species.misc import accept_size from sage.structure.unique_representation import UniqueRepresentation diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index a83d6cb12c7..05952ad4e8f 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -971,10 +971,10 @@ def change_ring(self, ring): Lazy Taylor Series Ring in z over Rational Field """ P = self.parent() - if P._names is not None: - Q = type(P)(ring, names=P.variable_names(), sparse=P._sparse) - else: + if P._names is None: Q = type(P)(ring, sparse=P._sparse) + else: + Q = type(P)(ring, names=P.variable_names(), sparse=P._sparse) return Q.element_class(Q, self._coeff_stream) # === module structure === From 3b7da1870a5f2b17c99b9ae2beca51535e9ec126 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Mon, 29 Aug 2022 16:49:40 +0100 Subject: [PATCH 062/350] Add optional parameter to select DFS or not --- src/sage/graphs/edge_connectivity.pyx | 71 +++++++++++++++------------ 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index e968d4f827d..19d92bcf9b2 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -171,10 +171,12 @@ cdef class GabowEdgeConnectivity: cdef queue[int] incident_edges_Q # queue of edges cdef int num_start_f_trees # number of f-trees at the beginning of an iteration + cdef int num_joins # number of joined vertices from dfs cdef int* T # whether the an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree + cdef bint dfs # whether or not we should use dfs-based fast initialization - def __init__(self, G): + def __init__(self, G, dfs=True): r""" Initialize this object. @@ -189,6 +191,7 @@ cdef class GabowEdgeConnectivity: sage: GabowEdgeConnectivity(D).edge_connectivity() 4 """ + self.dfs = dfs self.ec_checked = False from sage.graphs.digraph import DiGraph if not isinstance(G, DiGraph): @@ -368,31 +371,33 @@ cdef class GabowEdgeConnectivity: cdef int njoins = 0 cdef int z - # There's only one f-tree, so we already have a complete k-intersection - # We save the edges and advance to the next iteration - if self.num_start_f_trees < self.n-1: - self.re_init(tree) - else: - # There are several f-trees, and we try to join them - while njoins < self.num_start_f_trees-1: - # Get the root of an active subtree or INT_MAX if none exists - z = self.choose_root() - while z != INT_MAX: - if self.search_joining(z): - # We have augmented the root of the corresponding f_tree - njoins += 1 - else: - # We cannot find a tree - return False - - z = self.choose_root() - - # Trace the paths in order to transfer the edges to the appropriate - # tree Ti - self.augmentation_algorithm() - # Reinitialize data structures and make all f_trees active for next round + self.num_start_f_trees = self.n - self.num_joins + # There are fewer than n f-trees, and prepare to join thme + # If there's only one f-tree, we just save the edges and advance to the next iteration + if self.dfs: + if self.num_start_f_trees < self.n - 1: self.re_init(tree) - sig_check() + + # There are n f-trees, and we try to join them + while njoins < self.num_start_f_trees-1: + # Get the root of an active subtree or INT_MAX if none exists + z = self.choose_root() + while z != INT_MAX: + if self.search_joining(z): + # We have augmented the root of the corresponding f_tree + njoins += 1 + else: + # We cannot find a tree + return False + + z = self.choose_root() + + # Trace the paths in order to transfer the edges to the appropriate + # tree Ti + self.augmentation_algorithm() + # Reinitialize data structures and make all f_trees active for next round + self.re_init(tree) + sig_check() return True @@ -432,10 +437,11 @@ cdef class GabowEdgeConnectivity: self.root[j] = j self.forests[j] = True - self.num_start_f_trees = 0 + self.num_joins = 0 # Initialize T_k to be a DFS spanning forest of G \ T - self.compute_dfs_tree() + if self.dfs: + self.compute_dfs_tree() # Set inactive the f-trees of the root vertex self.forests[self.root_vertex] = False @@ -493,6 +499,7 @@ cdef class GabowEdgeConnectivity: self.root[v] = r self.forests[v] = False self.my_edge_state[e_id] = self.current_tree + self.num_joins += 1 # recursively find more vertices and grow the subtree rooted at r self.find_dfs_tree(v, r) @@ -935,14 +942,16 @@ cdef class GabowEdgeConnectivity: # Arrange the edges of each tree for j in range(tree + 1): - for e in range(len(self.tree_edges[j])): - e_id = self.tree_edges[j][e] - self.T[e_id] = False + if self.dfs: + for e in range(len(self.tree_edges[j])): + e_id = self.tree_edges[j][e] + self.T[e_id] = False self.tree_edges[j].clear() for j in range(self.m): if self.my_edge_state[j] != self.UNUSED: self.tree_edges[self.my_edge_state[j]].push_back(j) - self.T[j] = True + if self.dfs: + self.T[j] = True for j in range(tree + 1): if not j or j == tree or self.tree_flag[j]: From 41ed8a7d120ee2bb49570ecdc774451e596e22c9 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 22 Aug 2022 19:33:14 +0800 Subject: [PATCH 063/350] remove experimental warnings for composite elliptic-curve isogenies --- src/sage/schemes/elliptic_curves/ell_field.py | 6 ++---- src/sage/schemes/elliptic_curves/hom.py | 1 - src/sage/schemes/elliptic_curves/hom_composite.py | 13 +------------ 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 68b8375daee..6b64df4d075 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1098,7 +1098,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al kernel point of odd order `\geq 5`. This algorithm is selected using ``algorithm="velusqrt"``. - - Factored Isogenies (*experimental* --- see + - Factored Isogenies (see :mod:`~sage.schemes.elliptic_curves.hom_composite`): Given a list of points which generate a composite-order subgroup, decomposes the isogeny into prime-degree steps. @@ -1200,9 +1200,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al sage: E = EllipticCurve(GF(2^32-5), [170246996, 2036646110]) sage: P = E.lift_x(2) - sage: E.isogeny(P, algorithm="factored") # experimental - doctest:warning - ... + sage: E.isogeny(P, algorithm="factored") Composite morphism of degree 1073721825 = 3^4*5^2*11*19*43*59: From: Elliptic Curve defined by y^2 = x^3 + 170246996*x + 2036646110 over Finite Field of size 4294967291 To: Elliptic Curve defined by y^2 = x^3 + 272790262*x + 1903695400 over Finite Field of size 4294967291 diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 8d707e8e6b7..35c23e8fef2 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -221,7 +221,6 @@ def degree(self): is the product of the degrees of the individual factors:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - doctest:warning ... sage: E = EllipticCurve(GF(419), [1,0]) sage: P, = E.gens() sage: phi = EllipticCurveHom_composite(E, P+P) diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 32b1fa9e0bb..6528d7bef5d 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -7,12 +7,6 @@ while exposing (close to) the same interface as "normal", unfactored elliptic-curve isogenies. -.. WARNING:: - - This module is currently considered experimental. - It may change in a future release without prior warning, or even - be removed altogether if things turn out to be unfixably broken. - EXAMPLES: The following example would take quite literally forever with the @@ -20,8 +14,6 @@ decomposing into prime steps is exponentially faster:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - doctest:warning - ... sage: p = 3 * 2^143 - 1 sage: GF(p^2).inject_variables() Defining z2 @@ -90,9 +82,6 @@ from sage.schemes.elliptic_curves.ell_curve_isogeny import EllipticCurveIsogeny from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism -from sage.misc.superseded import experimental_warning -experimental_warning(32744, 'EllipticCurveHom_composite is experimental code.') - #TODO: implement sparse strategies? (cf. the SIKE cryptosystem) def _eval_factored_isogeny(phis, P): @@ -789,7 +778,7 @@ def make_default(): This method exists only temporarily to make testing more convenient while :class:`EllipticCurveHom_composite` is - experimental. + not yet the default. EXAMPLES:: From c9726da07a369d588216e9eb23e5d82eaf00fc46 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 22 Aug 2022 19:42:42 +0800 Subject: [PATCH 064/350] change default composition of EllipticCurveHom to EllipticCurveHom_composite --- .../elliptic_curves/ell_curve_isogeny.py | 7 +-- src/sage/schemes/elliptic_curves/hom.py | 9 ++-- .../schemes/elliptic_curves/hom_composite.py | 45 +++---------------- 3 files changed, 12 insertions(+), 49 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 9c3cb195eff..516a713e422 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -813,18 +813,15 @@ class EllipticCurveIsogeny(EllipticCurveHom): sage: phi.codomain() Elliptic Curve defined by y^2 + x*y = x^3 + 24*x + 6 over Finite Field of size 31 - Composition tests (see :trac:`16245`):: + Composition tests (see :trac:`16245`, cf. :trac:`34410`):: sage: E = EllipticCurve(j=GF(7)(0)) sage: phi = E.isogeny([E(0), E((0,1)), E((0,-1))]); phi Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 sage: phi2 = phi * phi; phi2 - Composite map: + Composite morphism of degree 9 = 3^2: From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 To: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 - Defn: Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 - then - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7 Examples over relative number fields used not to work (see :trac:`16779`):: diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 35c23e8fef2..d0973ef6123 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -75,12 +75,9 @@ def _composition_(self, other, homset): sage: phi * iso Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 sage: phi.dual() * phi - Composite map: + Composite morphism of degree 4 = 2^2: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 - Defn: Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 - then - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 """ if not isinstance(self, EllipticCurveHom) or not isinstance(other, EllipticCurveHom): raise TypeError(f'cannot compose {type(self)} with {type(other)}') @@ -93,8 +90,8 @@ def _composition_(self, other, homset): if ret is not NotImplemented: return ret - # fall back to generic formal composite map - return Morphism._composition_(self, other, homset) + from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite + return EllipticCurveHom_composite.from_factors([other, self]) @staticmethod diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 6528d7bef5d..1e2ca2658b0 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -769,48 +769,17 @@ def is_injective(self): @staticmethod def make_default(): r""" - Calling this method will override the composition method - of :class:`EllipticCurveHom` such that it constructs a - :class:`EllipticCurveHom_composite` object by default, - rather than a :class:`sage.categories.map.FormalCompositeMap`. + This method does nothing and will be removed. - .. WARNING:: - - This method exists only temporarily to make testing more - convenient while :class:`EllipticCurveHom_composite` is - not yet the default. + (It is a leftover from the time when :class:`EllipticCurveHom_composite` + wasn't the default yet.) EXAMPLES:: sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite - sage: E = EllipticCurve(GF(587), [1,0]) - sage: P = E(3,404) - sage: phi = E.isogeny(7*P) - sage: psi = phi.codomain().isogeny(phi(P)) - sage: psi * phi - Composite map: - From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 587 - To: Elliptic Curve defined by y^2 = x^3 + 296*x + 164 over Finite Field of size 587 - Defn: Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 587 to Elliptic Curve defined by y^2 = x^3 + 126*x + 500 over Finite Field of size 587 - then - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 126*x + 500 over Finite Field of size 587 to Elliptic Curve defined by y^2 = x^3 + 296*x + 164 over Finite Field of size 587 sage: EllipticCurveHom_composite.make_default() - sage: psi * phi - Composite morphism of degree 49 = 7^2: - From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 587 - To: Elliptic Curve defined by y^2 = x^3 + 296*x + 164 over Finite Field of size 587 - sage: (psi * phi).factors() - (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 587 to Elliptic Curve defined by y^2 = x^3 + 126*x + 500 over Finite Field of size 587, - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 126*x + 500 over Finite Field of size 587 to Elliptic Curve defined by y^2 = x^3 + 296*x + 164 over Finite Field of size 587) + doctest:warning ... """ - def _composition_(self, other, homset): - if not isinstance(self, EllipticCurveHom) or not isinstance(other, EllipticCurveHom): - raise TypeError(f'cannot compose {type(self)} with {type(other)}') - ret = self._composition_impl(self, other) - if ret is not NotImplemented: - return ret - ret = other._composition_impl(self, other) - if ret is not NotImplemented: - return ret - return EllipticCurveHom_composite.from_factors([other, self]) - EllipticCurveHom._composition_ = _composition_ + from sage.misc.superseded import deprecation + deprecation(34410, 'calling EllipticCurveHom_composite.make_default() is no longer necessary') + From 0d42205811be6c0954c3da08740c422c4ff29567 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 30 Aug 2022 07:28:27 +0800 Subject: [PATCH 065/350] make PolynomialQuotientRing_generic inherit from QuotientRing_generic --- src/sage/rings/homset.py | 4 +++- .../rings/polynomial/polynomial_quotient_ring.py | 14 ++++++++------ src/sage/rings/quotient_ring.py | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index c0db5c9210b..6f7a2d4b415 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -49,7 +49,9 @@ def RingHomset(R, S, category = None): """ if quotient_ring.is_QuotientRing(R): - return RingHomset_quo_ring(R, S, category = category) + from .polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing + if not is_PolynomialQuotientRing(R): # backwards compatibility + return RingHomset_quo_ring(R, S, category = category) return RingHomset_generic(R, S, category = category) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index bb5d8356be6..f425e9693c2 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -256,7 +256,7 @@ def is_PolynomialQuotientRing(x): return isinstance(x, PolynomialQuotientRing_generic) -class PolynomialQuotientRing_generic(CommutativeRing): +class PolynomialQuotientRing_generic(QuotientRing_generic): """ Quotient of a univariate polynomial ring by an ideal. @@ -417,7 +417,9 @@ def __init__(self, ring, polynomial, name=None, category=None): # Note that is_finite() is cheap so it does not seem to do a lazy # _refine_category_() in is_finite() as we do for is_field() category = category.Finite() - CommutativeRing.__init__(self, ring, names=name, category=category) + + QuotientRing_generic.__init__(self, ring, ring.ideal(polynomial), names=name, category=category) + self._base = ring # backwards compatibility -- different from QuotientRing_generic _ideal_class_ = QuotientRing_generic._ideal_class_ @@ -779,11 +781,11 @@ def construction(self): -- Simon King (2010-05) """ from sage.categories.pushout import QuotientFunctor - Cover = self.base() + Cover = self.__ring + kwds = {} if Cover in CommutativeRings(): - return QuotientFunctor([self.modulus()]*Cover, self.variable_names(), - domain=CommutativeRings(), codomain=CommutativeRings()), Cover - return QuotientFunctor([self.modulus()]*self.base(), self.variable_names()), Cover + kwds['domain'] = kwds['codomain'] = CommutativeRings() + return QuotientFunctor([self.modulus()]*Cover, self.variable_names(), **kwds), Cover @cached_method def base_ring(self): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index cae440d543d..ea096e68343 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -956,9 +956,8 @@ def ideal(self, *gens, **kwds): """ if len(gens) == 1: gens = gens[0] - from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular - if not isinstance(self.__R, MPolynomialRing_libsingular) and \ - (not hasattr(self.__R, '_has_singular') or not self.__R._has_singular): + from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base + if not (isinstance(self.__R, MPolynomialRing_base) and self.__R._has_singular): # pass through return super().ideal(gens, **kwds) if is_SingularElement(gens): @@ -1224,7 +1223,8 @@ def _singular_(self, singular=singular_default): Q._check_valid() return Q except (AttributeError, ValueError): - return self._singular_init_(singular) + self.__singular = self._singular_init_(singular) + return self.__singular def _singular_init_(self, singular=None): """ From c95d42979c5f0a0c12b725fcb7f139f1954b3e80 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 1 Sep 2022 17:50:06 +0900 Subject: [PATCH 066/350] Refactor identity morphism --- src/sage/categories/homset.py | 10 +-- src/sage/schemes/affine/affine_homset.py | 75 +++++++++++++------ src/sage/schemes/affine/affine_space.py | 24 +++++- src/sage/schemes/generic/algebraic_scheme.py | 16 ++++ src/sage/schemes/generic/ambient_space.py | 21 ++++++ src/sage/schemes/generic/homset.py | 38 +++++----- src/sage/schemes/generic/morphism.py | 60 +++++++++++++-- src/sage/schemes/generic/scheme.py | 2 +- .../con_rational_function_field.py | 2 +- .../schemes/projective/projective_homset.py | 68 +++++++++++++---- .../schemes/projective/projective_morphism.py | 19 +++++ .../schemes/projective/projective_space.py | 23 +++++- src/sage/schemes/toric/homset.py | 2 +- 13 files changed, 284 insertions(+), 76 deletions(-) diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 4fe021b86ca..480b3346223 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -47,8 +47,10 @@ - Simon King (2013-02): added examples """ + # **************************************************************************** -# Copyright (C) 2005 David Kohel , William Stein +# Copyright (C) 2005 David Kohel , +# William Stein # # Distributed under the terms of the GNU General Public License (GPL) # @@ -62,7 +64,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - from sage.categories.category import Category, JoinCategory from . import morphism from sage.structure.parent import Parent, Set_generic @@ -86,7 +87,6 @@ def Hom(X, Y, category=None, check=True): INPUT: - - ``X`` -- an object of a category - ``Y`` -- an object of a category @@ -743,8 +743,6 @@ def __bool__(self): """ return True - - def homset_category(self): """ Return the category that this is a Hom in, i.e., this is typically @@ -1083,7 +1081,7 @@ def __ne__(self, other): True """ return not (self == other) - + def __contains__(self, x): """ Test whether the parent of the argument is ``self``. diff --git a/src/sage/schemes/affine/affine_homset.py b/src/sage/schemes/affine/affine_homset.py index b9260996204..98b3b3a8994 100644 --- a/src/sage/schemes/affine/affine_homset.py +++ b/src/sage/schemes/affine/affine_homset.py @@ -23,15 +23,16 @@ - Ben Hutz (2018): add numerical point support """ - -#***************************************************************************** -# Copyright (C) 2006 William Stein +# ***************************************************************************** +# Copyright (C) 2006 William Stein # -# Distributed under the terms of the GNU General Public License (GPL) -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +# ***************************************************************************** + +from copy import copy from sage.misc.verbose import verbose from sage.rings.integer_ring import ZZ @@ -42,13 +43,13 @@ from sage.categories.number_fields import NumberFields from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -import sage.schemes.generic.homset -from copy import copy +from sage.schemes.generic.homset import SchemeHomset_points, SchemeHomset_generic + +# ******************************************************************* +# Affine varieties +# ******************************************************************* -#******************************************************************* -# Affine varieties -#******************************************************************* -class SchemeHomset_points_spec(sage.schemes.generic.homset.SchemeHomset_generic): +class SchemeHomset_points_spec(SchemeHomset_generic): """ Set of rational points of an affine variety. @@ -62,7 +63,6 @@ class SchemeHomset_points_spec(sage.schemes.generic.homset.SchemeHomset_generic) sage: SchemeHomset_points_spec(Spec(QQ), Spec(QQ)) Set of rational points of Spectrum of Rational Field """ - def _element_constructor_(self, *args, **kwds): """ The element constructor. @@ -86,7 +86,7 @@ def _element_constructor_(self, *args, **kwds): Defn: Ring endomorphism of Rational Field Defn: 1 |--> 1 """ - return sage.schemes.generic.homset.SchemeHomset_generic._element_constructor_(self, *args, **kwds) + return super()._element_constructor_(*args, **kwds) def _repr_(self): """ @@ -101,14 +101,47 @@ def _repr_(self): sage: S._repr_() 'Set of rational points of Spectrum of Rational Field' """ - return 'Set of rational points of '+str(self.codomain()) + return 'Set of rational points of {}'.format(self.codomain()) + + +class SchemeHomset_polynomial_affine_space(SchemeHomset_generic): + """ + Set of morphisms between affine spaces defined by polynomials. + + EXAMPLES:: + + sage: A. = AffineSpace(2, QQ) + sage: Hom(A, A) + Set of morphisms + From: Affine Space of dimension 2 over Rational Field + To: Affine Space of dimension 2 over Rational Field + """ + def identity(self): + """ + The identity morphism of this homset. + + EXAMPLES:: + + sage: A. = AffineSpace(2, QQ) + sage: I = A.identity_morphism() + sage: I.parent() + Set of morphisms + From: Affine Space of dimension 2 over Rational Field + To: Affine Space of dimension 2 over Rational Field + sage: _.identity() == I + True + """ + if self.is_endomorphism_set(): + from sage.schemes.generic.morphism import SchemeMorphism_polynomial_id + return SchemeMorphism_polynomial_id(self.domain()) + raise TypeError("identity map is only defined for endomorphisms") +# ******************************************************************* +# Affine varieties +# ******************************************************************* -#******************************************************************* -# Affine varieties -#******************************************************************* -class SchemeHomset_points_affine(sage.schemes.generic.homset.SchemeHomset_points): +class SchemeHomset_points_affine(SchemeHomset_points): """ Set of rational points of an affine variety. diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index a4c48b334c3..ba56ef9fc8d 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -20,21 +20,24 @@ from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.categories.map import Map from sage.categories.fields import Fields -_Fields = Fields() +from sage.categories.homset import Hom from sage.categories.number_fields import NumberFields from sage.misc.latex import latex from sage.misc.mrange import cartesian_product_iterator +from sage.matrix.constructor import matrix from sage.structure.category_object import normalize_names from sage.schemes.generic.scheme import AffineScheme from sage.schemes.generic.ambient_space import AmbientSpace -from sage.schemes.affine.affine_homset import SchemeHomset_points_affine +from sage.schemes.affine.affine_homset import (SchemeHomset_points_affine, + SchemeHomset_polynomial_affine_space) from sage.schemes.affine.affine_morphism import (SchemeMorphism_polynomial_affine_space, SchemeMorphism_polynomial_affine_space_field, SchemeMorphism_polynomial_affine_space_finite_field) from sage.schemes.affine.affine_point import (SchemeMorphism_point_affine, SchemeMorphism_point_affine_field, SchemeMorphism_point_affine_finite_field) -from sage.matrix.constructor import matrix + +_Fields = Fields() def is_AffineSpace(x): r""" @@ -225,7 +228,6 @@ def __iter__(self): for v in cartesian_product_iterator([R for _ in range(n)]): yield C._point(AHom, v, check=False) - def ngens(self): """ Return the number of generators of self, i.e. the number of @@ -363,6 +365,20 @@ def _morphism(self, *args, **kwds): """ return SchemeMorphism_polynomial_affine_space(*args, **kwds) + def _homset(self, *args, **kwds): + """ + Construct the Hom-set. + + EXAMPLES:: + + sage: A. = AffineSpace(2, QQ) + sage: Hom(A, A) + Set of morphisms + From: Affine Space of dimension 2 over Rational Field + To: Affine Space of dimension 2 over Rational Field + """ + return SchemeHomset_polynomial_affine_space(*args, **kwds) + def _point_homset(self, *args, **kwds): """ Construct a Hom-set for this affine space. diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index 22dbacd8fe0..60d883905fe 100644 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -341,6 +341,22 @@ def ambient_space(self): """ return self.__A + def identity_morphism(self): + """ + Return the identity morphism. + + OUTPUT: the identity morphism of the scheme ``self`` + + EXAMPLES:: + + sage: X = Spec(QQ) + sage: X.identity_morphism() + Scheme endomorphism of Spectrum of Rational Field + Defn: Identity map + """ + from sage.schemes.generic.morphism import SchemeMorphism_polynomial_id + return SchemeMorphism_polynomial_id(self) + def embedding_morphism(self): r""" Return the default embedding morphism of ``self``. diff --git a/src/sage/schemes/generic/ambient_space.py b/src/sage/schemes/generic/ambient_space.py index bcf742c8b25..616f8473ead 100644 --- a/src/sage/schemes/generic/ambient_space.py +++ b/src/sage/schemes/generic/ambient_space.py @@ -279,6 +279,27 @@ def defining_polynomials(self): """ return () + def identity_morphism(self): + """ + Return the identity morphism. + + OUTPUT: the identity morphism of the scheme ``self`` + + EXAMPLES:: + + sage: A = AffineSpace(2, GF(3)) + sage: A.identity_morphism() + Scheme endomorphism of Affine Space of dimension 2 over Finite Field of size 3 + Defn: Identity map + + sage: P = ProjectiveSpace(3, ZZ) + sage: P.identity_morphism() + Scheme endomorphism of Projective Space of dimension 3 over Integer Ring + Defn: Identity map + """ + from sage.schemes.generic.morphism import SchemeMorphism_polynomial_id + return SchemeMorphism_polynomial_id(self) + ###################################################################### # Associated MPolynomial ring generators ###################################################################### diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 601e80b7f49..49aa3a2d3f8 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -25,16 +25,15 @@ - Ben Hutz (June 2012): added support for projective ring """ - -#***************************************************************************** -# Copyright (C) 2011 Volker Braun -# Copyright (C) 2006 William Stein +# ***************************************************************************** +# Copyright (C) 2011 Volker Braun +# Copyright (C) 2006 William Stein # -# Distributed under the terms of the GNU General Public License (GPL) -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +# ***************************************************************************** from sage.categories.homset import HomsetWithBase from sage.structure.factory import UniqueFactory @@ -70,9 +69,10 @@ def is_SchemeHomset(H): return isinstance(H, SchemeHomset_generic) -#******************************************************************* -# Factory for Hom sets of schemes -#******************************************************************* +# ******************************************************************* +# Factory for Hom sets of schemes +# ******************************************************************* + class SchemeHomsetFactory(UniqueFactory): """ Factory for Hom-sets of schemes. @@ -212,10 +212,10 @@ def create_object(self, version, key, **extra_args): SchemeHomset = SchemeHomsetFactory('sage.schemes.generic.homset.SchemeHomset') +# ******************************************************************* +# Base class +# ******************************************************************* -#******************************************************************* -# Base class -#******************************************************************* class SchemeHomset_generic(HomsetWithBase): r""" The base class for Hom-sets of schemes. @@ -393,9 +393,11 @@ def _element_constructor_(self, x, check=True): raise TypeError("x must be a ring homomorphism, list or tuple") -#******************************************************************* -# Base class for points -#******************************************************************* + +# ******************************************************************* +# Base class for points +# ******************************************************************* + class SchemeHomset_points(SchemeHomset_generic): """ Set of rational points of the scheme. diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py index 85d2c34db59..d3fe7abd885 100644 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -667,6 +667,7 @@ def glue_along_domains(self, other): from . import glue return glue.GluedScheme(self, other) + class SchemeMorphism_id(SchemeMorphism): """ Return the identity morphism from `X` to itself. @@ -927,11 +928,11 @@ def ring_homomorphism(self): ############################################################################ -# Morphisms between schemes given on points -# The _affine and _projective below refer to the CODOMAIN. -# The domain can be either affine or projective regardless -# of the class +# Morphisms between schemes given on points. The _affine and _projective below +# refer to the CODOMAIN. The domain can be either affine or projective +# regardless of the class ############################################################################ + class SchemeMorphism_polynomial(SchemeMorphism): r""" A morphism of schemes determined by polynomials that define what @@ -1019,6 +1020,26 @@ def __init__(self, parent, polys, check=True): SchemeMorphism.__init__(self, parent) + def __eq__(self, other): + """ + Check equality of ``self`` and ``other``. + + INPUT: + + - ``other`` -- a morphism + + EXAMPLES:: + + sage: A. = AffineSpace(2, QQ) + sage: I = A.identity_morphism() + sage: I.parent().identity() == I + True + """ + if isinstance(other, SchemeMorphism_polynomial): + if self.parent() == other.parent() and self._polys == other._polys: + return True + raise TypeError('cannot determine equality') + def defining_polynomials(self): """ Return the defining polynomials. @@ -1207,7 +1228,6 @@ def _call_with_args(self, x, args, kwds): P = [f(x._coords) for f in self.defining_polynomials()] return self._codomain.point(P,check) - def _repr_defn(self): """ Return a string representation of the definition of ``self``. @@ -1731,6 +1751,36 @@ def _composition_(self, other, homset): return homset([p(*opolys) for p in self._polys]) +class SchemeMorphism_polynomial_id(SchemeMorphism_id, SchemeMorphism_polynomial): + """ + Return the identity morphism from `X` to itself. + + INPUT: + + - ``X`` -- an affine or projective scheme + + EXAMPLES:: + + sage: X = Spec(ZZ) + sage: X.identity_morphism() # indirect doctest + Scheme endomorphism of Spectrum of Integer Ring + Defn: Identity map + """ + def __init__(self, X): + """ + Initialize. + + TESTS:: + + sage: A = AffineSpace(2, GF(3)) + sage: A.identity_morphism().defining_polynomials() + (x0, x1) + """ + super().__init__(X) + variables = X.ambient_space().coordinate_ring().gens() + SchemeMorphism_polynomial.__init__(self, X.Hom(X), variables, check=False) + + ############################################################################ # Rational points on schemes, which we view as morphisms determined # by coordinates. diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index cf76b537e8b..3474d822f1e 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -646,7 +646,7 @@ def _Hom_(self, Y, category=None, check=True): sage: E = EllipticCurve('37a1') sage: Hom(E, E).__class__ - + sage: Hom(Spec(ZZ), Spec(ZZ)).__class__ diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py index 66147eba580..0d1d457f085 100644 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -138,7 +138,7 @@ def has_rational_point(self, point=False, algorithm='default', sage: F. = QuadraticField(-1) sage: R. = F[] sage: C = Conic([1,i*t,-t^2+4]) - sage: C.has_rational_point(point = True) + sage: C.has_rational_point(point=True) (True, (-t - 2*i : -2*i : 1)) It works on non-diagonal conics as well:: diff --git a/src/sage/schemes/projective/projective_homset.py b/src/sage/schemes/projective/projective_homset.py index 0f7b6abce52..b70acc76452 100644 --- a/src/sage/schemes/projective/projective_homset.py +++ b/src/sage/schemes/projective/projective_homset.py @@ -27,21 +27,20 @@ - Ben Hutz (2018): add numerical point support """ - -#***************************************************************************** -# Copyright (C) 2011 Volker Braun -# Copyright (C) 2006 William Stein +# ***************************************************************************** +# Copyright (C) 2011 Volker Braun +# Copyright (C) 2006 William Stein # -# Distributed under the terms of the GNU General Public License (GPL) -# as published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +# ***************************************************************************** from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR from sage.rings.cc import CC -from sage.schemes.generic.homset import SchemeHomset_points +from sage.schemes.generic.homset import SchemeHomset_points, SchemeHomset_generic from sage.misc.verbose import verbose @@ -53,9 +52,11 @@ from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme from copy import copy -#******************************************************************* -# Projective varieties -#******************************************************************* + +# ******************************************************************* +# Projective varieties +# ******************************************************************* + class SchemeHomset_points_projective_field(SchemeHomset_points): """ Set of rational points of a projective variety over a field. @@ -459,6 +460,7 @@ def numerical_points(self, F=None, **kwds): return rat_points raise NotImplementedError('numerical approximation of points only for dimension 0 subschemes') + class SchemeHomset_points_projective_ring(SchemeHomset_points): """ Set of rational points of a projective variety over a commutative ring. @@ -527,9 +529,43 @@ def points(self, B=0): raise TypeError("unable to enumerate points over %s"%R) -#******************************************************************* -# Abelian varieties -#******************************************************************* +class SchemeHomset_polynomial_projective_space(SchemeHomset_generic): + """ + Set of morphisms of a projective space. + + EXAMPLES:: + + sage: P. = ProjectiveSpace(2, QQ) + sage: Hom(P, P) + Set of morphisms + From: Projective Space of dimension 2 over Rational Field + To: Projective Space of dimension 2 over Rational Field + """ + def identity(self): + """ + Return the identity morphism of this hom-set. + + EXAMPLES:: + + sage: P. = ProjectiveSpace(2, QQ) + sage: Hom(P, P) + Set of morphisms + From: Projective Space of dimension 2 over Rational Field + To: Projective Space of dimension 2 over Rational Field + sage: _.identity() + Scheme endomorphism of Projective Space of dimension 2 over Rational Field + Defn: Identity map + """ + if self.is_endomorphism_set(): + from sage.schemes.generic.morphism import SchemeMorphism_polynomial_id + return SchemeMorphism_polynomial_id(self.domain()) + raise TypeError("identity map is only defined for endomorphisms") + + +# ******************************************************************* +# Abelian varieties +# ******************************************************************* + class SchemeHomset_points_abelian_variety_field(SchemeHomset_points_projective_field): r""" Set of rational points of an Abelian variety. diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 42402cfbc74..e07c06614a5 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -83,6 +83,7 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ from sage.modules.free_module_element import vector +from sage.matrix.constructor import matrix from sage.schemes.generic.morphism import SchemeMorphism_polynomial from sage.categories.finite_fields import FiniteFields from sage.categories.number_fields import NumberFields @@ -2281,6 +2282,24 @@ def __call__(self, x): pass raise ValueError('the morphism is not defined at this point') + def __eq__(self, other): + """ + EXAMPLES:: + + sage: R. = QQ[] + sage: C = Curve(7*x^2 + 2*y*z + z^2) + sage: f, g = C.parametrization() + sage: f*g == C.identity_morphism() + True + """ + if not isinstance(other, SchemeMorphism_polynomial): + return False + if self.domain() != other.domain() or self.codomain() != other.codomain(): + return False + R = self.codomain().coordinate_ring() + mat = matrix([self.defining_polynomials(), other.defining_polynomials()]) + return all(R(minor).is_zero() for minor in mat.minors(2)) + @cached_method def representatives(self): """ diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index ed44ebcd6aa..b87405cc509 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -112,7 +112,8 @@ from sage.modules.free_module_element import prepare from sage.schemes.generic.ambient_space import AmbientSpace from sage.schemes.projective.projective_homset import (SchemeHomset_points_projective_ring, - SchemeHomset_points_projective_field) + SchemeHomset_points_projective_field, + SchemeHomset_polynomial_projective_space) from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring, SchemeMorphism_point_projective_field, SchemeMorphism_point_projective_finite_field) @@ -459,7 +460,7 @@ def _validate(self, polynomials): sage: P._validate([x*y - z^2, x]) [x*y - z^2, x] - :: + :: sage: P. = ProjectiveSpace(2, ZZ) sage: P._validate((x*y - z, x)) @@ -467,7 +468,7 @@ def _validate(self, polynomials): ... TypeError: x*y - z is not a homogeneous polynomial - :: + :: sage: P. = ProjectiveSpace(2, ZZ) sage: P._validate(x*y - z) @@ -741,6 +742,20 @@ def _morphism(self, *args, **kwds): """ return SchemeMorphism_polynomial_projective_space(*args, **kwds) + def _homset(self, *args, **kwds): + """ ii + Construct the Hom-set + + EXAMPLES:: + + sage: P. = ProjectiveSpace(2, QQ) + sage: Hom(P, P) + Set of morphisms + From: Projective Space of dimension 2 over Rational Field + To: Projective Space of dimension 2 over Rational Field + """ + return SchemeHomset_polynomial_projective_space(*args, **kwds) + def _point_homset(self, *args, **kwds): """ Construct a point Hom-set. @@ -1804,6 +1819,7 @@ def is_linearly_independent(self, points, n=None): break return linearly_independent + class ProjectiveSpace_field(ProjectiveSpace_ring): def _point_homset(self, *args, **kwds): """ @@ -2100,6 +2116,7 @@ def line_through(self, p, q): m = matrix(3, list(self.gens()) + list(p) + list(q)) return Curve([f for f in m.minors(3) if f]) + class ProjectiveSpace_finite_field(ProjectiveSpace_field): def _point(self, *args, **kwds): """ diff --git a/src/sage/schemes/toric/homset.py b/src/sage/schemes/toric/homset.py index b5c97e10f83..a057ecdf1ab 100644 --- a/src/sage/schemes/toric/homset.py +++ b/src/sage/schemes/toric/homset.py @@ -84,7 +84,7 @@ From: Projective Space of dimension 2 over Rational Field To: 2-d CPR-Fano toric variety covered by 3 affine patches sage: type(native_to_toric) - + sage: native_to_toric([u^2, v^2, w^2]) Scheme morphism: From: Projective Space of dimension 2 over Rational Field From d9982f331afc48287f70eb4adf3895a9f49c98c7 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 2 Sep 2022 01:39:28 +0900 Subject: [PATCH 067/350] Extend to morphisms to affine spaces --- .../schemes/projective/projective_morphism.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index e07c06614a5..7210fca5191 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2287,16 +2287,30 @@ def __eq__(self, other): EXAMPLES:: sage: R. = QQ[] - sage: C = Curve(7*x^2 + 2*y*z + z^2) + sage: C = Curve(7*x^2 + 2*y*z + z^2) # conic sage: f, g = C.parametrization() sage: f*g == C.identity_morphism() True + + sage: C = Curve(x^2 + y^2 - z^2) + sage: A. = AffineSpace(QQ,2) + sage: i = C.hom([(x + z)/y, 1], A) + sage: j = C.hom([y/(z - x), 1], A) + sage: i == j + True """ + Y = self.codomain() + if not isinstance(other, SchemeMorphism_polynomial): return False - if self.domain() != other.domain() or self.codomain() != other.codomain(): + if self.domain() != other.domain() or Y != other.codomain(): return False - R = self.codomain().coordinate_ring() + + if not Y.is_projective(): # codomain is affine + e = Y.projective_embedding(0) + return (e * self) == (e * other) + + R = self.domain().coordinate_ring() mat = matrix([self.defining_polynomials(), other.defining_polynomials()]) return all(R(minor).is_zero() for minor in mat.minors(2)) From e66bb26d47f38e523e652b1ebfaecec4b3251ea9 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 2 Sep 2022 01:55:15 +0900 Subject: [PATCH 068/350] Minor edits --- src/sage/schemes/projective/projective_morphism.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 7210fca5191..7b0f8db98ae 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2293,10 +2293,10 @@ def __eq__(self, other): True sage: C = Curve(x^2 + y^2 - z^2) - sage: A. = AffineSpace(QQ,2) - sage: i = C.hom([(x + z)/y, 1], A) - sage: j = C.hom([y/(z - x), 1], A) - sage: i == j + sage: A. = AffineSpace(QQ, 1) + sage: f = C.hom([(x + z)/y], A) + sage: g = C.hom([y/(z - x)], A) + sage: f == g True """ Y = self.codomain() From 293b4392f318a6a6a487dc87fa8c8d64864fbf23 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 2 Sep 2022 23:15:30 +0200 Subject: [PATCH 069/350] adapt doctests --- src/sage/combinat/species/species.py | 6 +++--- src/sage/combinat/species/structure.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index ee3236f4024..4cd3403ae61 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -776,10 +776,10 @@ def algebraic_equation_system(self): :: sage: sorted(B.digraph().vertex_iterator(), key=str) - [Combinatorial species, - Product of (Combinatorial species) and (Combinatorial species), + [Combinatorial species with min=1, + Product of (Combinatorial species with min=1) and (Combinatorial species with min=1), Singleton species, - Sum of (Singleton species) and (Product of (Combinatorial species) and (Combinatorial species))] + Sum of (Singleton species) and (Product of (Combinatorial species with min=1) and (Combinatorial species with min=1))] :: diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index bdd6f710600..b37f0837ded 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -390,7 +390,7 @@ def __iter__(self): try: if self.cardinality() == 0: return iter([]) - except RuntimeError: + except TypeError: raise NotImplementedError return getattr(self._species, self._iterator)(self._structure_class, self._labels) From d6bf255389c1c464f77014f671ca792d4dc896c9 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Sat, 3 Sep 2022 21:22:57 +0100 Subject: [PATCH 070/350] Switch from recursive to iterative DFS --- src/sage/graphs/edge_connectivity.pyx | 68 ++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 19d92bcf9b2..86bf1bbfea7 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -175,6 +175,7 @@ cdef class GabowEdgeConnectivity: cdef int* T # whether the an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree cdef bint dfs # whether or not we should use dfs-based fast initialization + cdef int* s1 def __init__(self, G, dfs=True): r""" @@ -238,6 +239,7 @@ cdef class GabowEdgeConnectivity: self.depth_1 = self.mem.calloc(self.max_ec, sizeof(int*)) self.depth_2 = self.mem.calloc(self.max_ec, sizeof(int*)) self.stack = self.mem.calloc(self.n, sizeof(int)) + self.s1 = self.mem.calloc(self.n, sizeof(int)) self.tree_edges.resize(self.max_ec) self.tree_edges_incident.resize(self.n) self.T = self.mem.calloc(self.m, sizeof(int)) @@ -441,13 +443,75 @@ cdef class GabowEdgeConnectivity: # Initialize T_k to be a DFS spanning forest of G \ T if self.dfs: - self.compute_dfs_tree() + self.iterative_compute_dfs_tree() # Set inactive the f-trees of the root vertex self.forests[self.root_vertex] = False self.L_roots[tree] = self.UNUSED self.tree_flag[tree] = False + + cdef void iterative_compute_dfs_tree(self): + """ + Find a DFS spanning forest of G \ T + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + # Mark all vertices as unvisited + for i in range(self.n): + self.visited[i] = False + + for r in range(self.n): + if not self.visited[r]: + # Make this vertex the root of the following dfs tree + self.root[r] = r + # Make the f_tree rooted at this vertex active + self.forests[r] = True + # Find connected vertices of the f-tree rooted at r + self.iterative_find_dfs_tree(r) + # Each call of find_dfs_tree creates an f-tree + self.num_start_f_trees += 1 + + cdef void iterative_find_dfs_tree(self, r): + """ + Find more vertices of the f-tree rooted at r + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int t = 1 + self.s1[0] = r + self.visited[r] = True + + while t > 0: + t -= 1 + u = self.s1[t] + # Visit outgoing arcs of current vertex + for e_id in self.my_g_reversed[u]: + v = self.my_to[e_id] + if v == u: + v = self.my_from[e_id] + # Ensure a vertex is not visited, is not a proven k-intersection edge + # and root_vertex remains deficient + if not self.visited[v] and not self.T[e_id] and v != self.root_vertex: + # Make current vertex belong to the f_tree rooted at r + self.root[v] = r + self.forests[v] = False + self.my_edge_state[e_id] = self.current_tree + self.num_joins += 1 + self.visited[v] = True + # iteratively find more vertices and grow the subtree rooted at r + self.s1[t] = v + t += 1 cdef void compute_dfs_tree(self): """ @@ -473,7 +537,7 @@ cdef class GabowEdgeConnectivity: # Find connected vertices of the f-tree rooted at r self.find_dfs_tree(r, r) # Each call of find_dfs_tree creates an f-tree - self.num_start_f_trees += 1 + #self.num_start_f_trees += 1 cdef void find_dfs_tree(self, u, r): """ From 7c5a81464e8d6efee219b78fda2888ee90f1f6d2 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 4 Sep 2022 13:30:53 +0200 Subject: [PATCH 071/350] trac #34123: review edit and bug fix --- src/sage/graphs/edge_connectivity.pyx | 132 ++++++++++++-------------- 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 22a2995b948..c7d10e9631c 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -120,7 +120,7 @@ cdef class GabowEdgeConnectivity: cdef vector[vector[int]] g_out cdef vector[vector[int]] g_in cdef vector[vector[int]] my_g # either g_out or g_in - cdef vector[vector[int]] my_g_reversed # either g_out or g_in + cdef vector[vector[int]] my_g_reversed # either g_out or g_in # values associated to edges cdef int* tail # source of edge j @@ -170,14 +170,15 @@ cdef class GabowEdgeConnectivity: cdef queue[pair[int, int]] joining_edges # queue of tuples (edge id, edge state) cdef queue[int] incident_edges_Q # queue of edges - cdef int num_start_f_trees # number of f-trees at the beginning of an iteration - cdef int num_joins # number of joined vertices from dfs - cdef int* T # whether the an edge is in the proven k-intersection + cdef int num_start_f_trees # number of f-trees at the beginning of an iteration + cdef int num_joins # number of joined vertices from dfs + cdef bint* T # whether the an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree - cdef bint dfs # whether or not we should use dfs-based fast initialization - cdef int* s1 + cdef bint dfs # whether or not we should use dfs-based fast initialization + cdef int * incident_edge_index # used for DFS initialization + cdef bint use_rec # variable to remove, used for development - def __init__(self, G, dfs=True): + def __init__(self, G, dfs=True, use_rec=False): r""" Initialize this object. @@ -193,6 +194,7 @@ cdef class GabowEdgeConnectivity: 4 """ self.dfs = dfs + self.use_rec = use_rec self.ec_checked = False from sage.graphs.digraph import DiGraph if not isinstance(G, DiGraph): @@ -239,10 +241,10 @@ cdef class GabowEdgeConnectivity: self.depth_1 = self.mem.calloc(self.max_ec, sizeof(int*)) self.depth_2 = self.mem.calloc(self.max_ec, sizeof(int*)) self.stack = self.mem.calloc(self.n, sizeof(int)) - self.s1 = self.mem.calloc(self.n, sizeof(int)) + self.incident_edge_index = self.mem.calloc(self.n, sizeof(int)) self.tree_edges.resize(self.max_ec) self.tree_edges_incident.resize(self.n) - self.T = self.mem.calloc(self.m, sizeof(int)) + self.T = self.mem.calloc(self.m, sizeof(bint)) self.visited = self.mem.calloc(self.n, sizeof(bint)) # Set some constants @@ -254,7 +256,7 @@ cdef class GabowEdgeConnectivity: self.edge_state_1[i] = self.UNUSED # edge i is unused self.edge_state_2[i] = self.UNUSED self.labels[i] = self.UNUSED # edge i is unlabeled - self.T[i] = False # edge i doesn't belong to any k-intersection yet + self.T[i] = False # edge i doesn't belong to any k-intersection yet _ = self.compute_edge_connectivity() sig_check() @@ -374,11 +376,11 @@ cdef class GabowEdgeConnectivity: cdef int z self.num_start_f_trees = self.n - self.num_joins - # There are fewer than n f-trees, and prepare to join thme - # If there's only one f-tree, we just save the edges and advance to the next iteration - if self.dfs: - if self.num_start_f_trees < self.n - 1: - self.re_init(tree) + # There are fewer than n f-trees. We prepare to join them. If there's + # only one f-tree, we just save the edges and advance to the next + # iteration + if self.dfs and self.num_start_f_trees < self.n - 1: + self.re_init(tree) # There are n f-trees, and we try to join them while njoins < self.num_start_f_trees-1: @@ -443,7 +445,7 @@ cdef class GabowEdgeConnectivity: # Initialize T_k to be a DFS spanning forest of G \ T if self.dfs: - self.iterative_compute_dfs_tree() + self.compute_dfs_tree() # Set inactive the f-trees of the root vertex self.forests[self.root_vertex] = False @@ -451,7 +453,7 @@ cdef class GabowEdgeConnectivity: self.L_roots[tree] = self.UNUSED self.tree_flag[tree] = False - cdef void iterative_compute_dfs_tree(self): + cdef void compute_dfs_tree(self): """ Find a DFS spanning forest of G \ T @@ -470,14 +472,17 @@ cdef class GabowEdgeConnectivity: if not self.visited[r]: # Make this vertex the root of the following dfs tree self.root[r] = r - # Make the f_tree rooted at this vertex active + # Make the f-tree rooted at this vertex active self.forests[r] = True # Find connected vertices of the f-tree rooted at r - self.iterative_find_dfs_tree(r) + if self.use_rec: + self.find_dfs_tree_rec(r, r) + else: + self.find_dfs_tree(r) # Each call of find_dfs_tree creates an f-tree self.num_start_f_trees += 1 - cdef void iterative_find_dfs_tree(self, r): + cdef void find_dfs_tree(self, r): """ Find more vertices of the f-tree rooted at r @@ -488,58 +493,40 @@ cdef class GabowEdgeConnectivity: sage: GabowEdgeConnectivity(D).edge_connectivity() 4 """ - cdef int t = 1 - self.s1[0] = r + cdef int u, v, e_id, e + cdef int * stack = self.stack + cdef int * edge_index = self.incident_edge_index + # We initialize the stack and mark the root as visited + cdef int t = 0 # index pointing to the top of the stack + stack[0] = r + edge_index[r] = self.my_g_reversed[r].size() self.visited[r] = True - while t > 0: - t -= 1 - u = self.s1[t] - # Visit outgoing arcs of current vertex - for e_id in self.my_g_reversed[u]: - v = self.my_to[e_id] - if v == u: - v = self.my_from[e_id] - # Ensure a vertex is not visited, is not a proven k-intersection edge - # and root_vertex remains deficient - if not self.visited[v] and not self.T[e_id] and v != self.root_vertex: - # Make current vertex belong to the f_tree rooted at r - self.root[v] = r - self.forests[v] = False - self.my_edge_state[e_id] = self.current_tree - self.num_joins += 1 - self.visited[v] = True - # iteratively find more vertices and grow the subtree rooted at r - self.s1[t] = v - t += 1 - - cdef void compute_dfs_tree(self): - """ - Find a DFS spanning forest of G \ T - - EXAMPLES:: - - sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity - sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D).edge_connectivity() - 4 - """ - # Mark all vertices as unvisited - for i in range(self.n): - self.visited[i] = False - - for r in range(self.n): - if not self.visited[r]: - # Make this vertex the root of the following dfs tree - self.root[r] = r - # Make the f_tree rooted at this vertex active - self.forests[r] = True - # Find connected vertices of the f-tree rooted at r - self.find_dfs_tree(r, r) - # Each call of find_dfs_tree creates an f-tree - #self.num_start_f_trees += 1 - - cdef void find_dfs_tree(self, u, r): + while t >= 0: + u = stack[t] + if edge_index[u]: + # Visit the next incident edge of u + edge_index[u] -= 1 + e_id = self.my_g_reversed[u][edge_index[u]] + if not self.T[e_id]: + v = self.my_to[e_id] + if not self.visited[v] and v != self.root_vertex: + # Make v belong to the f-tree rooted at r + self.root[v] = r + self.forests[v] = False + self.my_edge_state[e_id] = self.current_tree + self.num_joins += 1 + self.visited[v] = True + # add v to the stack + t += 1 + stack[t] = v + edge_index[v] = self.my_g_reversed[v].size() + # and proceed with v + else: + # We are done with u. We pop. + t -= 1 + + cdef void find_dfs_tree_rec(self, u, r): """ Find more vertices of the f-tree rooted at r @@ -565,7 +552,7 @@ cdef class GabowEdgeConnectivity: self.my_edge_state[e_id] = self.current_tree self.num_joins += 1 # recursively find more vertices and grow the subtree rooted at r - self.find_dfs_tree(v, r) + self.find_dfs_tree_rec(v, r) cdef int choose_root(self): """ @@ -1007,8 +994,7 @@ cdef class GabowEdgeConnectivity: # Arrange the edges of each tree for j in range(tree + 1): if self.dfs: - for e in range(len(self.tree_edges[j])): - e_id = self.tree_edges[j][e] + for e_id in self.tree_edges[j]: self.T[e_id] = False self.tree_edges[j].clear() for j in range(self.m): From 95c09720b3bd2ffcaaa93e1398f1e50f2717e2c9 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 4 Sep 2022 16:32:36 +0200 Subject: [PATCH 072/350] trac #34123: small edits --- src/sage/graphs/edge_connectivity.pyx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index c7d10e9631c..7fecce22cbd 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -454,8 +454,8 @@ cdef class GabowEdgeConnectivity: self.tree_flag[tree] = False cdef void compute_dfs_tree(self): - """ - Find a DFS spanning forest of G \ T + r""" + Find a DFS spanning forest of `G \backslash T`. EXAMPLES:: @@ -482,18 +482,18 @@ cdef class GabowEdgeConnectivity: # Each call of find_dfs_tree creates an f-tree self.num_start_f_trees += 1 - cdef void find_dfs_tree(self, r): - """ - Find more vertices of the f-tree rooted at r + cdef void find_dfs_tree(self, int r): + r""" + Find more vertices of the f-tree rooted at `r`. EXAMPLES:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D).edge_connectivity() + sage: GabowEdgeConnectivity(D, dfs=True, use_rec=False).edge_connectivity() 4 """ - cdef int u, v, e_id, e + cdef int u, v, e_id cdef int * stack = self.stack cdef int * edge_index = self.incident_edge_index # We initialize the stack and mark the root as visited @@ -526,15 +526,15 @@ cdef class GabowEdgeConnectivity: # We are done with u. We pop. t -= 1 - cdef void find_dfs_tree_rec(self, u, r): - """ - Find more vertices of the f-tree rooted at r + cdef void find_dfs_tree_rec(self, int u, int r): + r""" + Find more vertices of the f-tree rooted at `r`. EXAMPLES:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D).edge_connectivity() + sage: GabowEdgeConnectivity(D, dfs=True, use_rec=True).edge_connectivity() 4 """ # Mark vertex u as visited to avoid visiting it multiple times From b76d8f40ac50839297cb25fe23da16c0c0a8c49c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 7 Sep 2022 22:36:50 +0200 Subject: [PATCH 073/350] allow to define lazy series using iterators, adapt doctest --- .../categories/highest_weight_crystals.py | 20 ++-- src/sage/categories/sets_with_grading.py | 16 ++- src/sage/combinat/tutorial.py | 11 +- src/sage/data_structures/stream.py | 40 +++++++ src/sage/rings/lazy_series_ring.py | 108 +++++++++++++----- .../combinat_doctest.py | 11 +- .../polynomes_doctest.py | 28 +++-- 7 files changed, 163 insertions(+), 71 deletions(-) diff --git a/src/sage/categories/highest_weight_crystals.py b/src/sage/categories/highest_weight_crystals.py index e063e388998..06c07a18f9b 100644 --- a/src/sage/categories/highest_weight_crystals.py +++ b/src/sage/categories/highest_weight_crystals.py @@ -322,14 +322,9 @@ def q_dimension(self, q=None, prec=None, use_product=False): 1 + q + 2*q^2 + 2*q^3 + 4*q^4 + 5*q^5 + 7*q^6 + 9*q^7 + 13*q^8 + 16*q^9 + O(q^10) sage: qdim = C.q_dimension(); qdim - 1 + q + 2*q^2 + 2*q^3 + 4*q^4 + 5*q^5 + 7*q^6 - + 9*q^7 + 13*q^8 + 16*q^9 + 22*q^10 + O(x^11) - sage: qdim.compute_coefficients(15) - sage: qdim - 1 + q + 2*q^2 + 2*q^3 + 4*q^4 + 5*q^5 + 7*q^6 - + 9*q^7 + 13*q^8 + 16*q^9 + 22*q^10 + 27*q^11 - + 36*q^12 + 44*q^13 + 57*q^14 + 70*q^15 + O(x^16) - + 1 + q + 2*q^2 + 2*q^3 + 4*q^4 + 5*q^5 + 7*q^6 + O(q^7) + sage: qdim[:16] + [1, 1, 2, 2, 4, 5, 7, 9, 13, 16, 22, 27, 36, 44, 57, 70] """ from sage.rings.integer_ring import ZZ WLR = self.weight_lattice_realization() @@ -375,22 +370,21 @@ def iter_by_deg(gens): elif prec is None: # If we're here, we may not be a finite crystal. # In fact, we're probably infinite. - from sage.combinat.species.series import LazyPowerSeriesRing + from sage.rings.lazy_series_ring import LazyTaylorSeriesRing if q is None: - P = LazyPowerSeriesRing(ZZ, names='q') + P = LazyTaylorSeriesRing(ZZ, names='q') else: P = q.parent() - if not isinstance(P, LazyPowerSeriesRing): + if not isinstance(P, LazyTaylorSeriesRing): raise TypeError("the parent of q must be a lazy power series ring") ret = P(iter_by_deg(mg)) - ret.compute_coefficients(10) return ret from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic if q is None: q = PowerSeriesRing(ZZ, 'q', default_prec=prec).gen(0) P = q.parent() - ret = P.sum(c * q**deg for deg,c in enumerate(iter_by_deg(mg))) + ret = P.sum(c * q**deg for deg, c in enumerate(iter_by_deg(mg))) if ret.degree() == max_deg and isinstance(P, PowerSeriesRing_generic): ret = P(ret, prec) return ret diff --git a/src/sage/categories/sets_with_grading.py b/src/sage/categories/sets_with_grading.py index 8ef7b8b0256..c2e5aa8451e 100644 --- a/src/sage/categories/sets_with_grading.py +++ b/src/sage/categories/sets_with_grading.py @@ -212,11 +212,21 @@ def generating_series(self): Non negative integers sage: N.generating_series() 1/(-z + 1) + + sage: Permutations().generating_series() + 1 + z + 2*z^2 + 6*z^3 + 24*z^4 + 120*z^5 + 720*z^6 + O(z^7) + + .. TODO:: + + - Very likely, this should always return a lazy power series. """ - from sage.combinat.species.series import LazyPowerSeriesRing + from sage.sets.non_negative_integers import NonNegativeIntegers + from sage.rings.lazy_series_ring import LazyTaylorSeriesRing from sage.rings.integer_ring import ZZ - R = LazyPowerSeriesRing(ZZ) - R(self.graded_component(grade).cardinality() for grade in self.grading_set()) + if isinstance(self.grading_set(), NonNegativeIntegers): + R = LazyTaylorSeriesRing(ZZ, names="z") + return R(lambda n: self.graded_component(n).cardinality()) + raise NotImplementedError # TODO: # * asymptotic behavior: we need an object for asymptotic behavior and diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index e9df13c746c..73558c15a91 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -315,13 +315,12 @@ in particular, without needing a closed form for the answer. We begin by defining the ring of lazy power series:: - sage: L. = LazyPowerSeriesRing(QQ) + sage: L. = LazyTaylorSeriesRing(QQ) Then we create a “free” power series, which we name, and which we then define by a recursive equation:: - sage: C = L() - sage: C._name = 'C' + sage: C = L.undefined(valuation=1) sage: C.define( z + C * C ) :: @@ -1672,7 +1671,7 @@ We begin by redefining the complete binary trees; to do so, we stipulate the recurrence relation directly on the sets:: - sage: BT = CombinatorialSpecies() + sage: BT = CombinatorialSpecies(min=1) sage: Leaf = SingletonSpecies() sage: BT.define( Leaf + (BT*BT) ) @@ -1697,7 +1696,7 @@ We recover the generating function for the Catalan numbers:: sage: g = BT.isotype_generating_series(); g - x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + O(x^6) + z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) which is returned in the form of a lazy power series:: @@ -1715,7 +1714,7 @@ The Fibonacci sequence is easily recognized here, hence the name:: - sage: L = FW.isotype_generating_series().coefficients(15); L + sage: L = FW.isotype_generating_series()[:15]; L [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987] :: diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index fc5a99a7a60..a8118dd4746 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -749,6 +749,45 @@ def _polynomial_part(self, R): return R(self._initial_coefficients).shift(v) +class Stream_iterator(Stream_inexact): + r""" + Class that creates a stream from an iterator. + + INPUT: + + - ``iter`` -- a function that generates the coefficients of the + stream + - ``approximate_order`` -- integer; a lower bound for the order + of the stream + + Instances of this class are always dense. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_iterator + sage: f = Stream_iterator(iter(NonNegativeIntegers()), 0) + sage: [f[i] for i in range(10)] + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + + sage: f = Stream_iterator(iter(NonNegativeIntegers()), 1) + sage: [f[i] for i in range(10)] + [0, 0, 1, 2, 3, 4, 5, 6, 7, 8] + + """ + def __init__(self, iter, approximate_order): + """ + Initialize. + + TESTS:: + + sage: from sage.data_structures.stream import Stream_iterator + sage: f = Stream_iterator(iter(NonNegativeIntegers()), 0) + sage: TestSuite(f).run(skip="_test_pickling") + """ + self.iterate_coefficients = lambda: iter + super().__init__(False, approximate_order) + + class Stream_function(Stream_inexact): r""" Class that creates a stream from a function on the integers. @@ -2450,6 +2489,7 @@ def is_nonzero(self): """ return self._series.is_nonzero() + class Stream_derivative(Stream_inexact): """ Operator for taking derivatives of a stream. diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 1bfdffef6d8..4de2f13c51b 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -61,10 +61,12 @@ from sage.data_structures.stream import ( Stream_zero, Stream_function, + Stream_iterator, Stream_exact, Stream_uninitialized ) +from types import GeneratorType class LazySeriesRing(UniqueRepresentation, Parent): """ @@ -329,6 +331,11 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: f == g True + We support passing a generator:: + + sage: L(filter(is_odd, NN), -3) + z^-3 + 3*z^-2 + 5*z^-1 + 7 + 9*z + 11*z^2 + 13*z^3 + O(z^4) + .. TODO:: Add a method to change the sparse/dense implementation. @@ -342,6 +349,8 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No raise ValueError("the valuation must be specified") return self.element_class(self, Stream_uninitialized(self._sparse, valuation)) + # WARNING: if x is not explicitly specified as None, it is + # set to 0 by Parent.__call__ if coefficients is not None and (x is not None and (not isinstance(x, int) or x)): raise ValueError("coefficients must be None if x is provided") @@ -376,7 +385,7 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No return self.element_class(self, coeff_stream) initial_coefficients = [x[i] for i in range(x.valuation(), x.degree() + 1)] coeff_stream = Stream_exact(initial_coefficients, self._sparse, - order=x.valuation(), constant=constant, degree=degree) + order=x.valuation(), degree=degree, constant=constant) return self.element_class(self, coeff_stream) # Handle when it is a lazy series @@ -413,7 +422,7 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No x._coeff_stream._approximate_order += len(initial_coefficients) initial_coefficients = [] coeff_stream = Stream_exact(initial_coefficients, self._sparse, - order=valuation, constant=constant, degree=degree) + order=valuation, degree=degree, constant=constant) return self.element_class(self, coeff_stream) # We are just possibly shifting the result @@ -425,19 +434,25 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No else: x = coefficients - if callable(x): + if callable(x) or isinstance(x, (GeneratorType, map, filter)): if valuation is None: raise ValueError("the valuation must be specified") if degree is None: if constant is not None: raise ValueError("constant may only be specified if the degree is specified") - coeff_stream = Stream_function(lambda i: BR(x(i)), self._sparse, valuation) + if callable(x): + coeff_stream = Stream_function(lambda i: BR(x(i)), self._sparse, valuation) + else: + coeff_stream = Stream_iterator(map(BR, _skip_leading_zeros(x)), valuation) return self.element_class(self, coeff_stream) # degree is not None if constant is None: constant = BR.zero() - p = [BR(x(i)) for i in range(valuation, degree)] + if callable(x): + p = [BR(x(i)) for i in range(valuation, degree)] + else: + p = [BR(c) for c, _ in zip(_skip_leading_zeros(x), range(valuation, degree))] if not any(p) and not constant: return self.zero() coeff_stream = Stream_exact(p, self._sparse, order=valuation, @@ -466,7 +481,8 @@ def undefined(self, valuation=None): sage: s z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8) """ - return self(None, valuation=valuation) + coeff_stream = Stream_uninitialized(self._sparse, valuation) + return self.element_class(self, coeff_stream) unknown = undefined @@ -870,6 +886,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyLaurentSeriesRing(E, 't') # not tested """ self._sparse = sparse + self._arity = 1 # We always use the dense because our CS_exact is implemented densely self._laurent_poly_ring = LaurentPolynomialRing(base_ring, names) self._internal_poly_ring = self._laurent_poly_ring @@ -1156,8 +1173,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): if self._arity == 1: self._internal_poly_ring = self._laurent_poly_ring else: - coeff_ring = PolynomialRing(base_ring, names) - self._internal_poly_ring = PolynomialRing(coeff_ring, "DUMMY_VARIABLE") + self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE") category = Algebras(base_ring.category()) if base_ring in Fields(): category &= CompleteDiscreteValuationRings() @@ -1272,7 +1288,7 @@ def gens(self): """ return tuple([self.gen(n) for n in range(self.ngens())]) - def _element_constructor_(self, x=None, valuation=None, constant=None, degree=None, check=True): + def _element_constructor_(self, x=None, valuation=None, constant=None, degree=None, coefficients=None, check=True): """ Construct a Taylor series from ``x``. @@ -1379,10 +1395,11 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No """ if valuation is not None: if valuation < 0: - raise ValueError("the valuation of a Taylor series must be positive") - if len(self.variable_names()) > 1: + raise ValueError("the valuation of a Taylor series must be non-negative") + # TODO: the following is nonsense, think of an iterator + if self._arity > 1: raise ValueError("valuation must not be specified for multivariate Taylor series") - if len(self.variable_names()) > 1: + if self._arity > 1: valuation = 0 R = self._laurent_poly_ring @@ -1399,7 +1416,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No if isinstance(constant, (tuple, list)): constant, degree = constant if constant is not None: - if len(self.variable_names()) > 1 and constant: + if self._arity > 1 and constant: raise ValueError("constant must be zero for multivariate Taylor series") constant = BR(constant) if x in R: @@ -1413,7 +1430,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No constant=constant) return self.element_class(self, coeff_stream) - if len(self.variable_names()) == 1: + if self._arity == 1: v = x.valuation() d = x.degree() p_list = [x[i] for i in range(v, d + 1)] @@ -1436,16 +1453,20 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No return self.element_class(self, x._coeff_stream) # TODO: Implement a way to make a self._sparse copy raise NotImplementedError("cannot convert between sparse and dense") - if callable(x): + if callable(x) or isinstance(x, (GeneratorType, map, filter)): if valuation is None: valuation = 0 if degree is not None: if constant is None: constant = ZZ.zero() - if len(self.variable_names()) == 1: - p = [BR(x(i)) for i in range(valuation, degree)] + if callable(x): + p = [x(i) for i in range(valuation, degree)] else: - p = [R(x(i)) for i in range(valuation, degree)] + p = [c for c, _ in zip(_skip_leading_zeros(x), range(valuation, degree))] + if self._arity == 1: + p = [BR(c) for c in p] + else: + p = [R(c) for c in p] if not all(e.is_homogeneous() and e.degree() == i for i, e in enumerate(p, valuation)): raise ValueError("coefficients must be homogeneous polynomials of the correct degree") @@ -1454,15 +1475,21 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No constant=constant, degree=degree) return self.element_class(self, coeff_stream) - if check and len(self.variable_names()) > 1: - def y(n): - e = R(x(n)) - if not e or e.is_homogeneous() and e.degree() == n: - return e - raise ValueError("coefficient %s at degree %s is not a homogeneous polynomial" % (e, n)) - coeff_stream = Stream_function(y, self._sparse, valuation) + if check and self._arity > 1: + if callable(x): + def y(n): + e = R(x(n)) + if not e or e.is_homogeneous() and e.degree() == n: + return e + raise ValueError("coefficient %s at degree %s is not a homogeneous polynomial" % (e, n)) + coeff_stream = Stream_function(y, self._sparse, valuation) + else: + coeff_stream = Stream_iterator(map(R, _skip_leading_zeros(x)), valuation) else: - coeff_stream = Stream_function(x, self._sparse, valuation) + if callable(x): + coeff_stream = Stream_function(x, self._sparse, valuation) + else: + coeff_stream = Stream_iterator(map(BR, _skip_leading_zeros(x)), valuation) return self.element_class(self, coeff_stream) raise ValueError(f"unable to convert {x} into a lazy Taylor series") @@ -1868,8 +1895,8 @@ def __init__(self, base_ring, names, sparse=True, category=None): raise ValueError("positive characteristic not allowed for Dirichlet series") self._sparse = sparse - # TODO: it would be good to have something better than the symbolic ring - self._laurent_poly_ring = SR + self._arity = 1 + self._laurent_poly_ring = SR # TODO: it would be good to have something better than the symbolic ring self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=True) category = Algebras(base_ring.category()) @@ -2067,3 +2094,28 @@ def _monomial(self, c, n): return L(c) * L(n) ** -L(self.variable_name()) except (ValueError, TypeError): return '({})/{}^{}'.format(self.base_ring()(c), n, self.variable_name()) + +def _skip_leading_zeros(iterator): + """ + Return an iterator which discards all leading zeros. + + EXAMPLES:: + + sage: from sage.rings.lazy_series_ring import _skip_leading_zeros + sage: it = map(lambda x: 0 if x < 10 else x, NN) + sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))] + [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] + + sage: it = map(GF(3), NN) + sage: [x for x, _ in zip(it, range(10))] + [0, 1, 2, 0, 1, 2, 0, 1, 2, 0] + sage: it = map(GF(3), NN) + sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))] + [1, 2, 0, 1, 2, 0, 1, 2, 0, 1] + """ + while True: + c = next(iterator) + if c: + yield c + break + yield from iterator diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py index 9dc4f6e430a..211843c00a2 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py @@ -117,12 +117,11 @@ Sage example in ./combinat.tex, line 654:: - sage: L. = LazyPowerSeriesRing(QQ) + sage: L. = LazyTaylorSeriesRing(QQ) Sage example in ./combinat.tex, line 661:: - sage: C = L() - sage: C._name = 'C' + sage: C = L.undefined(valuation=1) sage: C.define( z + C * C ) Sage example in ./combinat.tex, line 666:: @@ -889,7 +888,7 @@ Sage example in ./combinat.tex, line 2697:: - sage: BT = CombinatorialSpecies() + sage: BT = CombinatorialSpecies(min=1) sage: Leaf = SingletonSpecies() sage: BT.define( Leaf + (BT*BT) ) @@ -906,7 +905,7 @@ Sage example in ./combinat.tex, line 2727:: sage: g = BT.isotype_generating_series(); g - x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + O(x^6) + z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) Sage example in ./combinat.tex, line 2733:: @@ -922,7 +921,7 @@ Sage example in ./combinat.tex, line 2752:: - sage: L = FW.isotype_generating_series().coefficients(15); L + sage: L = FW.isotype_generating_series()[:15]; L [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987] Sage example in ./combinat.tex, line 2769:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py index 452a116401d..075d388d3b2 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py @@ -362,29 +362,28 @@ Sage example in ./polynomes.tex, line 2028:: - sage: L. = LazyPowerSeriesRing(QQ) - sage: lazy_exp = x.exponential(); lazy_exp - O(1) + sage: L. = LazyTaylorSeriesRing(QQ) + sage: lazy_exp = x.exp(); lazy_exp + 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) Sage example in ./polynomes.tex, line 2039:: sage: lazy_exp[5] 1/120 sage: lazy_exp - 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + O(x^6) + 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) Sage example in ./polynomes.tex, line 2062:: sage: f = L(1) # the constant lazy series 1 sage: for i in range(5): - ....: f = (x*f).exponential() - ....: f.compute_coefficients(5) # forces the computation + ....: f = (x*f).exp() ....: print(f) # of the first coefficients - 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + O(x^6) - 1 + x + 3/2*x^2 + 5/3*x^3 + 41/24*x^4 + 49/30*x^5 + O(x^6) - 1 + x + 3/2*x^2 + 8/3*x^3 + 101/24*x^4 + 63/10*x^5 + O(x^6) - 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 49/5*x^5 + O(x^6) - 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 54/5*x^5 + O(x^6) + 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) + 1 + x + 3/2*x^2 + 5/3*x^3 + 41/24*x^4 + 49/30*x^5 + 1057/720*x^6 + O(x^7) + 1 + x + 3/2*x^2 + 8/3*x^3 + 101/24*x^4 + 63/10*x^5 + 6607/720*x^6 + O(x^7) + 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 49/5*x^5 + 12847/720*x^6 + O(x^7) + 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 54/5*x^5 + 16087/720*x^6 + O(x^7) Sage example in ./polynomes.tex, line 2091:: @@ -393,10 +392,9 @@ Sage example in ./polynomes.tex, line 2105:: - sage: from sage.combinat.species.series import LazyPowerSeries - sage: f = LazyPowerSeries(L, name='f') - sage: f.define((x*f).exponential()) - sage: f.coefficients(8) + sage: f = L.undefined(valuation=0) + sage: f.define((x*f).exp()) + sage: f[:8] [1, 1, 3/2, 8/3, 125/24, 54/5, 16807/720, 16384/315] Sage example in ./polynomes.tex, line 2158:: From 4eb4dbd483cbac03078e0d709a8487c4f18ad219 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 8 Sep 2022 22:09:47 +0200 Subject: [PATCH 074/350] fix behaviour of __getitem__ for slices, provide missing doctests, minor simplifications in species directory --- src/sage/combinat/species/cycle_species.py | 16 +-- .../combinat/species/generating_series.py | 98 ++++--------------- .../combinat/species/linear_order_species.py | 4 +- .../combinat/species/permutation_species.py | 11 +-- src/sage/rings/lazy_series.py | 25 ++++- src/sage/rings/lazy_series_ring.py | 8 +- 6 files changed, 64 insertions(+), 98 deletions(-) diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index ced61ed4471..0e82416b54f 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -195,11 +195,9 @@ def _gs_callable(self, base_ring, n): sage: g[0:3] [0.000000000000000, 1.00000000000000, 0.500000000000000] """ - one = base_ring(1) - if n == 0: - return base_ring(0) - else: - return self._weight*one/n + if n: + return self._weight * base_ring.one() / n + return base_ring.zero() def _order(self): """ @@ -232,7 +230,9 @@ def _itgs_list(self, base_ring, n): sage: g[0:3] [0.000000000000000, 1.00000000000000, 1.00000000000000] """ - return base_ring(0) if n == 0 else self._weight*base_ring(1) + if n: + return self._weight * base_ring.one() + return base_ring.zero() def _cis_callable(self, base_ring, n): r""" @@ -268,9 +268,9 @@ def _cis_callable(self, base_ring, n): from sage.combinat.sf.sf import SymmetricFunctions p = SymmetricFunctions(base_ring).power() - zero = base_ring(0) + zero = base_ring.zero() - if n == 0: + if not n: return zero res = zero for k in divisors(n): diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index c6191b97960..e4a9fb037f7 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -142,6 +142,12 @@ class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): """ def __init__(self, base_ring): + """ + TESTS:: + + self: R = OrdinaryGeneratingSeriesRing(QQ); R + Lazy Taylor Series Ring in z over Rational Field + """ super().__init__(base_ring, names="z") Element = OrdinaryGeneratingSeries @@ -252,15 +258,19 @@ class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): TESTS: - We test to make sure that caching works. - - :: + We test to make sure that caching works:: sage: R is ExponentialGeneratingSeriesRing(QQ) True """ def __init__(self, base_ring): + """ + TESTS:: + + self: R = ExponentialGeneratingSeriesRing(QQ); R + Lazy Taylor Series Ring in z over Rational Field + """ super().__init__(base_ring, names="z") Element = ExponentialGeneratingSeries @@ -369,78 +379,7 @@ def _egs_gen(self, n, ao): return 0 return self.coefficient(n).coefficient([1]*n) - r""" - Return the multiplicative inverse of ``self``. - - This algorithm is derived from [BLL]_. - - EXAMPLES:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: E.__invert__()[:4] - [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] - - The defining characteristic of the multiplicative inverse `F^{-1}` of - a cycle index series `F` is that `F \cdot F^{-1} = F^{-1} \cdot F = 1` - (that is, both products with `F` yield the multiplicative identity `1`):: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E * ~E)[:6] - [p[], 0, 0, 0, 0, 0] - - REFERENCES: - - - [BLL]_ - - [BLL-Intro]_ - - http://bergeron.math.uqam.ca/Site/bergeron_anglais_files/livre_combinatoire.pdf - - AUTHORS: - - - Andrew Gainer-Dewar - - TESTS:: - - sage: E = species.SetSpecies().cycle_index_series() - sage: (E / E)[:6] - [p[], 0, 0, 0, 0, 0] - """ - - """ - Return a generator for the coefficients of the composition of this - cycle index series and the cycle index series ``y``. This overrides - the method defined in ``LazyTaylorSeries``. - - The notion "composition" means plethystic substitution here, as - defined in Section 2.2 of [BLL-Intro]_. - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: g = E_cis._compose_gen(C.cycle_index_series(),0) - sage: [next(g) for i in range(4)] - [p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]] - - Return the composition of one term in ``self`` with `y`. - - INPUT: - - - ``p`` - a term in ``self`` - - ``y_powers`` - a stream for the powers of `y` - starting with `y` - - EXAMPLES:: - - sage: E = species.SetSpecies(); C = species.CycleSpecies() - sage: E_cis = E.cycle_index_series() - sage: C_cis = C.cycle_index_series() - sage: c_powers = Stream(C_cis._power_gen()) - sage: p2 = E_cis.coefficient(2); p2 - 1/2*p[1, 1] + 1/2*p[2] - sage: E_cis._compose_term(p2, c_powers)[:4] - [0, 0, 1/2*p[1, 1] + 1/2*p[2], 1/2*p[1, 1, 1] + 1/2*p[2, 1]] - """ - + def derivative(self, n=1): r""" Return the species-theoretic `n`-th derivative of ``self``, where `n` is ``order``. @@ -469,7 +408,9 @@ def _egs_gen(self, n, ao): sage: L[:8] == C.derivative()[:8] True """ + return self.derivative_with_respect_to_p1(n=n) + def pointing(self): r""" Return the species-theoretic pointing of ``self``. @@ -491,7 +432,10 @@ def _egs_gen(self, n, ao): True """ + X = self.parent()([1], valuation=1) + return X*self.derivative_with_respect_to_p1() + def exponential(self): r""" Return the species-theoretic exponential of ``self``. @@ -649,7 +593,7 @@ def ExponentialCycleIndexSeries(R = RationalField()): + 1/3*p[3, 1] + 1/4*p[4]] """ CIS = CycleIndexSeriesRing(R) - return CIS(lambda n: _exp_term(n)) + return CIS(_exp_term) @cached_function @@ -704,4 +648,4 @@ def LogarithmCycleIndexSeries(R = RationalField()): [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R) - return CIS(lambda n: _cl_term(n)) + return CIS(_cl_term) diff --git a/src/sage/combinat/species/linear_order_species.py b/src/sage/combinat/species/linear_order_species.py index 6ae435b4e22..bd4b4a36f7d 100644 --- a/src/sage/combinat/species/linear_order_species.py +++ b/src/sage/combinat/species/linear_order_species.py @@ -134,7 +134,7 @@ def _gs_list(self, base_ring, n): sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return base_ring(1) + return base_ring.one() def _itgs_list(self, base_ring, n): r""" @@ -148,7 +148,7 @@ def _itgs_list(self, base_ring, n): sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return base_ring(1) + return base_ring.one() def _cis_callable(self, base_ring, n): diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index 4485e19477a..f6471e0e66e 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -197,7 +197,7 @@ def _gs_list(self, base_ring, n): sage: g[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ - return base_ring(1) + return base_ring.one() def _itgs_callable(self, base_ring, n): @@ -254,15 +254,14 @@ def _cis_gen(self, base_ring, m, n): pn = p([m]) - if n == 0: + if not n: return p(1) if m == 1: if n % 2: - return base_ring(0) - else: - return pn**(n//2) + return base_ring.zero() + return pn**(n//2) elif n % m: - return base_ring(0) + return base_ring.zero() return pn**(n//m) #Backward compatibility diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index b17d5336784..5e3ef985c1f 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -294,11 +294,17 @@ def __getitem__(self, n): [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] """ - R = self.parent()._internal_poly_ring.base_ring() + L = self.parent() + R = L._internal_poly_ring.base_ring() if isinstance(n, slice): if n.stop is None: raise NotImplementedError("cannot list an infinite set") - start = n.start if n.start is not None else self._coeff_stream._approximate_order + if n.start is not None: + start = n.start + elif L._minimal_valuation is not None: + start = L._minimal_valuation + else: + start = self._coeff_stream._approximate_order step = n.step if n.step is not None else 1 return [R(self._coeff_stream[k]) for k in range(start, n.stop, step)] return R(self._coeff_stream[n]) @@ -2449,12 +2455,25 @@ def __invert__(self): sage: ~z z^-1 + We can also compute the multiplicative inverse of a symmetric + function:: + + sage: h = SymmetricFunctions(QQ).h() + sage: p = SymmetricFunctions(QQ).p() + sage: L = LazySymmetricFunctions(p) + sage: E = L(lambda n: h[n]) + sage: (~E)[:4] + [p[], -p[1], 1/2*p[1, 1] - 1/2*p[2], -1/6*p[1, 1, 1] + 1/2*p[2, 1] - 1/3*p[3]] + + sage: (E * ~E)[:6] + [p[], 0, 0, 0, 0, 0] + TESTS:: sage: L. = LazyLaurentSeriesRing(QQ) sage: g = L([2], valuation=-1, constant=1); g 2*x^-1 + 1 + x + x^2 + O(x^3) - sage: g*g^-1 + sage: g * g^-1 1 + O(x^7) """ diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 4de2f13c51b..dd5fdf6a447 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -10,7 +10,7 @@ :class:`LazyLaurentSeriesRing` | The ring of lazy Laurent series. :class:`LazyTaylorSeriesRing` | The ring of (possibly multivariate) lazy Taylor series. - :class:`LazyCompletionGradedAlgebra` | The completion of a graded alebra consisting of formal series. + :class:`LazyCompletionGradedAlgebra` | The completion of a graded algebra consisting of formal series. :class:`LazySymmetricFunctions` | The ring of (possibly multivariate) lazy symmetric functions. :class:`LazyDirichletSeriesRing` | The ring of lazy Dirichlet series. @@ -887,6 +887,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): """ self._sparse = sparse self._arity = 1 + self._minimal_valuation = None # We always use the dense because our CS_exact is implemented densely self._laurent_poly_ring = LaurentPolynomialRing(base_ring, names) self._internal_poly_ring = self._laurent_poly_ring @@ -1168,6 +1169,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): from sage.structure.category_object import normalize_names names = normalize_names(-1, names) self._sparse = sparse + self._minimal_valuation = 0 self._laurent_poly_ring = PolynomialRing(base_ring, names) self._arity = len(names) if self._arity == 1: @@ -1513,7 +1515,7 @@ def _an_element_(self): class LazyCompletionGradedAlgebra(LazySeriesRing): r""" - The completion of a graded alebra consisting of formal series. + The completion of a graded algebra consisting of formal series. For a graded algebra `A`, we can form a completion of `A` consisting of all formal series of `A` such that each homogeneous component is @@ -1566,6 +1568,7 @@ def __init__(self, basis, sparse=True, category=None): sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) """ base_ring = basis.base_ring() + self._minimal_valuation = 0 if basis in Algebras.TensorProducts: self._arity = len(basis._sets) else: @@ -1895,6 +1898,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): raise ValueError("positive characteristic not allowed for Dirichlet series") self._sparse = sparse + self._minimal_valuation = 1 self._arity = 1 self._laurent_poly_ring = SR # TODO: it would be good to have something better than the symbolic ring self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=True) From 6f76b00e9f2aa3e39118b8278349f48de0753c05 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 8 Sep 2022 22:21:23 +0200 Subject: [PATCH 075/350] replace LazyTaylorSeriesRing and LazyTaylorSeries with LazyPowerSeriesRing and LazyPowerSeries and add appropriate deprecations --- .../categories/highest_weight_crystals.py | 6 +- src/sage/categories/sets_with_grading.py | 4 +- .../combinat/species/generating_series.py | 25 ++-- src/sage/combinat/tutorial.py | 2 +- src/sage/rings/all.py | 2 +- src/sage/rings/lazy_series.py | 124 ++++++++++++------ src/sage/rings/lazy_series_ring.py | 50 +++---- .../combinat_doctest.py | 2 +- .../polynomes_doctest.py | 2 +- 9 files changed, 127 insertions(+), 90 deletions(-) diff --git a/src/sage/categories/highest_weight_crystals.py b/src/sage/categories/highest_weight_crystals.py index 06c07a18f9b..b8afdee2117 100644 --- a/src/sage/categories/highest_weight_crystals.py +++ b/src/sage/categories/highest_weight_crystals.py @@ -370,12 +370,12 @@ def iter_by_deg(gens): elif prec is None: # If we're here, we may not be a finite crystal. # In fact, we're probably infinite. - from sage.rings.lazy_series_ring import LazyTaylorSeriesRing + from sage.rings.lazy_series_ring import LazyPowerSeriesRing if q is None: - P = LazyTaylorSeriesRing(ZZ, names='q') + P = LazyPowerSeriesRing(ZZ, names='q') else: P = q.parent() - if not isinstance(P, LazyTaylorSeriesRing): + if not isinstance(P, LazyPowerSeriesRing): raise TypeError("the parent of q must be a lazy power series ring") ret = P(iter_by_deg(mg)) return ret diff --git a/src/sage/categories/sets_with_grading.py b/src/sage/categories/sets_with_grading.py index c2e5aa8451e..5d01bfab999 100644 --- a/src/sage/categories/sets_with_grading.py +++ b/src/sage/categories/sets_with_grading.py @@ -221,10 +221,10 @@ def generating_series(self): - Very likely, this should always return a lazy power series. """ from sage.sets.non_negative_integers import NonNegativeIntegers - from sage.rings.lazy_series_ring import LazyTaylorSeriesRing + from sage.rings.lazy_series_ring import LazyPowerSeriesRing from sage.rings.integer_ring import ZZ if isinstance(self.grading_set(), NonNegativeIntegers): - R = LazyTaylorSeriesRing(ZZ, names="z") + R = LazyPowerSeriesRing(ZZ, names="z") return R(lambda n: self.graded_component(n).cardinality()) raise NotImplementedError diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index e4a9fb037f7..8c0910f0043 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -49,8 +49,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.lazy_series import LazyTaylorSeries, LazySymmetricFunction -from sage.rings.lazy_series_ring import LazyTaylorSeriesRing, LazySymmetricFunctions +from sage.rings.lazy_series import LazyPowerSeries, LazySymmetricFunction +from sage.rings.lazy_series_ring import LazyPowerSeriesRing, LazySymmetricFunctions from sage.rings.integer import Integer from sage.rings.rational_field import RationalField from sage.arith.all import moebius, gcd, lcm, divisors @@ -61,11 +61,11 @@ from sage.arith.misc import factorial -class OrdinaryGeneratingSeries(LazyTaylorSeries): +class OrdinaryGeneratingSeries(LazyPowerSeries): r""" A class for ordinary generating series. - Note that it is just a :class:`LazyTaylorSeries` whose elements + Note that it is just a :class:`LazyPowerSeries` whose elements have some extra methods. EXAMPLES:: @@ -113,12 +113,12 @@ def counts(self, n): return [self.count(i) for i in range(n)] -class OrdinaryGeneratingSeriesRing(LazyTaylorSeriesRing): +class OrdinaryGeneratingSeriesRing(LazyPowerSeriesRing): r""" Return the ring of ordinary generating series over ``R``. Note that it is just a - :class:`LazyTaylorSeriesRing` whose elements have + :class:`LazyPowerSeriesRing` whose elements have some extra methods. EXAMPLES:: @@ -153,12 +153,12 @@ def __init__(self, base_ring): Element = OrdinaryGeneratingSeries -class ExponentialGeneratingSeries(LazyTaylorSeries): +class ExponentialGeneratingSeries(LazyPowerSeries): r""" A class for ordinary generating series. Note that it is just a - :class:`LazyTaylorSeries` whose elements have + :class:`LazyPowerSeries` whose elements have some extra methods. EXAMPLES:: @@ -238,12 +238,12 @@ def functorial_composition(self, y): P = self.parent() return P(lambda n: self.count(y.count(n)) / factorial(n), 0) -class ExponentialGeneratingSeriesRing(LazyTaylorSeriesRing): +class ExponentialGeneratingSeriesRing(LazyPowerSeriesRing): r""" Return the ring of exponential generating series over ``R``. Note that it is just a - :class:`LazyTaylorSeriesRing` whose elements have + :class:`LazyPowerSeriesRing` whose elements have some extra methods. EXAMPLES:: @@ -381,8 +381,7 @@ def _egs_gen(self, n, ao): def derivative(self, n=1): r""" - Return the species-theoretic `n`-th derivative of ``self``, - where `n` is ``order``. + Return the species-theoretic `n`-th derivative of ``self``. For a cycle index series `F (p_{1}, p_{2}, p_{3}, \ldots)`, its derivative is the cycle index series `F' = D_{p_{1}} F` (that is, @@ -518,7 +517,7 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): difficult to implement in Sage, as it would be an element of a power series ring in infinitely many variables. - Note that it is just a :class:`LazyTaylorSeriesRing` (whose base + Note that it is just a :class:`LazyPowerSeriesRing` (whose base ring is `\Lambda`) whose elements have some extra methods. EXAMPLES:: diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 73558c15a91..90ec8eea713 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -315,7 +315,7 @@ in particular, without needing a closed form for the answer. We begin by defining the ring of lazy power series:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) Then we create a “free” power series, which we name, and which we then define by a recursive equation:: diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 500ab0b615a..a6090039db2 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -146,7 +146,7 @@ lazy_import('sage.rings.laurent_series_ring_element', 'LaurentSeries', deprecation=33602) # Lazy Laurent series ring -lazy_import('sage.rings.lazy_series_ring', ['LazyLaurentSeriesRing', 'LazyTaylorSeriesRing', +lazy_import('sage.rings.lazy_series_ring', ['LazyLaurentSeriesRing', 'LazyPowerSeriesRing', 'LazySymmetricFunctions', 'LazyDirichletSeriesRing']) # Tate algebras diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 5e3ef985c1f..e7869d6e8b5 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -68,7 +68,7 @@ series are much faster. Moreover, these are the series where equality can be decided. For example:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: f = 1 + 2*z^2 / (1 - z) sage: f - 2 / (1 - z) + 1 + 2*z 0 @@ -77,7 +77,7 @@ streams of multivariate polynomials. Therefore, the only exact series in this case are polynomials:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: 1 / (1-x) 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + O(x,y)^7 @@ -139,7 +139,7 @@ sage: L. = LazyLaurentSeriesRing(QQ) sage: check(L, z) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: check(L, z) sage: p = SymmetricFunctions(QQ).p() sage: L = LazySymmetricFunctions(p) @@ -1066,7 +1066,7 @@ def change_ring(self, ring): A Taylor series example:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: s = 2 + z sage: t = s.change_ring(QQ) sage: t^-1 @@ -1479,7 +1479,7 @@ def exp(self): ... ValueError: can only compose with a positive valuation series - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: exp(x+y)[4].factor() (1/24) * (x + y)^4 sage: exp(x/(1-y)).polynomial(3) @@ -1506,7 +1506,7 @@ def log(self): sage: log(1/(1-z)) z + 1/2*z^2 + 1/3*z^3 + 1/4*z^4 + 1/5*z^5 + 1/6*z^6 + 1/7*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: log((1 + x/(1-y))).polynomial(3) 1/3*x^3 - x^2*y + x*y^2 - 1/2*x^2 + x*y + x @@ -1543,7 +1543,7 @@ def sin(self): ... ValueError: can only compose with a positive valuation series - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: sin(x/(1-y)).polynomial(3) -1/6*x^3 + x*y^2 + x*y + x @@ -1569,7 +1569,7 @@ def cos(self): sage: cos(z) 1 - 1/2*z^2 + 1/24*z^4 - 1/720*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: cos(x/(1-y)).polynomial(4) 1/24*x^4 - 3/2*x^2*y^2 - x^2*y - 1/2*x^2 + 1 @@ -1595,7 +1595,7 @@ def tan(self): sage: tan(z) z + 1/3*z^3 + 2/15*z^5 + 17/315*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: tan(x/(1-y)).polynomial(5) 2/15*x^5 + 2*x^3*y^2 + x*y^4 + x^3*y + x*y^3 + 1/3*x^3 + x*y^2 + x*y + x @@ -1661,7 +1661,7 @@ def sec(self): sage: sec(z) 1 + 1/2*z^2 + 5/24*z^4 + 61/720*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: sec(x/(1-y)).polynomial(4) 5/24*x^4 + 3/2*x^2*y^2 + x^2*y + 1/2*x^2 + 1 @@ -1685,7 +1685,7 @@ def arcsin(self): sage: arcsin(z) z + 1/6*z^3 + 3/40*z^5 + 5/112*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: asin(x/(1-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (3/40*x^5+x^3*y^2+x*y^4) + (3/8*x^5*y+5/3*x^3*y^3+x*y^5) @@ -1723,7 +1723,7 @@ def arccos(self): sage: arccos(z/(1-z)) 1/2*pi - z - z^2 - 7/6*z^3 - 3/2*z^4 - 83/40*z^5 - 73/24*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(SR) + sage: L. = LazyPowerSeriesRing(SR) sage: arccos(x/(1-y)) 1/2*pi + (-x) + (-x*y) + ((-1/6)*x^3-x*y^2) + ((-1/2)*x^3*y-x*y^3) + ((-3/40)*x^5-x^3*y^2-x*y^4) + ((-3/8)*x^5*y+(-5/3)*x^3*y^3-x*y^5) + O(x,y)^7 @@ -1747,7 +1747,7 @@ def arctan(self): sage: arctan(z) z - 1/3*z^3 + 1/5*z^5 - 1/7*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: atan(x/(1-y)) x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (1/5*x^5-2*x^3*y^2+x*y^4) + (x^5*y-10/3*x^3*y^3+x*y^5) + (-1/7*x^7+3*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8 @@ -1786,7 +1786,7 @@ def arccot(self): sage: arccot(z/(1-z)) 1/2*pi - z - z^2 - 2/3*z^3 + 4/5*z^5 + 4/3*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(SR) + sage: L. = LazyPowerSeriesRing(SR) sage: acot(x/(1-y)) 1/2*pi + (-x) + (-x*y) + (1/3*x^3-x*y^2) + (x^3*y-x*y^3) + ((-1/5)*x^5+2*x^3*y^2-x*y^4) + (-x^5*y+10/3*x^3*y^3-x*y^5) + O(x,y)^7 @@ -1812,7 +1812,7 @@ def sinh(self): sage: sinh(z) z + 1/6*z^3 + 1/120*z^5 + 1/5040*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: sinh(x/(1-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (1/120*x^5+x^3*y^2+x*y^4) + (1/24*x^5*y+5/3*x^3*y^3+x*y^5) @@ -1840,7 +1840,7 @@ def cosh(self): sage: cosh(z) 1 + 1/2*z^2 + 1/24*z^4 + 1/720*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: cosh(x/(1-y)) 1 + 1/2*x^2 + x^2*y + (1/24*x^4+3/2*x^2*y^2) + (1/6*x^4*y+2*x^2*y^3) + (1/720*x^6+5/12*x^4*y^2+5/2*x^2*y^4) + O(x,y)^7 @@ -1867,7 +1867,7 @@ def tanh(self): sage: tanh(z) z - 1/3*z^3 + 2/15*z^5 - 17/315*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: tanh(x/(1-y)) x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (2/15*x^5-2*x^3*y^2+x*y^4) + (2/3*x^5*y-10/3*x^3*y^3+x*y^5) + (-17/315*x^7+2*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8 @@ -1930,7 +1930,7 @@ def sech(self): sage: sech(z) 1 - 1/2*z^2 + 5/24*z^4 - 61/720*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: sech(x/(1-y)) 1 + (-1/2*x^2) + (-x^2*y) + (5/24*x^4-3/2*x^2*y^2) + (5/6*x^4*y-2*x^2*y^3) + (-61/720*x^6+25/12*x^4*y^2-5/2*x^2*y^4) + O(x,y)^7 @@ -2000,7 +2000,7 @@ def arcsinh(self): sage: arcsinh(z) z - 1/6*z^3 + 3/40*z^5 - 5/112*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: asinh(x/(1-y)) x + x*y + (-1/6*x^3+x*y^2) + (-1/2*x^3*y+x*y^3) + (3/40*x^5-x^3*y^2+x*y^4) + (3/8*x^5*y-5/3*x^3*y^3+x*y^5) + (-5/112*x^7+9/8*x^5*y^2-5/2*x^3*y^4+x*y^6) + O(x,y)^8 @@ -2038,7 +2038,7 @@ def arctanh(self): sage: arctanh(z) z + 1/3*z^3 + 1/5*z^5 + 1/7*z^7 + O(z^8) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: atanh(x/(1-y)) x + x*y + (1/3*x^3+x*y^2) + (x^3*y+x*y^3) + (1/5*x^5+2*x^3*y^2+x*y^4) + (x^5*y+10/3*x^3*y^3+x*y^5) + (1/7*x^7+3*x^5*y^2+5*x^3*y^4+x*y^6) + O(x,y)^8 @@ -2073,7 +2073,7 @@ def hypergeometric(self, a, b): sage: z.hypergeometric([], []) - exp(z) O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: (x+y).hypergeometric([1, 1], [1]).polynomial(4) x^4 + 4*x^3*y + 6*x^2*y^2 + 4*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 + x^2 + 2*x*y + y^2 + x + y + 1 @@ -2140,7 +2140,7 @@ def sqrt(self): sage: sqrt(1+z) 1 + 1/2*z - 1/8*z^2 + 1/16*z^3 - 5/128*z^4 + 7/256*z^5 - 21/1024*z^6 + O(z^7) - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: sqrt(1+x/(1-y)) 1 + 1/2*x + (-1/8*x^2+1/2*x*y) + (1/16*x^3-1/4*x^2*y+1/2*x*y^2) + (-5/128*x^4+3/16*x^3*y-3/8*x^2*y^2+1/2*x*y^3) @@ -2576,7 +2576,7 @@ def _div_(self, other): Examples for multivariate Taylor series:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: 1 / (1 - y) 1 + y + y^2 + y^3 + y^4 + y^5 + y^6 + O(x,y)^7 @@ -3575,13 +3575,13 @@ def _format_series(self, formatter, format_strings=False): return formatter(poly) + strformat(" + O({})".format(formatter(z**m))) -class LazyTaylorSeries(LazyCauchyProductSeries): +class LazyPowerSeries(LazyCauchyProductSeries): r""" A Taylor series where the coefficients are computed lazily. EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: f = 1 / (1 - x^2 + y^3); f 1 + x^2 + (-y^3) + x^4 + (-2*x^2*y^3) + (x^6+y^6) + O(x,y)^7 sage: P. = PowerSeriesRing(ZZ, default_prec=101) @@ -3596,6 +3596,44 @@ class LazyTaylorSeries(LazyCauchyProductSeries): sage: g == f True """ + def exponential(self): + r""" + Return the exponential series of ``self``. + + This method is deprecated, use :meth:`exp` instead. + + TESTS:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: lazy_exp = x.exponential(); lazy_exp + doctest:...: DeprecationWarning: the method exponential is deprecated. Use exp instead. + See https://trac.sagemath.org/32367 for details. + 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) + """ + from sage.misc.superseded import deprecation + deprecation(32367, 'the method exponential is deprecated. Use exp instead.') + return self.exp() + + def compute_coefficients(self, i): + r""" + Computes all the coefficients of self up to i. + + This method is deprecated, it has no effect anymore. + + TESTS:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: a = L([1,2,3], constant=3) + sage: a.compute_coefficients(5) + doctest:...: DeprecationWarning: the method compute_coefficients obsolete and has no effect. + See https://trac.sagemath.org/32367 for details. + sage: a + 1 + 2*z + 3*z^2 + 3*z^3 + 3*z^4 + 3*z^5 + O(z^6) + """ + from sage.misc.superseded import deprecation + deprecation(32367, "the method compute_coefficients obsolete and has no effect.") + return + def __call__(self, *g, check=True): r""" Return the composition of ``self`` with ``g``. @@ -3625,8 +3663,8 @@ def __call__(self, *g, check=True): EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(QQ) - sage: M. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(QQ) + sage: M. = LazyPowerSeriesRing(ZZ) sage: g1 = 1 / (1 - x) sage: g2 = x + y^2 sage: p = a^2 + b + 1 @@ -3636,7 +3674,7 @@ def __call__(self, *g, check=True): The number of mappings from a set with `m` elements to a set with `n` elements:: - sage: M. = LazyTaylorSeriesRing(QQ) + sage: M. = LazyPowerSeriesRing(QQ) sage: Ea = M(lambda n: 1/factorial(n)) sage: Ex = L(lambda n: 1/factorial(n)*x^n) sage: Ea(Ex*y)[5] @@ -3680,7 +3718,7 @@ def __call__(self, *g, check=True): of `f` and the parent of `g` or extended to the corresponding lazy series:: - sage: T. = LazyTaylorSeriesRing(QQ) + sage: T. = LazyPowerSeriesRing(QQ) sage: R. = ZZ[] sage: S. = R[] sage: L. = LaurentPolynomialRing(ZZ) @@ -3709,7 +3747,7 @@ def __call__(self, *g, check=True): TESTS:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: f = 1 / (1 - x - y) sage: f(f) Traceback (most recent call last): @@ -3732,7 +3770,7 @@ def __call__(self, *g, check=True): Consistency check when `g` is an uninitialized series between a polynomial `f` as both a polynomial and a lazy series:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: f = 1 - z sage: g = L(None, valuation=1) sage: f(g) == f.polynomial()(g) @@ -3749,8 +3787,8 @@ def __call__(self, *g, check=True): Check that composing the zero series with anything yields zero:: - sage: T. = LazyTaylorSeriesRing(QQ) - sage: M. = LazyTaylorSeriesRing(QQ) + sage: T. = LazyPowerSeriesRing(QQ) + sage: M. = LazyPowerSeriesRing(QQ) sage: T(0)(1/(1-a), a+b) 0 @@ -3812,13 +3850,13 @@ def __call__(self, *g, check=True): S = fP._laurent_poly_ring P = fP if isinstance(P, (PolynomialRing_general, MPolynomialRing_base)): - from sage.rings.lazy_series_ring import LazyTaylorSeriesRing + from sage.rings.lazy_series_ring import LazyPowerSeriesRing S = P try: sparse = S.is_sparse() except AttributeError: sparse = fP.is_sparse() - P = LazyTaylorSeriesRing(S.base_ring(), S.variable_names(), sparse) + P = LazyPowerSeriesRing(S.base_ring(), S.variable_names(), sparse) elif isinstance(P, LaurentPolynomialRing_univariate): from sage.rings.lazy_series_ring import LazyLaurentSeriesRing S = P @@ -3887,7 +3925,7 @@ def revert(self): EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: (2*z).revert() 1/2*z sage: (z-z^2).revert() @@ -3903,7 +3941,7 @@ def revert(self): TESTS:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: s = L(lambda n: 2 if n == 1 else 0, valuation=1); s 2*z + O(z^8) sage: s.revert() @@ -3920,7 +3958,7 @@ def revert(self): ValueError: cannot determine whether the compositional inverse exists sage: R. = QQ[] - sage: L. = LazyTaylorSeriesRing(R.fraction_field()) + sage: L. = LazyPowerSeriesRing(R.fraction_field()) sage: s = L([q], valuation=0, constant=t); s q + t*z + t*z^2 + t*z^3 + O(z^4) sage: s.revert() @@ -4029,7 +4067,7 @@ def derivative(self, *args): EXAMPLES:: - sage: T. = LazyTaylorSeriesRing(ZZ) + sage: T. = LazyPowerSeriesRing(ZZ) sage: z.derivative() 1 sage: (1+z+z^2).derivative(3) @@ -4038,7 +4076,7 @@ def derivative(self, *args): 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) sage: R. = QQ[] - sage: L. = LazyTaylorSeriesRing(R) + sage: L. = LazyPowerSeriesRing(R) sage: f = 1/(1-q*x+y); f 1 + (q*x-y) + (q^2*x^2+(-2*q)*x*y+y^2) + (q^3*x^3+(-3*q^2)*x^2*y+3*q*x*y^2-y^3) + (q^4*x^4+(-4*q^3)*x^3*y+6*q^2*x^2*y^2+(-4*q)*x*y^3+y^4) + (q^5*x^5+(-5*q^4)*x^4*y+10*q^3*x^3*y^2+(-10*q^2)*x^2*y^3+5*q*x*y^4-y^5) + (q^6*x^6+(-6*q^5)*x^5*y+15*q^4*x^4*y^2+(-20*q^3)*x^3*y^3+15*q^2*x^2*y^4+(-6*q)*x*y^5+y^6) + O(x,y)^7 sage: f.derivative(q) @@ -4106,7 +4144,7 @@ def _format_series(self, formatter, format_strings=False): TESTS:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: f = 1 / (2 - x^2 + y) sage: f._format_series(repr) '1/2 + (-1/4*y) + (1/4*x^2+1/8*y^2) + (-1/4*x^2*y-1/16*y^3) + (1/8*x^4+3/16*x^2*y^2+1/32*y^4) + (-3/16*x^4*y-1/8*x^2*y^3-1/64*y^5) + (1/16*x^6+3/16*x^4*y^2+5/64*x^2*y^4+1/128*y^6) + O(x,y)^7' @@ -4188,7 +4226,7 @@ def polynomial(self, degree=None, names=None): EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: f = x^2 + y*x - x + 2; f 2 + (-x) + (x^2+x*y) sage: f.polynomial() @@ -4212,7 +4250,7 @@ def polynomial(self, degree=None, names=None): sage: g3.polynomial(0) 1 - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: f = z-z^2 sage: f.polynomial() -z^2 + z diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index dd5fdf6a447..c29a41fcd1c 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -9,7 +9,7 @@ :delim: | :class:`LazyLaurentSeriesRing` | The ring of lazy Laurent series. - :class:`LazyTaylorSeriesRing` | The ring of (possibly multivariate) lazy Taylor series. + :class:`LazyPowerSeriesRing` | The ring of (possibly multivariate) lazy Taylor series. :class:`LazyCompletionGradedAlgebra` | The completion of a graded algebra consisting of formal series. :class:`LazySymmetricFunctions` | The ring of (possibly multivariate) lazy symmetric functions. :class:`LazyDirichletSeriesRing` | The ring of lazy Dirichlet series. @@ -51,7 +51,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.lazy_series import (LazyModuleElement, LazyLaurentSeries, - LazyTaylorSeries, + LazyPowerSeries, LazyCompletionGradedAlgebraElement, LazySymmetricFunction, LazyDirichletSeries) @@ -475,7 +475,7 @@ def undefined(self, valuation=None): EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: s = L.undefined(1) sage: s.define(z + (s^2+s(z^2))/2) sage: s @@ -549,7 +549,7 @@ def one(self): sage: L.one() 1 - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.one() 1 @@ -583,7 +583,7 @@ def zero(self): sage: L.zero() 0 - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.zero() 0 """ @@ -605,7 +605,7 @@ def characteristic(self): sage: R.characteristic() 11 - sage: R. = LazyTaylorSeriesRing(GF(7)); R + sage: R. = LazyPowerSeriesRing(GF(7)); R Multivariate Lazy Taylor Series Ring in x, y over Finite Field of size 7 sage: R.characteristic() 7 @@ -628,7 +628,7 @@ def _coerce_map_from_(self, S): sage: L.has_coerce_map_from(GF(2)) True - sage: L = LazyTaylorSeriesRing(GF(2), 'z') + sage: L = LazyPowerSeriesRing(GF(2), 'z') sage: L.has_coerce_map_from(ZZ) True sage: L.has_coerce_map_from(GF(2)) @@ -1137,7 +1137,7 @@ def _monomial(self, c, n): ###################################################################### -class LazyTaylorSeriesRing(LazySeriesRing): +class LazyPowerSeriesRing(LazySeriesRing): """ The ring of (possibly multivariate) lazy Taylor series. @@ -1149,13 +1149,13 @@ class LazyTaylorSeriesRing(LazySeriesRing): EXAMPLES:: - sage: LazyTaylorSeriesRing(ZZ, 't') + sage: LazyPowerSeriesRing(ZZ, 't') Lazy Taylor Series Ring in t over Integer Ring - sage: L. = LazyTaylorSeriesRing(QQ); L + sage: L. = LazyPowerSeriesRing(QQ); L Multivariate Lazy Taylor Series Ring in x, y over Rational Field """ - Element = LazyTaylorSeries + Element = LazyPowerSeries def __init__(self, base_ring, names, sparse=True, category=None): """ @@ -1163,7 +1163,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: - sage: L = LazyTaylorSeriesRing(ZZ, 't') + sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) """ from sage.structure.category_object import normalize_names @@ -1197,7 +1197,7 @@ def _repr_(self): EXAMPLES:: - sage: LazyTaylorSeriesRing(GF(2), 'z') + sage: LazyPowerSeriesRing(GF(2), 'z') Lazy Taylor Series Ring in z over Finite Field of size 2 """ BR = self.base_ring() @@ -1212,7 +1212,7 @@ def _latex_(self): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(GF(2), 'z') + sage: L = LazyPowerSeriesRing(GF(2), 'z') sage: latex(L) \Bold{F}_{2} [\![z]\!] """ @@ -1226,7 +1226,7 @@ def _monomial(self, c, n): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L._monomial(2, 3) 2*z^3 """ @@ -1243,7 +1243,7 @@ def gen(self, n=0): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.gen() z sage: L.gen(3) @@ -1271,7 +1271,7 @@ def ngens(self): EXAMPLES:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: L.ngens() 1 """ @@ -1284,7 +1284,7 @@ def gens(self): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(ZZ, 'x,y') + sage: L = LazyPowerSeriesRing(ZZ, 'x,y') sage: L.gens() (x, y) """ @@ -1304,13 +1304,13 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No EXAMPLES:: - sage: L = LazyTaylorSeriesRing(GF(2), 'z') + sage: L = LazyPowerSeriesRing(GF(2), 'z') sage: L(2) 0 sage: L(3) 1 - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L(lambda i: i, 5, 1, 10) 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13) sage: L(lambda i: i, 5, (1, 10)) @@ -1355,7 +1355,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No sage: P. = QQ[] sage: p = x + 3*x^2 + x^5 - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: L(p) x + 3*x^2 + x^5 @@ -1364,13 +1364,13 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No sage: P. = QQ[] sage: p = x + y^2 + x*y - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: L(p) x + (x*y+y^2) TESTS:: - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: L(constant=1) Traceback (most recent call last): ... @@ -1450,7 +1450,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No degree=degree) return self.element_class(self, coeff_stream) - if isinstance(x, LazyTaylorSeries): + if isinstance(x, LazyPowerSeries): if x._coeff_stream._is_sparse is self._sparse: return self.element_class(self, x._coeff_stream) # TODO: Implement a way to make a self._sparse copy @@ -1501,7 +1501,7 @@ def _an_element_(self): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(ZZ, 'z') + sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.an_element() z + z^2 + z^3 + z^4 + O(z^5) """ diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py index 211843c00a2..e964bcd4b70 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py @@ -117,7 +117,7 @@ Sage example in ./combinat.tex, line 654:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) Sage example in ./combinat.tex, line 661:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py index 075d388d3b2..2115f8edb3c 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/polynomes_doctest.py @@ -362,7 +362,7 @@ Sage example in ./polynomes.tex, line 2028:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: lazy_exp = x.exp(); lazy_exp 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) From b7d1b867793601ac3108944231dde2175234eba9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 9 Sep 2022 09:32:23 +0200 Subject: [PATCH 076/350] fix categories and add doctests --- src/sage/rings/lazy_series_ring.py | 36 ++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index c29a41fcd1c..bce8c794307 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1165,6 +1165,27 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + sage: L = LazyPowerSeriesRing(ZZ, 's, t') + sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + Check that :trac:`34470` is fixed:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: L in CompleteDiscreteValuationRings + True + sage: L.uniformizer() + t + sage: lcm(1/(1 - t^2) - 1, t) + t^2 + + sage: L. = LazyPowerSeriesRing(ZZ) + sage: L in PrincipalIdealDomains + False + + sage: L = LazyPowerSeriesRing(QQ, 's, t') + sage: L in PrincipalIdealDomains + False """ from sage.structure.category_object import normalize_names names = normalize_names(-1, names) @@ -1177,8 +1198,9 @@ def __init__(self, base_ring, names, sparse=True, category=None): else: self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE") category = Algebras(base_ring.category()) - if base_ring in Fields(): + if base_ring in Fields() and self._arity == 1: category &= CompleteDiscreteValuationRings() + self.uniformizer = lambda: self.gen() elif base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): @@ -1566,6 +1588,14 @@ def __init__(self, basis, sparse=True, category=None): sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + Check that :trac:`34470` is fixed:: + + sage: s = SymmetricFunctions(QQ).s() + sage: L = LazySymmetricFunctions(s) + sage: L in PrincipalIdealDomains + False + """ base_ring = basis.base_ring() self._minimal_valuation = 0 @@ -1576,9 +1606,7 @@ def __init__(self, basis, sparse=True, category=None): raise ValueError("basis should be a graded algebra") self._arity = 1 category = Algebras(base_ring.category()) - if base_ring in Fields(): - category &= CompleteDiscreteValuationRings() - elif base_ring in IntegralDomains(): + if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): category = category.Commutative() From f5e3f2ef6f0c1757881e16c1563833cf119f4a83 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 9 Sep 2022 12:46:04 +0200 Subject: [PATCH 077/350] fix documentation --- src/doc/en/reference/combinat/module_list.rst | 3 -- src/sage/combinat/tutorial.py | 2 +- src/sage/rings/lazy_series_ring.py | 34 +++++++++++-------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 7a97a40e30d..e42e3891d45 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -339,11 +339,8 @@ Comprehensive Module List sage/combinat/species/permutation_species sage/combinat/species/product_species sage/combinat/species/recursive_species - sage/combinat/species/series - sage/combinat/species/series_order sage/combinat/species/set_species sage/combinat/species/species - sage/combinat/species/stream sage/combinat/species/structure sage/combinat/species/subset_species sage/combinat/species/sum_species diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 90ec8eea713..6422d920378 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -310,7 +310,7 @@ It is unfortunate to have to recalculate everything if at some point we wanted the 101-st coefficient. Lazy power series (see -:mod:`sage.combinat.species.series`) come into their own here, in that +:mod:`sage.rings.lazy_series_ring`) come into their own here, in that one can define them from a system of equations without solving it, and, in particular, without needing a closed form for the answer. We begin by defining the ring of lazy power series:: diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index c29a41fcd1c..78299f03c17 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -709,7 +709,7 @@ def is_exact(self): class LazyLaurentSeriesRing(LazySeriesRing): - """ + r""" The ring of lazy Laurent series. The ring of Laurent series over a ring with the usual arithmetic @@ -743,8 +743,7 @@ class LazyLaurentSeriesRing(LazySeriesRing): Finite Field of size 3 Series can be defined by specifying a coefficient function - along with a valuation or a degree where after the series - is evenutally constant:: + and a valuation:: sage: R. = QQ[] sage: L. = LazyLaurentSeriesRing(R) @@ -764,9 +763,9 @@ class LazyLaurentSeriesRing(LazySeriesRing): -5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + (y^2 + x)*z^2 + x*z^3 + x*z^4 + x*z^5 + O(z^6) - Similarly, we can specify a polynomial or the initial - coefficients with anything that converts into the - corresponding Laurent polynomial ring:: + We can also specify a polynomial or the initial coefficients. + Additionally, we may specify that all coefficients are equal to a + given constant, beginning at a given degree:: sage: L([1, x, y, 0, x+y]) 1 + x*z + y*z^2 + (x + y)*z^4 @@ -797,8 +796,8 @@ class LazyLaurentSeriesRing(LazySeriesRing): sage: L(x^-2 + 3 + x, valuation=-5, degree=0, constant=2) z^-5 + 3*z^-3 + z^-2 + 2 + 2*z + 2*z^2 + O(z^3) - We can also truncate, shift, and make eventually constant any - Laurent series:: + We can truncate a series, shift its coefficients, or replace all + coefficients beginning with a given degree by a constant:: sage: f = 1 / (z + z^2) sage: f @@ -819,16 +818,16 @@ class LazyLaurentSeriesRing(LazySeriesRing): more examples):: sage: L. = LazyLaurentSeriesRing(ZZ) - sage: s = L(None, valuation=0) + sage: s = L.undefined(valuation=0) sage: s.define(1 + z*s^2) sage: s 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) - If we do not explicitly know the exact value of every - coefficient, then equality checking will depend on the computed - coefficients. If at a certain point we cannot prove two series - are different (which involves the coefficients we have computed), - then we will raise an error:: + If the series is not specified by a finite number of initial + coefficients and a constant for the remaining coefficients, then + equality checking will depend on the coefficients which have + already been computed. If this information is not enough to + check that two series are different we raise an error:: sage: f = 1 / (z + z^2); f z^-1 - 1 + z - z^2 + z^3 - z^4 + z^5 + O(z^6) @@ -1302,6 +1301,13 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No - ``degree`` -- (optional) the degree when the series is ``constant`` - ``check`` -- (optional) check that coefficients are homogeneous of the correct degree when they are retrieved + .. WARNING:: + + The behaviour of ``LazyPowerSeries(l)`` for a list ``l`` + with non-zero last element `e` changed with + :trac:`32367`. To obtain the old behaviour, use + ``LazyPowerSeries(l, constant=e)``. + EXAMPLES:: sage: L = LazyPowerSeriesRing(GF(2), 'z') From c5bfba5f8e8d41bc6341b7a490ae56469e2adcae Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 9 Sep 2022 20:26:44 +0200 Subject: [PATCH 078/350] adapt a doctest --- src/sage/combinat/sf/sfa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 1fb9d204e34..854b92393f5 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -3083,7 +3083,7 @@ def plethysm(self, x, include=None, exclude=None): + ... + O^8 sage: fog = f(g) sage: fog[:8] - [s[2, 1], + [0, 0, 0, s[2, 1], s[1, 1, 1, 1] + 3*s[2, 1, 1] + 2*s[2, 2] + 3*s[3, 1] + s[4], 2*s[1, 1, 1, 1, 1] + 8*s[2, 1, 1, 1] + 10*s[2, 2, 1] + 12*s[3, 1, 1] + 10*s[3, 2] + 8*s[4, 1] + 2*s[5], From ceecc89392820fbbf07f2ad1b9915ac02ac4d6d4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Sep 2022 08:20:09 +0200 Subject: [PATCH 079/350] don't use l --- src/sage/rings/lazy_series_ring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 78299f03c17..98e40a41c8f 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1303,10 +1303,10 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No .. WARNING:: - The behaviour of ``LazyPowerSeries(l)`` for a list ``l`` + The behaviour of ``LazyPowerSeries(c)`` for a list ``c`` with non-zero last element `e` changed with :trac:`32367`. To obtain the old behaviour, use - ``LazyPowerSeries(l, constant=e)``. + ``LazyPowerSeries(c, constant=e)``. EXAMPLES:: From 9629b2878b228fb2c5623f4d2b1df60e2c4bb287 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Sep 2022 08:46:45 +0200 Subject: [PATCH 080/350] require the start value for __getitem__ of LazyLaurentSeries --- src/sage/rings/lazy_series.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index e7869d6e8b5..f6079c16210 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -204,9 +204,9 @@ class LazyModuleElement(Element): sage: L. = LazyLaurentSeriesRing(ZZ) sage: M = L(lambda n: n, valuation=0) sage: N = L(lambda n: 1, valuation=0) - sage: M[:10] + sage: M[0:10] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - sage: N[:10] + sage: N[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] Two sequences can be added:: @@ -218,19 +218,19 @@ class LazyModuleElement(Element): Two sequences can be subtracted:: sage: P = M - N - sage: P[:10] + sage: P[0:10] [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8] A sequence can be multiplied by a scalar:: sage: Q = 2 * M - sage: Q[:10] + sage: Q[0:10] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] The negation of a sequence can also be found:: sage: R = -M - sage: R[:10] + sage: R[0:10] [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] """ def __init__(self, parent, coeff_stream): @@ -304,7 +304,7 @@ def __getitem__(self, n): elif L._minimal_valuation is not None: start = L._minimal_valuation else: - start = self._coeff_stream._approximate_order + raise ValueError("the start value must be specified if there is no minimal valuation, such as for LazyLaurentSeries") step = n.step if n.step is not None else 1 return [R(self._coeff_stream[k]) for k in range(start, n.stop, step)] return R(self._coeff_stream[n]) @@ -739,9 +739,9 @@ def define(self, s): sage: t = L(None, valuation=0) sage: s.define(1 + z*t^3) sage: t.define(1 + z*s^2) - sage: s[:9] + sage: s[0:9] [1, 1, 3, 9, 34, 132, 546, 2327, 10191] - sage: t[:9] + sage: t[0:9] [1, 1, 2, 7, 24, 95, 386, 1641, 7150] A bigger example:: @@ -765,7 +765,7 @@ def define(self, s): sage: L. = LazyLaurentSeriesRing(QQ) sage: s = L(None, valuation=1) sage: s.define(z + (s^2+s(z^2))/2) - sage: [s[i] for i in range(9)] + sage: s[0:9] [0, 1, 1, 1, 2, 3, 6, 11, 23] The `q`-Catalan numbers:: @@ -791,7 +791,7 @@ def define(self, s): sage: L = Q(constant=1, degree=1) sage: T = Q(None, valuation=1) sage: T.define(leaf + internal_node * L(T)) - sage: [T[i] for i in range(6)] + sage: T[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] Similarly for Dirichlet series:: @@ -799,7 +799,7 @@ def define(self, s): sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: g = L(constant=1, valuation=2) sage: F = L(None); F.define(1 + g*F) - sage: [F[i] for i in range(1, 16)] + sage: F[:16] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] sage: oeis(_) # optional, internet 0: A002033: Number of perfect partitions of n. @@ -807,7 +807,7 @@ def define(self, s): ... sage: F = L(None); F.define(1 + g*F*F) - sage: [F[i] for i in range(1, 16)] + sage: F[:16] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5] We can compute the Frobenius character of unlabeled trees:: @@ -831,7 +831,7 @@ def define(self, s): sage: L. = LazyLaurentSeriesRing(ZZ, sparse=True) sage: s = L(None, valuation=0) sage: s.define(1 + z*s^3) - sage: s[:10] + sage: s[0:10] [1, 1, 3, 12, 55, 273, 1428, 7752, 43263, 246675] sage: e = L(None, valuation=0) From 037f3f7cad9b7bfb955f9cb3d1aaf7a4363c7ccb Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Sep 2022 10:36:32 +0200 Subject: [PATCH 081/350] implement coefficients --- src/sage/rings/lazy_series.py | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index f6079c16210..4eadf1cece3 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -311,6 +311,67 @@ def __getitem__(self, n): coefficient = __getitem__ + def coefficients(self, n=None): + """ + Return the first `n` non-zero coefficients of self. + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: f = L([1,2,3]) + sage: f.coefficients(5) + doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. + See https://trac.sagemath.org/32367 for details. + [1, 2, 3] + + sage: f = sin(x) + sage: f.coefficients(5) + doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. + See https://trac.sagemath.org/32367 for details. + [1, -1/6, 1/120, -1/5040, 1/362880] + + sage: L. = LazyPowerSeriesRing(QQ) + sage: f = sin(x^2+y^2) + sage: f.coefficients(5) + """ + coeff_stream = self._coeff_stream + if isinstance(coeff_stream, Stream_zero): + return [] + + if n is None: + from sage.misc.lazy_list import lazy_list + if isinstance(coeff_stream, Stream_exact): + if coeff_stream._constant: + coeffs = ([c for c in coeff_stream._initial_coefficients if c] + + lazy_list(lambda n: coeff_stream._constant)) + else: + coeffs = [c for c in coeff_stream._initial_coefficients if c] + else: + coeffs = lazy_list(filter(lambda c: c, + coeff_stream.iterate_coefficients())) + else: + if isinstance(self, LazyPowerSeries) and self.parent()._arity == 1: + from sage.misc.superseded import deprecation + deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') + + if isinstance(coeff_stream, Stream_exact) and not coeff_stream._constant: + coeffs = [c for c in coeff_stream._initial_coefficients if c] + else: + coeffs = [] + i = self.valuation() + while len(coeffs) < n: + if self[i]: + coeffs.append(self[i]) + i += 1 + + if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): + return coeffs + + if isinstance(coeffs, list): + return [c for coeff in coeffs for c in coeff.coefficients()] + + return lazy_list(map(lambda coeff: coeff.coefficients(), coeffs)) + def map_coefficients(self, func): r""" Return the series with ``func`` applied to each nonzero From 787197ed609f8291ba23d2c102686b2d8353ec9d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 10 Sep 2022 16:07:35 +0200 Subject: [PATCH 082/350] fix some bugs --- src/sage/rings/lazy_series.py | 79 ++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 4eadf1cece3..9658f98252a 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -312,8 +312,24 @@ def __getitem__(self, n): coefficient = __getitem__ def coefficients(self, n=None): - """ - Return the first `n` non-zero coefficients of self. + r"""Return the first `n` non-zero coefficients of ``self``. + + INPUT: + + - ``n`` -- (default: ``None``), the number of non-zero + coefficients to return. + + If the series has fewer than `n` non-zero coefficients, only + these are returned. + + If ``n`` is ``None``, a + :class:`~sage.misc.lazy_list.lazy_list_generic` with all + non-zero coefficients is returned instead. + + .. WARNING:: + + If there are fewer than `n` non-zero coefficients, but + this cannot be detected, this method will not return. EXAMPLES:: @@ -326,51 +342,48 @@ def coefficients(self, n=None): sage: f = sin(x) sage: f.coefficients(5) - doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. - See https://trac.sagemath.org/32367 for details. [1, -1/6, 1/120, -1/5040, 1/362880] sage: L. = LazyPowerSeriesRing(QQ) sage: f = sin(x^2+y^2) - sage: f.coefficients(5) + sage: f.coefficients(5) + [1, 1, -1/6, -1/2, -1/2] + + sage: f.coefficients() + lazy list [1, 1, -1/6, ...] + """ coeff_stream = self._coeff_stream if isinstance(coeff_stream, Stream_zero): return [] - - if n is None: - from sage.misc.lazy_list import lazy_list - if isinstance(coeff_stream, Stream_exact): - if coeff_stream._constant: - coeffs = ([c for c in coeff_stream._initial_coefficients if c] - + lazy_list(lambda n: coeff_stream._constant)) - else: - coeffs = [c for c in coeff_stream._initial_coefficients if c] + from itertools import repeat, chain, islice + from sage.misc.lazy_list import lazy_list + # prepare a generator of the non-zero coefficients + if isinstance(coeff_stream, Stream_exact): + if coeff_stream._constant: + coeffs = chain([c for c in coeff_stream._initial_coefficients if c], + repeat(coeff_stream._constant)) else: - coeffs = lazy_list(filter(lambda c: c, - coeff_stream.iterate_coefficients())) + coeffs = (c for c in coeff_stream._initial_coefficients if c) else: - if isinstance(self, LazyPowerSeries) and self.parent()._arity == 1: - from sage.misc.superseded import deprecation - deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') + coeffs = filter(lambda c: c, coeff_stream.iterate_coefficients()) - if isinstance(coeff_stream, Stream_exact) and not coeff_stream._constant: - coeffs = [c for c in coeff_stream._initial_coefficients if c] - else: - coeffs = [] - i = self.valuation() - while len(coeffs) < n: - if self[i]: - coeffs.append(self[i]) - i += 1 + if n is None: + if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): + return lazy_list(coeffs) - if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): - return coeffs + # flatten out the generator in the multivariate case + return lazy_list(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs))) + + if isinstance(self, LazyPowerSeries) and self.parent()._arity == 1: + from sage.misc.superseded import deprecation + deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') - if isinstance(coeffs, list): - return [c for coeff in coeffs for c in coeff.coefficients()] + if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): + return list(islice(coeffs, n)) - return lazy_list(map(lambda coeff: coeff.coefficients(), coeffs)) + # flatten out the generator in the multivariate case + return list(islice(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs)), n)) def map_coefficients(self, func): r""" From 8f46e127e30e1f0a3e6d1a6997e806baf7254710 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 11 Sep 2022 19:48:40 +0200 Subject: [PATCH 083/350] implement new semantics of __getitem__ --- src/sage/combinat/sf/sfa.py | 2 +- src/sage/rings/lazy_series.py | 68 ++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 854b92393f5..1fb9d204e34 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -3083,7 +3083,7 @@ def plethysm(self, x, include=None, exclude=None): + ... + O^8 sage: fog = f(g) sage: fog[:8] - [0, 0, 0, s[2, 1], + [s[2, 1], s[1, 1, 1, 1] + 3*s[2, 1, 1] + 2*s[2, 2] + 3*s[3, 1] + s[4], 2*s[1, 1, 1, 1, 1] + 8*s[2, 1, 1, 1] + 10*s[2, 2, 1] + 12*s[3, 1, 1] + 10*s[3, 2] + 8*s[4, 1] + 2*s[5], diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 9658f98252a..0b3567830c4 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -251,21 +251,36 @@ def __init__(self, parent, coeff_stream): self._coeff_stream = coeff_stream def __getitem__(self, n): - """ - Return the coefficient of the term with exponent ``n`` of the series. + r""" + Return the homogeneous degree ``n`` part of the series. INPUT: - - ``n`` -- integer; the exponent + - ``n`` -- integer; the degree + + For a series ``f``, the slice ``f[start:stop]`` produces the following: + + - if ``start`` and ``stop`` are integers, return the list of + terms with given degrees + + - if ``start`` is ``None``, return the list of terms + beginning with the valuation + + - if ``stop`` is ``None``, return a + :class:`~sage.misc.lazy_list.lazy_list_generic` instead. EXAMPLES:: - sage: L. = LazyLaurentSeriesRing(ZZ, sparse=False) + sage: L. = LazyLaurentSeriesRing(ZZ) sage: f = z / (1 - 2*z^3) sage: [f[n] for n in range(20)] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] sage: f[0:20] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] + sage: f[:20] + [1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] + sage: f[::3] + lazy list [1, 2, 4, ...] sage: M = L(lambda n: n, valuation=0) sage: [M[n] for n in range(20)] @@ -276,37 +291,35 @@ def __getitem__(self, n): sage: [M[n] for n in range(20)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] + Similarly for multivariate series:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: sin(x*y)[:11] + [x*y, 0, 0, 0, -1/6*x^3*y^3, 0, 0, 0, 1/120*x^5*y^5] + sage: sin(x*y)[2::4] + lazy list [x*y, -1/6*x^3*y^3, 1/120*x^5*y^5, ...] + Similarly for Dirichlet series:: sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: f = L(lambda n: n) - sage: [f[n] for n in range(1, 11)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - sage: f[1:11] + sage: L(lambda n: n)[1:11] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - - sage: M = L(lambda n: n) - sage: [M[n] for n in range(1, 11)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - sage: L = LazyDirichletSeriesRing(ZZ, "z", sparse=True) - sage: M = L(lambda n: n) - sage: [M[n] for n in range(1, 11)] - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - """ - L = self.parent() - R = L._internal_poly_ring.base_ring() + R = self.parent()._internal_poly_ring.base_ring() if isinstance(n, slice): - if n.stop is None: - raise NotImplementedError("cannot list an infinite set") - if n.start is not None: - start = n.start - elif L._minimal_valuation is not None: - start = L._minimal_valuation + if n.start is None: + # WARNING: for Dirichlet series, 'degree' and + # valuation are different + start = self._coeff_stream.order() else: - raise ValueError("the start value must be specified if there is no minimal valuation, such as for LazyLaurentSeries") + start = n.start step = n.step if n.step is not None else 1 + if n.stop is None: + from sage.misc.lazy_list import lazy_list + return lazy_list(lambda k: R(self._coeff_stream[start + k * step])) + return [R(self._coeff_stream[k]) for k in range(start, n.stop, step)] + return R(self._coeff_stream[n]) coefficient = __getitem__ @@ -893,8 +906,7 @@ def define(self, s): sage: X = L(s[1]) sage: A = L(None); A.define(X*E(A, check=False)) sage: A[:6] - [0, - m[1], + [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], 64*m[1, 1, 1, 1] + 34*m[2, 1, 1] + 18*m[2, 2] + 13*m[3, 1] + 4*m[4], From d9112b5ba3684ef6883708e84affd9fd137eb1dc Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Mon, 12 Sep 2022 06:40:28 +0100 Subject: [PATCH 084/350] Add doctests, edit parameter names --- src/sage/graphs/edge_connectivity.pyx | 29 ++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 7fecce22cbd..4cfdbd741ef 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -9,7 +9,6 @@ from a `2k` edge-connected graph or a `k` edge-connected digraph. .. TODO:: - - Add speedup methods proposed in [GKLP2021]_ for the edge connectivity - Implement the tree-packing algorithms proposed in [Gabow1995]_ and [BHKP2008]_ - Extend to digraphs with multiple edges @@ -62,7 +61,14 @@ cdef class GabowEdgeConnectivity: ....: D = DiGraph(graphs.RandomRegular(6, 50)) sage: GabowEdgeConnectivity(D).edge_connectivity() 6 - + + A complete digraph with `n` vertices is `n-1`-edge-connected:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = DiGraph(digraphs.Complete(2000)) + sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() + 1999 + TESTS: :trac:`32169`:: @@ -174,17 +180,22 @@ cdef class GabowEdgeConnectivity: cdef int num_joins # number of joined vertices from dfs cdef bint* T # whether the an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree - cdef bint dfs # whether or not we should use dfs-based fast initialization + cdef bint dfs_preprocessing # whether or not we should use DFS-based fast initialization cdef int * incident_edge_index # used for DFS initialization cdef bint use_rec # variable to remove, used for development - def __init__(self, G, dfs=True, use_rec=False): + def __init__(self, G, dfs_preprocessing=True, use_rec=False): r""" Initialize this object. INPUT: - ``G`` -- a :class:`~sage.graphs.digraph.DiGraph` + - ``dfs_preprocessing`` -- boolean (default: ``True``); indicates whether to + use the DFS-based "Fast initialization" provided in [GKLP2021]_ + - ``use_rec`` -- boolean (default: ``False``); indicates whether to use a + recursive or non-recursive DFS for ``dfs_preprocessing``. The recursive DFS + tends to be faster than the non-recursive version on complete digraphs EXAMPLES:: @@ -193,7 +204,7 @@ cdef class GabowEdgeConnectivity: sage: GabowEdgeConnectivity(D).edge_connectivity() 4 """ - self.dfs = dfs + self.dfs_preprocessing = dfs_preprocessing self.use_rec = use_rec self.ec_checked = False from sage.graphs.digraph import DiGraph @@ -379,7 +390,7 @@ cdef class GabowEdgeConnectivity: # There are fewer than n f-trees. We prepare to join them. If there's # only one f-tree, we just save the edges and advance to the next # iteration - if self.dfs and self.num_start_f_trees < self.n - 1: + if self.dfs_preprocessing and self.num_start_f_trees < self.n - 1: self.re_init(tree) # There are n f-trees, and we try to join them @@ -444,7 +455,7 @@ cdef class GabowEdgeConnectivity: self.num_joins = 0 # Initialize T_k to be a DFS spanning forest of G \ T - if self.dfs: + if self.dfs_preprocessing: self.compute_dfs_tree() # Set inactive the f-trees of the root vertex @@ -993,14 +1004,14 @@ cdef class GabowEdgeConnectivity: # Arrange the edges of each tree for j in range(tree + 1): - if self.dfs: + if self.dfs_preprocessing: for e_id in self.tree_edges[j]: self.T[e_id] = False self.tree_edges[j].clear() for j in range(self.m): if self.my_edge_state[j] != self.UNUSED: self.tree_edges[self.my_edge_state[j]].push_back(j) - if self.dfs: + if self.dfs_preprocessing: self.T[j] = True for j in range(tree + 1): From 6abf817342c6192d360d2458b558ea5c8b3513f2 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Mon, 12 Sep 2022 07:28:16 +0100 Subject: [PATCH 085/350] Use 10 vertices instead of 2000 --- src/sage/graphs/edge_connectivity.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 4cfdbd741ef..3462df9e14b 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -63,11 +63,11 @@ cdef class GabowEdgeConnectivity: 6 A complete digraph with `n` vertices is `n-1`-edge-connected:: - + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity - sage: D = DiGraph(digraphs.Complete(2000)) + sage: D = DiGraph(digraphs.Complete(10)) sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() - 1999 + 9 TESTS: From a742e36ca720f6eb22be9d8a4c309f0c2ae00082 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 12 Sep 2022 15:09:49 +0200 Subject: [PATCH 086/350] implement _im_gens_, part 1 --- src/sage/rings/lazy_series.py | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index e7869d6e8b5..ab9252d4728 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2724,6 +2724,32 @@ class LazyLaurentSeries(LazyCauchyProductSeries): sage: f = 1 / (1 - z - z^2) sage: TestSuite(f).run() """ + def _im_gens_(self, codomain, im_gens, base_map=None): + """ + Returns the image of ``self`` under the map that sends the + generators of the parent of ``self`` to the elements of the + tuple ``im_gens``. + + EXAMPLES:: + + sage: Z. = ZZ[] + sage: K. = NumberField(x^2 + 1) + sage: R. = LazyLaurentSeriesRing(K) + sage: f = R(lambda n: i^n, valuation=-2) + sage: f + -t^-2 - i*t^-1 + 1 + i*t - t^2 - i*t^3 + t^4 + O(t^5) + sage: f._im_gens_(R, [t + t^2]) + -t^-2 + (-i + 2)*t^-1 + (i - 2) + 4*t + (2*i - 6)*t^2 + (-2*i + 4)*t^3 + (-2*i - 7)*t^4 + O(t^5) + + sage: cc = K.hom([-i]) + sage: f._im_gens_(R, [t + t^2], base_map=cc) + -t^-2 + (i + 2)*t^-1 + (-i - 2) + 4*t + (-2*i - 6)*t^2 + (2*i + 4)*t^3 + (2*i - 7)*t^4 + O(t^5) + + """ + if base_map is None: + return codomain(self(im_gens[0])) + + return codomain(self.map_coefficients(base_map)(im_gens[0])) def __call__(self, g, *, check=True): r""" @@ -3634,6 +3660,32 @@ def compute_coefficients(self, i): deprecation(32367, "the method compute_coefficients obsolete and has no effect.") return + def _im_gens_(self, codomain, im_gens, base_map=None): + """ + Returns the image of ``self`` under the map that sends the + generators of the parent of ``self`` to the elements of the + tuple ``im_gens``. + + EXAMPLES:: + + sage: Z. = QQ[] + sage: R. = LazyPowerSeriesRing(Z) + sage: f = 1/(1-q-t) + sage: f + 1 + (q+t) + (q^2+2*q*t+t^2) + (q^3+3*q^2*t+3*q*t^2+t^3) + (q^4+4*q^3*t+6*q^2*t^2+4*q*t^3+t^4) + (q^5+5*q^4*t+10*q^3*t^2+10*q^2*t^3+5*q*t^4+t^5) + (q^6+6*q^5*t+15*q^4*t^2+20*q^3*t^3+15*q^2*t^4+6*q*t^5+t^6) + O(q,t)^7 + sage: S. = LazyPowerSeriesRing(Z) + sage: f._im_gens_(S, [t, x*t]) + 1 + ((x+1)*t) + ((x^2+2*x+1)*t^2) + ((x^3+3*x^2+3*x+1)*t^3) + ((x^4+4*x^3+6*x^2+4*x+1)*t^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*t^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*t^6) + O(t^7) + + sage: cc = Z.hom([-x]) + sage: f._im_gens_(S, [t, t], base_map=cc) + + """ + if base_map is None: + return codomain(self(*im_gens)) + + return codomain(self.map_coefficients(base_map)(*im_gens)) + def __call__(self, *g, check=True): r""" Return the composition of ``self`` with ``g``. From 3410eda2266a4ed0c38dc8ae053bd13194e26d62 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 12 Sep 2022 23:29:17 +0200 Subject: [PATCH 087/350] fix map_coefficients --- src/sage/rings/lazy_series.py | 80 ++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index afea2820872..2f07f6c28c5 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -325,7 +325,8 @@ def __getitem__(self, n): coefficient = __getitem__ def coefficients(self, n=None): - r"""Return the first `n` non-zero coefficients of ``self``. + r""" + Return the first `n` non-zero coefficients of ``self``. INPUT: @@ -398,9 +399,9 @@ def coefficients(self, n=None): # flatten out the generator in the multivariate case return list(islice(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs)), n)) - def map_coefficients(self, func): + def map_coefficients(self, f): r""" - Return the series with ``func`` applied to each nonzero + Return the series with ``f`` applied to each nonzero coefficient of ``self``. INPUT: @@ -408,7 +409,40 @@ def map_coefficients(self, func): - ``func`` -- function that takes in a coefficient and returns a new coefficient - EXAMPLES: + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: m = L(lambda n: n, valuation=0); m + z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) + sage: m.map_coefficients(lambda c: c + 1) + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) + + Similarly for Dirichlet series:: + + sage: L = LazyDirichletSeriesRing(ZZ, "z") + sage: s = L(lambda n: n-1); s + 1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z)) + sage: s.map_coefficients(lambda c: c + 1) + 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + O(1/(8^z)) + + Similarly for multivariate power series:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: f = 1/(1-(x+y)); f + 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 + sage: f.map_coefficients(lambda c: c^2) + 1 + (x+y) + (x^2+4*x*y+y^2) + (x^3+9*x^2*y+9*x*y^2+y^3) + (x^4+16*x^3*y+36*x^2*y^2+16*x*y^3+y^4) + (x^5+25*x^4*y+100*x^3*y^2+100*x^2*y^3+25*x*y^4+y^5) + (x^6+36*x^5*y+225*x^4*y^2+400*x^3*y^3+225*x^2*y^4+36*x*y^5+y^6) + O(x,y)^7 + + Similarly for lazy symmetric functions:: + + sage: p = SymmetricFunctions(QQ).p() + sage: L = LazySymmetricFunctions(p) + sage: f = 1/(1-2*L(p[1])); f + p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 + sage: f.map_coefficients(lambda c: log(c, 2)) + p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7 + + TESTS: Dense Implementation:: @@ -424,29 +458,7 @@ def map_coefficients(self, func): sage: m.map_coefficients(lambda c: c + 1) 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) - Sparse Implementation:: - - sage: L. = LazyLaurentSeriesRing(ZZ, sparse=True) - sage: m = L(lambda n: n, valuation=0); m - z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) - sage: m.map_coefficients(lambda c: c + 1) - 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) - - An example where the series is known to be exact:: - - sage: f = z + z^2 + z^3 - sage: f.map_coefficients(lambda c: c + 1) - 2*z + 2*z^2 + 2*z^3 - - Similarly for Dirichlet series:: - - sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: s = L(lambda n: n-1); s - 1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z)) - sage: s.map_coefficients(lambda c: c + 1) - 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + O(1/(8^z)) - - TESTS:: + Test the zero series:: sage: from sage.data_structures.stream import Stream_zero sage: L. = LazyLaurentSeriesRing(ZZ) @@ -455,12 +467,22 @@ def map_coefficients(self, func): sage: isinstance(s._coeff_stream, Stream_zero) True + An example where the series is known to be exact:: + + sage: f = z + z^2 + z^3 + sage: f.map_coefficients(lambda c: c + 1) + 2*z + 2*z^2 + 2*z^3 + """ P = self.parent() coeff_stream = self._coeff_stream if isinstance(coeff_stream, Stream_zero): return self - BR = P.base_ring() + R = P._internal_poly_ring.base_ring() + if P.base_ring() == R: + func = f + else: + func = lambda c: R(c).map_coefficients(f) if isinstance(coeff_stream, Stream_exact): initial_coefficients = [func(i) if i else 0 for i in coeff_stream._initial_coefficients] @@ -471,7 +493,7 @@ def map_coefficients(self, func): self._coeff_stream._is_sparse, order=coeff_stream._approximate_order, degree=coeff_stream._degree, - constant=BR(c)) + constant=P.base_ring()(c)) return P.element_class(P, coeff_stream) coeff_stream = Stream_map_coefficients(self._coeff_stream, func) return P.element_class(P, coeff_stream) From 8fc2dd1a5c5de7f393de048c920e1d49be4660ba Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 12 Sep 2022 23:39:52 +0200 Subject: [PATCH 088/350] fix doctests because of __getitem__ change --- src/sage/combinat/species/generating_series.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 8c0910f0043..5125695da91 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -480,7 +480,7 @@ def logarithm(self): sage: G = species.SimpleGraphSpecies().cycle_index_series() - 1 sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries sage: CG = LogarithmCycleIndexSeries()(G) - sage: CG.isotype_generating_series()[:8] + sage: CG.isotype_generating_series()[0:8] [0, 1, 1, 2, 6, 21, 112, 853] """ base_ring = self.parent().base_ring().base_ring() @@ -635,7 +635,7 @@ def LogarithmCycleIndexSeries(R = RationalField()): its cycle index has negative coefficients:: sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: LogarithmCycleIndexSeries()[:4] + sage: LogarithmCycleIndexSeries()[0:4] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` @@ -643,7 +643,7 @@ def LogarithmCycleIndexSeries(R = RationalField()): multiplicative identity `X`):: sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries()(Eplus)[:4] + sage: LogarithmCycleIndexSeries()(Eplus)[0:4] [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R) From 2a3389e6ae2c5be15a44f52d4b2fb339e63bc827 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 00:03:57 +0200 Subject: [PATCH 089/350] compute no more elements than necessary in __getitem__ --- src/sage/rings/lazy_series.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 2f07f6c28c5..c124297edcd 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -304,13 +304,31 @@ def __getitem__(self, n): sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: L(lambda n: n)[1:11] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + TESTS: + + Check that no more elements than necessary are computed:: + + sage: L = LazyDirichletSeriesRing(ZZ, "z") + sage: f = L(lambda n: 0 if n < 5 else n) + sage: f[:3] + [] + sage: f._coeff_stream._cache + {1: 0, 2: 0} """ R = self.parent()._internal_poly_ring.base_ring() + coeff_stream = self._coeff_stream if isinstance(n, slice): if n.start is None: # WARNING: for Dirichlet series, 'degree' and # valuation are different - start = self._coeff_stream.order() + if n.stop is None: + start = coeff_stream.order() + else: + start = coeff_stream._approximate_order + while start < n.stop and not coeff_stream[start]: + start += 1 + coeff_stream._approximate_order = start else: start = n.start step = n.step if n.step is not None else 1 From f7d7c4e1cd2f7d5218471e34b3535549363864cf Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 00:19:55 +0200 Subject: [PATCH 090/350] adapt doctests --- src/sage/rings/lazy_series.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index b4caa0fed53..c74fd3d6a48 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3799,13 +3799,14 @@ def _im_gens_(self, codomain, im_gens, base_map=None): sage: f = 1/(1-q-t) sage: f 1 + (q+t) + (q^2+2*q*t+t^2) + (q^3+3*q^2*t+3*q*t^2+t^3) + (q^4+4*q^3*t+6*q^2*t^2+4*q*t^3+t^4) + (q^5+5*q^4*t+10*q^3*t^2+10*q^2*t^3+5*q*t^4+t^5) + (q^6+6*q^5*t+15*q^4*t^2+20*q^3*t^3+15*q^2*t^4+6*q*t^5+t^6) + O(q,t)^7 - sage: S. = LazyPowerSeriesRing(Z) - sage: f._im_gens_(S, [t, x*t]) - 1 + ((x+1)*t) + ((x^2+2*x+1)*t^2) + ((x^3+3*x^2+3*x+1)*t^3) + ((x^4+4*x^3+6*x^2+4*x+1)*t^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*t^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*t^6) + O(t^7) + sage: S. = LazyPowerSeriesRing(Z) + sage: f._im_gens_(S, [s, x*s]) + 1 + ((x+1)*s) + ((x^2+2*x+1)*s^2) + ((x^3+3*x^2+3*x+1)*s^3) + ((x^4+4*x^3+6*x^2+4*x+1)*s^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*s^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*s^6) + O(s^7) sage: cc = Z.hom([-x]) - sage: f._im_gens_(S, [t, t], base_map=cc) - + sage: f = 1/(1+x*q-t) + sage: f._im_gens_(S, [s, x*s], base_map=cc) + 1 + 2*x*s + 4*x^2*s^2 + 8*x^3*s^3 + 16*x^4*s^4 + 32*x^5*s^5 + 64*x^6*s^6 + O(s^7) """ if base_map is None: return codomain(self(*im_gens)) From 89d9cccd0e5db988005e3503f86efd7283fea038 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 12:09:52 +0200 Subject: [PATCH 091/350] fix pyflakes warnings --- src/sage/combinat/species/composition_species.py | 2 +- src/sage/combinat/species/cycle_species.py | 1 - src/sage/combinat/species/generating_series.py | 3 +-- src/sage/combinat/species/permutation_species.py | 1 - src/sage/rings/lazy_series.py | 3 ++- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index 9050b8d89f0..9e80e25c00f 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -62,7 +62,7 @@ def transport(self, perm): f, gs = self._list pi = self._partition.transport(perm) f = f.change_labels(pi._list) - g = [g.change_labels(part) for g, part in zip(gs, pi)] # BUG HERE ? + _ = [g.change_labels(part) for g, part in zip(gs, pi)] # TODO: BUG HERE ? return self.__class__(self, self._labels, pi, f, gs) def change_labels(self, labels): diff --git a/src/sage/combinat/species/cycle_species.py b/src/sage/combinat/species/cycle_species.py index 0e82416b54f..7878a028265 100644 --- a/src/sage/combinat/species/cycle_species.py +++ b/src/sage/combinat/species/cycle_species.py @@ -15,7 +15,6 @@ from .species import GenericCombinatorialSpecies from .structure import GenericSpeciesStructure from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.integer_ring import ZZ from sage.arith.all import divisors, euler_phi from sage.combinat.species.misc import accept_size diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 5125695da91..6fd835912b6 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -53,9 +53,8 @@ from sage.rings.lazy_series_ring import LazyPowerSeriesRing, LazySymmetricFunctions from sage.rings.integer import Integer from sage.rings.rational_field import RationalField -from sage.arith.all import moebius, gcd, lcm, divisors +from sage.arith.all import divisors from sage.combinat.partition import Partition, Partitions -from functools import partial from sage.combinat.sf.sf import SymmetricFunctions from sage.misc.cachefunc import cached_function from sage.arith.misc import factorial diff --git a/src/sage/combinat/species/permutation_species.py b/src/sage/combinat/species/permutation_species.py index f6471e0e66e..a1a4b362f8e 100644 --- a/src/sage/combinat/species/permutation_species.py +++ b/src/sage/combinat/species/permutation_species.py @@ -19,7 +19,6 @@ from .species import GenericCombinatorialSpecies from .structure import GenericSpeciesStructure from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.integer_ring import ZZ from sage.combinat.permutation import Permutation, Permutations from sage.combinat.species.misc import accept_size diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index c124297edcd..fdd9d448bac 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -4855,7 +4855,8 @@ def derivative_with_respect_to_p1(self, n=1): return P.element_class(P, coeff_stream) def functorial_composition(self, *args): - r"""Return the functorial composition of ``self`` and ``g``. + r""" + Return the functorial composition of ``self`` and ``g``. Let `X` be a finite set of cardinality `m`. For a group action of the symmetric group `g: S_n \to S_X` and a From cf2b0cb9456298c279d7270d4c44e208929370e4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 14:58:06 +0200 Subject: [PATCH 092/350] require a graded basis --- src/sage/rings/lazy_series_ring.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 98e40a41c8f..8c1b7578a8d 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -38,6 +38,7 @@ from sage.structure.element import parent from sage.categories.algebras import Algebras +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.rings import Rings from sage.categories.integral_domains import IntegralDomains from sage.categories.fields import Fields @@ -1572,14 +1573,22 @@ def __init__(self, basis, sparse=True, category=None): sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + Check that a basis which is not graded is not enough:: + + sage: ht = SymmetricFunctions(ZZ).ht() + sage: L = LazySymmetricFunctions(ht) + Traceback (most recent call last): + ... + ValueError: basis should be in GradedAlgebrasWithBasis """ base_ring = basis.base_ring() self._minimal_valuation = 0 if basis in Algebras.TensorProducts: self._arity = len(basis._sets) else: - if basis not in Algebras.Graded: - raise ValueError("basis should be a graded algebra") + if basis not in GradedAlgebrasWithBasis: + raise ValueError("basis should be in GradedAlgebrasWithBasis") self._arity = 1 category = Algebras(base_ring.category()) if base_ring in Fields(): From 3bd9f8c26726786ff40db79486a1cb0b3cd58b00 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 13 Sep 2022 23:54:42 +0900 Subject: [PATCH 093/350] Fixing coefficients bug and some doc tweaks. --- src/sage/rings/lazy_series.py | 88 ++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index fdd9d448bac..920fce1c683 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -245,7 +245,6 @@ def __init__(self, parent, coeff_stream): sage: L = LazyDirichletSeriesRing(QQbar, 'z') sage: g = L(constant=1) sage: TestSuite(g).run() - """ Element.__init__(self, parent) self._coeff_stream = coeff_stream @@ -348,8 +347,7 @@ def coefficients(self, n=None): INPUT: - - ``n`` -- (default: ``None``), the number of non-zero - coefficients to return. + - ``n`` -- (optional) the number of non-zero coefficients to return If the series has fewer than `n` non-zero coefficients, only these are returned. @@ -384,6 +382,10 @@ def coefficients(self, n=None): sage: f.coefficients() lazy list [1, 1, -1/6, ...] + sage: L. = LazyPowerSeriesRing(GF(2)) + sage: f = L(lambda n: n) + sage: f.coefficients(5) + [1, 1, 1, 1, 1] """ coeff_stream = self._coeff_stream if isinstance(coeff_stream, Stream_zero): @@ -391,18 +393,20 @@ def coefficients(self, n=None): from itertools import repeat, chain, islice from sage.misc.lazy_list import lazy_list # prepare a generator of the non-zero coefficients + P = self.parent() + R = P.base_ring() if isinstance(coeff_stream, Stream_exact): if coeff_stream._constant: - coeffs = chain([c for c in coeff_stream._initial_coefficients if c], + coeffs = chain((c for c in coeff_stream._initial_coefficients if c), repeat(coeff_stream._constant)) else: coeffs = (c for c in coeff_stream._initial_coefficients if c) else: - coeffs = filter(lambda c: c, coeff_stream.iterate_coefficients()) + coeffs = filter(bool, coeff_stream.iterate_coefficients()) if n is None: - if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): - return lazy_list(coeffs) + if P._internal_poly_ring.base_ring() is not P._laurent_poly_ring: + return lazy_list(filter(bool, map(R, coeffs))) # flatten out the generator in the multivariate case return lazy_list(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs))) @@ -411,8 +415,8 @@ def coefficients(self, n=None): from sage.misc.superseded import deprecation deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') - if self.base_ring() == self.parent()._internal_poly_ring.base_ring(): - return list(islice(coeffs, n)) + if P._internal_poly_ring.base_ring() is not P._laurent_poly_ring: + return list(islice(filter(bool, map(R, coeffs)), n)) # flatten out the generator in the multivariate case return list(islice(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs)), n)) @@ -447,22 +451,32 @@ def map_coefficients(self, f): sage: L. = LazyPowerSeriesRing(QQ) sage: f = 1/(1-(x+y)); f - 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 + 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + + O(x,y)^7 sage: f.map_coefficients(lambda c: c^2) - 1 + (x+y) + (x^2+4*x*y+y^2) + (x^3+9*x^2*y+9*x*y^2+y^3) + (x^4+16*x^3*y+36*x^2*y^2+16*x*y^3+y^4) + (x^5+25*x^4*y+100*x^3*y^2+100*x^2*y^3+25*x*y^4+y^5) + (x^6+36*x^5*y+225*x^4*y^2+400*x^3*y^3+225*x^2*y^4+36*x*y^5+y^6) + O(x,y)^7 + 1 + (x+y) + (x^2+4*x*y+y^2) + (x^3+9*x^2*y+9*x*y^2+y^3) + + (x^4+16*x^3*y+36*x^2*y^2+16*x*y^3+y^4) + + (x^5+25*x^4*y+100*x^3*y^2+100*x^2*y^3+25*x*y^4+y^5) + + (x^6+36*x^5*y+225*x^4*y^2+400*x^3*y^3+225*x^2*y^4+36*x*y^5+y^6) + + O(x,y)^7 Similarly for lazy symmetric functions:: sage: p = SymmetricFunctions(QQ).p() sage: L = LazySymmetricFunctions(p) sage: f = 1/(1-2*L(p[1])); f - p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 + p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 sage: f.map_coefficients(lambda c: log(c, 2)) - p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7 + p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7 TESTS: - Dense Implementation:: + Dense implementation:: sage: L. = LazyLaurentSeriesRing(ZZ, sparse=False) sage: s = z/(1 - 2*z^2) @@ -497,10 +511,10 @@ def map_coefficients(self, f): if isinstance(coeff_stream, Stream_zero): return self R = P._internal_poly_ring.base_ring() - if P.base_ring() == R: - func = f - else: + if R is P._laurent_poly_ring: func = lambda c: R(c).map_coefficients(f) + else: + func = f if isinstance(coeff_stream, Stream_exact): initial_coefficients = [func(i) if i else 0 for i in coeff_stream._initial_coefficients] @@ -526,7 +540,7 @@ def truncate(self, d): EXAMPLES: - Dense Implementation:: + Dense implementation:: sage: L. = LazyLaurentSeriesRing(ZZ, sparse=False) sage: alpha = 1/(1-z) @@ -4204,9 +4218,18 @@ def derivative(self, *args): sage: R. = QQ[] sage: L. = LazyPowerSeriesRing(R) sage: f = 1/(1-q*x+y); f - 1 + (q*x-y) + (q^2*x^2+(-2*q)*x*y+y^2) + (q^3*x^3+(-3*q^2)*x^2*y+3*q*x*y^2-y^3) + (q^4*x^4+(-4*q^3)*x^3*y+6*q^2*x^2*y^2+(-4*q)*x*y^3+y^4) + (q^5*x^5+(-5*q^4)*x^4*y+10*q^3*x^3*y^2+(-10*q^2)*x^2*y^3+5*q*x*y^4-y^5) + (q^6*x^6+(-6*q^5)*x^5*y+15*q^4*x^4*y^2+(-20*q^3)*x^3*y^3+15*q^2*x^2*y^4+(-6*q)*x*y^5+y^6) + O(x,y)^7 + 1 + (q*x-y) + (q^2*x^2+(-2*q)*x*y+y^2) + + (q^3*x^3+(-3*q^2)*x^2*y+3*q*x*y^2-y^3) + + (q^4*x^4+(-4*q^3)*x^3*y+6*q^2*x^2*y^2+(-4*q)*x*y^3+y^4) + + (q^5*x^5+(-5*q^4)*x^4*y+10*q^3*x^3*y^2+(-10*q^2)*x^2*y^3+5*q*x*y^4-y^5) + + (q^6*x^6+(-6*q^5)*x^5*y+15*q^4*x^4*y^2+(-20*q^3)*x^3*y^3+15*q^2*x^2*y^4+(-6*q)*x*y^5+y^6) + + O(x,y)^7 sage: f.derivative(q) - x + (2*q*x^2+(-2)*x*y) + (3*q^2*x^3+(-6*q)*x^2*y+3*x*y^2) + (4*q^3*x^4+(-12*q^2)*x^3*y+12*q*x^2*y^2+(-4)*x*y^3) + (5*q^4*x^5+(-20*q^3)*x^4*y+30*q^2*x^3*y^2+(-20*q)*x^2*y^3+5*x*y^4) + (6*q^5*x^6+(-30*q^4)*x^5*y+60*q^3*x^4*y^2+(-60*q^2)*x^3*y^3+30*q*x^2*y^4+(-6)*x*y^5) + O(x,y)^7 + x + (2*q*x^2+(-2)*x*y) + (3*q^2*x^3+(-6*q)*x^2*y+3*x*y^2) + + (4*q^3*x^4+(-12*q^2)*x^3*y+12*q*x^2*y^2+(-4)*x*y^3) + + (5*q^4*x^5+(-20*q^3)*x^4*y+30*q^2*x^3*y^2+(-20*q)*x^2*y^3+5*x*y^4) + + (6*q^5*x^6+(-30*q^4)*x^5*y+60*q^3*x^4*y^2+(-60*q^2)*x^3*y^3+30*q*x^2*y^4+(-6)*x*y^5) + + O(x,y)^7 """ P = self.parent() @@ -4273,7 +4296,9 @@ def _format_series(self, formatter, format_strings=False): sage: L. = LazyPowerSeriesRing(QQ) sage: f = 1 / (2 - x^2 + y) sage: f._format_series(repr) - '1/2 + (-1/4*y) + (1/4*x^2+1/8*y^2) + (-1/4*x^2*y-1/16*y^3) + (1/8*x^4+3/16*x^2*y^2+1/32*y^4) + (-3/16*x^4*y-1/8*x^2*y^3-1/64*y^5) + (1/16*x^6+3/16*x^4*y^2+5/64*x^2*y^4+1/128*y^6) + O(x,y)^7' + '1/2 + (-1/4*y) + (1/4*x^2+1/8*y^2) + (-1/4*x^2*y-1/16*y^3) + + (1/8*x^4+3/16*x^2*y^2+1/32*y^4) + (-3/16*x^4*y-1/8*x^2*y^3-1/64*y^5) + + (1/16*x^6+3/16*x^4*y^2+5/64*x^2*y^4+1/128*y^6) + O(x,y)^7' sage: f = (2 - x^2 + y) sage: f._format_series(repr) @@ -4524,7 +4549,7 @@ def __call__(self, *args, check=True): .. TODO:: - allow specification of degree one elements + Allow specification of degree one elements. EXAMPLES:: @@ -4574,9 +4599,15 @@ def __call__(self, *args, check=True): sage: H = S(lambda n: s[n]) sage: H(S2(X*Y)) - (s[]#s[]) + (s[1]#s[1]) + (s[1,1]#s[1,1]+s[2]#s[2]) + (s[1,1,1]#s[1,1,1]+s[2,1]#s[2,1]+s[3]#s[3]) + O^7 + (s[]#s[]) + (s[1]#s[1]) + (s[1,1]#s[1,1]+s[2]#s[2]) + + (s[1,1,1]#s[1,1,1]+s[2,1]#s[2,1]+s[3]#s[3]) + O^7 sage: H(S2(X+Y)) - (s[]#s[]) + (s[]#s[1]+s[1]#s[]) + (s[]#s[2]+s[1]#s[1]+s[2]#s[]) + (s[]#s[3]+s[1]#s[2]+s[2]#s[1]+s[3]#s[]) + (s[]#s[4]+s[1]#s[3]+s[2]#s[2]+s[3]#s[1]+s[4]#s[]) + (s[]#s[5]+s[1]#s[4]+s[2]#s[3]+s[3]#s[2]+s[4]#s[1]+s[5]#s[]) + (s[]#s[6]+s[1]#s[5]+s[2]#s[4]+s[3]#s[3]+s[4]#s[2]+s[5]#s[1]+s[6]#s[]) + O^7 + (s[]#s[]) + (s[]#s[1]+s[1]#s[]) + (s[]#s[2]+s[1]#s[1]+s[2]#s[]) + + (s[]#s[3]+s[1]#s[2]+s[2]#s[1]+s[3]#s[]) + + (s[]#s[4]+s[1]#s[3]+s[2]#s[2]+s[3]#s[1]+s[4]#s[]) + + (s[]#s[5]+s[1]#s[4]+s[2]#s[3]+s[3]#s[2]+s[4]#s[1]+s[5]#s[]) + + (s[]#s[6]+s[1]#s[5]+s[2]#s[4]+s[3]#s[3]+s[4]#s[2]+s[5]#s[1]+s[6]#s[]) + + O^7 TESTS:: @@ -4734,7 +4765,12 @@ def revert(self): sage: f = L(2*p[1] + p[2] + p[1,1]) sage: f.revert() - 1/2*p[1] + (-1/4*p[1,1]-1/2*p[2]) + (1/4*p[1,1,1]+1/2*p[2,1]) + (-5/16*p[1,1,1,1]-3/4*p[2,1,1]+1/2*p[4]) + (7/16*p[1,1,1,1,1]+5/4*p[2,1,1,1]+1/2*p[2,2,1]-1/2*p[4,1]) + (-21/32*p[1,1,1,1,1,1]-35/16*p[2,1,1,1,1]-3/2*p[2,2,1,1]-1/4*p[2,2,2]+3/4*p[4,1,1]) + (33/32*p[1,1,1,1,1,1,1]+63/16*p[2,1,1,1,1,1]+15/4*p[2,2,1,1,1]+3/4*p[2,2,2,1]-5/4*p[4,1,1,1]-p[4,2,1]) + O^8 + 1/2*p[1] + (-1/4*p[1,1]-1/2*p[2]) + (1/4*p[1,1,1]+1/2*p[2,1]) + + (-5/16*p[1,1,1,1]-3/4*p[2,1,1]+1/2*p[4]) + + (7/16*p[1,1,1,1,1]+5/4*p[2,1,1,1]+1/2*p[2,2,1]-1/2*p[4,1]) + + (-21/32*p[1,1,1,1,1,1]-35/16*p[2,1,1,1,1]-3/2*p[2,2,1,1]-1/4*p[2,2,2]+3/4*p[4,1,1]) + + (33/32*p[1,1,1,1,1,1,1]+63/16*p[2,1,1,1,1,1]+15/4*p[2,2,1,1,1]+3/4*p[2,2,2,1]-5/4*p[4,1,1,1]-p[4,2,1]) + + O^8 ALGORITHM: @@ -4939,7 +4975,7 @@ def functorial_composition(self, *args): sage: F2 = L(lambda n: e[n]) sage: f1 = F1.functorial_composition(f) sage: f2 = F2.functorial_composition(f) - sage: (F1 + F2).functorial_composition(f) - f1 - f2 + sage: (F1 + F2).functorial_composition(f) - f1 - f2 # long time O^7 TESTS: From 555d1b07df4f0ba82f23392142037114c03cd0e9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 21:54:58 +0200 Subject: [PATCH 094/350] fix LazyPowerSeries._element_constructor_ when passed a function --- src/sage/rings/lazy_series.py | 57 ++++++++++++++++++++++++++++-- src/sage/rings/lazy_series_ring.py | 2 +- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 920fce1c683..e114c599b81 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -100,7 +100,11 @@ sage: hinv.valuation() -1 -TESTS:: +TESTS: + +We check that -- at least for some simple cases -- division, +composition and reversion do not raise exceptions for univariate lazy +Laurent series, lazy power series and lazy symmetric functions:: sage: def check(L, z, verbose=False): ....: # division @@ -144,6 +148,53 @@ sage: p = SymmetricFunctions(QQ).p() sage: L = LazySymmetricFunctions(p) sage: check(L, L(p[1])) + +We check that the elements in the cache of the stream of homogeneous +components are in the correct ring:: + + sage: def check(L, x, valuation, verbose=False): + ....: f = L(x, valuation=valuation) + ....: _ = f[2], f[5] + ....: if callable(x): + ....: assert len(f._coeff_stream._cache) == 2, "the cache is %s" % f._coeff_stream._cache + ....: else: + ....: m = 6 if valuation is None else 5 - valuation + 1 + ....: assert len(f._coeff_stream._cache) == m, "the cache is %s" % f._coeff_stream._cache + ....: P = f._coeff_stream._cache[2].parent() + ....: assert P is L._internal_poly_ring.base_ring(), "the cache is in %s" % P + ....: if verbose: + ....: print(P) + + sage: def gen(): + ....: n = 0 + ....: while True: + ....: yield n + ....: n += 1 + + sage: L. = LazyLaurentSeriesRing(GF(2)) + sage: check(L, lambda n: n, valuation=-5) + sage: check(L, gen(), valuation=-5) + + sage: L = LazyDirichletSeriesRing(QQbar, "s") + sage: check(L, lambda n: n, valuation=2) + sage: check(L, gen(), valuation=2) + + sage: L. = LazyPowerSeriesRing(GF(2)) + sage: check(L, lambda n: n, valuation=0) + sage: check(L, gen(), valuation=0) + + sage: L. = LazyPowerSeriesRing(GF(2)) + sage: check(L, lambda n: (x + y)^n, valuation=None) + sage: def gen(): + ....: n = 0 + ....: while True: + ....: yield (x+y)^n + ....: n += 1 + sage: check(L, gen(), valuation=None) + + sage: s = SymmetricFunctions(GF(2)).s() + sage: L = LazySymmetricFunctions(s) + sage: check(L, lambda n: sum(k*s(la) for k, la in enumerate(Partitions(n))), valuation=0) """ # **************************************************************************** @@ -406,7 +457,7 @@ def coefficients(self, n=None): if n is None: if P._internal_poly_ring.base_ring() is not P._laurent_poly_ring: - return lazy_list(filter(bool, map(R, coeffs))) + return lazy_list(coeffs) # flatten out the generator in the multivariate case return lazy_list(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs))) @@ -416,7 +467,7 @@ def coefficients(self, n=None): deprecation(32367, 'the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead.') if P._internal_poly_ring.base_ring() is not P._laurent_poly_ring: - return list(islice(filter(bool, map(R, coeffs)), n)) + return list(islice(coeffs, n)) # flatten out the generator in the multivariate case return list(islice(chain.from_iterable(map(lambda coeff: coeff.coefficients(), coeffs)), n)) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 8c1b7578a8d..ad332222c32 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1496,7 +1496,7 @@ def y(n): coeff_stream = Stream_iterator(map(R, _skip_leading_zeros(x)), valuation) else: if callable(x): - coeff_stream = Stream_function(x, self._sparse, valuation) + coeff_stream = Stream_function(lambda i: BR(x(i)), self._sparse, valuation) else: coeff_stream = Stream_iterator(map(BR, _skip_leading_zeros(x)), valuation) return self.element_class(self, coeff_stream) From baea68dbd79e0a0774f2763c12aa776a01a5f0c5 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 14 Sep 2022 08:57:52 +0200 Subject: [PATCH 095/350] pass functions using coefficients to element constructor --- src/sage/rings/lazy_series.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index e114c599b81..82fdf399e96 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1681,10 +1681,17 @@ def exp(self): sage: L. = LazyLaurentSeriesRing(QQ); x = var("x") sage: exp(z)[0:6] == exp(x).series(x, 6).coefficients(sparse=False) True + + Check the exponential when the base ring is a lazy ring:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: M. = LazyPowerSeriesRing(L) + sage: exp(x) + 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: 1/factorial(ZZ(n)), valuation=0) + f = P(coefficients=lambda n: 1/factorial(ZZ(n)), valuation=0) return f(self) def log(self): @@ -1714,7 +1721,7 @@ def log(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: ((-1) ** (n + 1))/ZZ(n), valuation=1) + f = P(coefficients=lambda n: ((-1) ** (n + 1))/ZZ(n), valuation=1) return f(self-1) # trigonometric functions @@ -1746,8 +1753,8 @@ def sin(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: (n % 2)/factorial(ZZ(n)) if n % 4 == 1 else -(n % 2)/factorial(ZZ(n)), - valuation=1) + c = lambda n: (n % 2)/factorial(ZZ(n)) if n % 4 == 1 else -(n % 2)/factorial(ZZ(n)) + f = P(coefficients=c, valuation=1) return f(self) def cos(self): @@ -1772,8 +1779,8 @@ def cos(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: 1/factorial(ZZ(n)) if n % 4 == 0 else (n % 2 - 1)/factorial(ZZ(n)), - valuation=0) + c = lambda n: 1/factorial(ZZ(n)) if n % 4 == 0 else (n % 2 - 1)/factorial(ZZ(n)) + f = P(coefficients=c, valuation=0) return f(self) def tan(self): @@ -2017,7 +2024,7 @@ def sinh(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: 1/factorial(ZZ(n)) if n % 2 else ZZ.zero(), + f = P(coefficients=lambda n: 1/factorial(ZZ(n)) if n % 2 else ZZ.zero(), valuation=1) return f(self) @@ -2044,7 +2051,7 @@ def cosh(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: ZZ.zero() if n % 2 else 1/factorial(ZZ(n)), + f = P(coefficients=lambda n: ZZ.zero() if n % 2 else 1/factorial(ZZ(n)), valuation=0) return f(self) @@ -2243,7 +2250,7 @@ def arctanh(self): """ from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - f = P(lambda n: 1/ZZ(n) if n % 2 else ZZ.zero(), valuation=1) + f = P(coefficients=lambda n: 1/ZZ(n) if n % 2 else ZZ.zero(), valuation=1) return f(self) def hypergeometric(self, a, b): @@ -2285,7 +2292,7 @@ def coeff(n, c): for term in range(len(c)): num *= rising_factorial(c[term], n) return num - f = P(lambda n: coeff(n, a) / (coeff(n, b) * factorial(ZZ(n))), + f = P(coefficients=lambda n: coeff(n, a) / (coeff(n, b) * factorial(ZZ(n))), valuation=0) return f(self) @@ -2318,7 +2325,7 @@ def __pow__(self, n): from .lazy_series_ring import LazyLaurentSeriesRing P = LazyLaurentSeriesRing(self.base_ring(), "z", sparse=self.parent()._sparse) - exp = P(lambda k: 1/factorial(ZZ(k)), valuation=0) + exp = P(coefficients=lambda k: 1/factorial(ZZ(k)), valuation=0) return exp(self.log() * n) def sqrt(self): From 7745337b260ad2e37c1c30b04756606e0e775610 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 14 Sep 2022 14:53:07 +0200 Subject: [PATCH 096/350] remove unused variable detected by pyflakes --- src/sage/rings/lazy_series.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 82fdf399e96..f463243b2c1 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -445,7 +445,6 @@ def coefficients(self, n=None): from sage.misc.lazy_list import lazy_list # prepare a generator of the non-zero coefficients P = self.parent() - R = P.base_ring() if isinstance(coeff_stream, Stream_exact): if coeff_stream._constant: coeffs = chain((c for c in coeff_stream._initial_coefficients if c), From cdad494f9eb5f409f987301f4a8fd073c846f1b2 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 15 Sep 2022 09:35:53 +0200 Subject: [PATCH 097/350] do not advertise L(None) in favour of L.define() --- src/sage/data_structures/stream.py | 3 +- src/sage/rings/lazy_series.py | 85 +++++++++++++++++------------- src/sage/rings/lazy_series_ring.py | 61 +++++++++++++-------- 3 files changed, 91 insertions(+), 58 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index a8118dd4746..0b0c1aa9d87 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -864,7 +864,8 @@ def __init__(self, is_sparse, approximate_order): sage: TestSuite(C).run(skip="_test_pickling") """ self._target = None - assert approximate_order is not None, "calling Stream_uninitialized with None as approximate order" + if approximate_order is None: + raise ValueError("the valuation must be specified for undefined series") super().__init__(is_sparse, approximate_order) def get_coefficient(self, n): diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index f463243b2c1..4e2f35f2c3b 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -856,21 +856,21 @@ def __bool__(self): Uninitialized series:: - sage: g = L(None, valuation=0) + sage: g = L.undefined(valuation=0) sage: bool(g) True sage: g.define(0) sage: bool(g) False - sage: g = L(None, valuation=0) + sage: g = L.undefined(valuation=0) sage: bool(g) True sage: g.define(1 + z) sage: bool(g) True - sage: g = L(None, valuation=0) + sage: g = L.undefined(valuation=0) sage: bool(g) True sage: g.define(1 + z*g) @@ -911,23 +911,23 @@ def define(self, s): We begin by constructing the Catalan numbers:: - sage: L. = LazyLaurentSeriesRing(ZZ) - sage: C = L(None, valuation=0) + sage: L. = LazyPowerSeriesRing(ZZ) + sage: C = L.undefined() sage: C.define(1 + z*C^2) sage: C 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) The Catalan numbers but with a valuation 1:: - sage: B = L(None, valuation=1) + sage: B = L.undefined(valuation=1) sage: B.define(z + B^2) sage: B z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) We can define multiple series that are linked:: - sage: s = L(None, valuation=0) - sage: t = L(None, valuation=0) + sage: s = L.undefined() + sage: t = L.undefined() sage: s.define(1 + z*t^3) sage: t.define(1 + z*s^2) sage: s[0:9] @@ -937,10 +937,10 @@ def define(self, s): A bigger example:: - sage: L. = LazyLaurentSeriesRing(ZZ) - sage: A = L(None, valuation=5) - sage: B = L(None, valuation=0) - sage: C = L(None, valuation=2) + sage: L. = LazyPowerSeriesRing(ZZ) + sage: A = L.undefined(valuation=5) + sage: B = L.undefined() + sage: C = L.undefined(valuation=2) sage: A.define(z^5 + B^2) sage: B.define(z^5 + C^2) sage: C.define(z^2 + C^2 + A^2) @@ -953,8 +953,8 @@ def define(self, s): Counting binary trees:: - sage: L. = LazyLaurentSeriesRing(QQ) - sage: s = L(None, valuation=1) + sage: L. = LazyPowerSeriesRing(QQ) + sage: s = L.undefined(valuation=1) sage: s.define(z + (s^2+s(z^2))/2) sage: s[0:9] [0, 1, 1, 1, 2, 3, 6, 11, 23] @@ -963,7 +963,7 @@ def define(self, s): sage: R. = ZZ[] sage: L. = LazyLaurentSeriesRing(R) - sage: s = L(None, valuation=0) + sage: s = L.undefined(valuation=0) sage: s.define(1+z*s*s(q*z)) sage: s 1 + z + (q + 1)*z^2 + (q^3 + q^2 + 2*q + 1)*z^3 @@ -976,11 +976,11 @@ def define(self, s): and number of internal nodes:: sage: R. = QQ[] - sage: Q. = LazyLaurentSeriesRing(R) + sage: Q. = LazyPowerSeriesRing(R) sage: leaf = z sage: internal_node = q * z sage: L = Q(constant=1, degree=1) - sage: T = Q(None, valuation=1) + sage: T = Q.undefined(valuation=1) sage: T.define(leaf + internal_node * L(T)) sage: T[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q] @@ -989,7 +989,8 @@ def define(self, s): sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: g = L(constant=1, valuation=2) - sage: F = L(None); F.define(1 + g*F) + sage: F = L.undefined() + sage: F.define(1 + g*F) sage: F[:16] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] sage: oeis(_) # optional, internet @@ -997,7 +998,8 @@ def define(self, s): 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... - sage: F = L(None); F.define(1 + g*F*F) + sage: F = L.undefined() + sage: F.define(1 + g*F*F) sage: F[:16] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5] @@ -1008,7 +1010,8 @@ def define(self, s): sage: L = LazySymmetricFunctions(m) sage: E = L(lambda n: s[n], valuation=0) sage: X = L(s[1]) - sage: A = L(None); A.define(X*E(A, check=False)) + sage: A = L.undefined() + sage: A.define(X*E(A, check=False)) sage: A[:6] [m[1], 2*m[1, 1] + m[2], @@ -1019,12 +1022,12 @@ def define(self, s): TESTS:: sage: L. = LazyLaurentSeriesRing(ZZ, sparse=True) - sage: s = L(None, valuation=0) - sage: s.define(1 + z*s^3) - sage: s[0:10] + sage: s = L.undefined(valuation=-1) + sage: s.define(z^-1 + z^3*s^3) + sage: s[-1:9] [1, 1, 3, 12, 55, 273, 1428, 7752, 43263, 246675] - sage: e = L(None, valuation=0) + sage: e = L.undefined(valuation=0) sage: e.define(1 + z*e) sage: e.define(1 + z*e) Traceback (most recent call last): @@ -1035,12 +1038,12 @@ def define(self, s): ... ValueError: series already defined - sage: e = L(None, valuation=0) + sage: e = L.undefined(valuation=0) sage: e.define(1) sage: e 1 - sage: e = L(None, valuation=0) + sage: e = L.undefined(valuation=0) sage: e.define((1 + z).polynomial()) sage: e 1 + z @@ -1048,11 +1051,21 @@ def define(self, s): sage: D = LazyDirichletSeriesRing(QQ, "s") sage: L. = LazyLaurentSeriesRing(QQ) sage: e = L(lambda n: 1/factorial(n), 0) - sage: g = D(None, valuation=2) + sage: g = D.undefined(valuation=2) sage: o = D(constant=1, valuation=2) sage: g.define(o * e(g)) sage: g 1/(2^s) + 1/(3^s) + 2/4^s + 1/(5^s) + 3/6^s + 1/(7^s) + 9/2/8^s + O(1/(9^s)) + + For Laurent series there is no minimal valuation, so it has + to be specified:: + + sage: L. = LazyLaurentSeriesRing(QQ) + sage: L.undefined() + Traceback (most recent call last): + ... + ValueError: the valuation must be specified for undefined series + """ if not isinstance(self._coeff_stream, Stream_uninitialized) or self._coeff_stream._target is not None: raise ValueError("series already defined") @@ -1098,7 +1111,7 @@ def _repr_(self): sage: L(lambda x: x if x > 0 else 0, valuation=-10) O(z^-3) - sage: L(None, valuation=0) + sage: L.undefined(valuation=0) Uninitialized Lazy Laurent Series sage: L(0) 0 @@ -1145,7 +1158,7 @@ def _latex_(self): sage: latex(L(lambda x: x if x > 0 else 0, valuation=-10)) O(\frac{1}{z^{3}}) - sage: latex(L(None, valuation=0)) + sage: latex(L.undefined(valuation=0)) \text{\texttt{Undef}} sage: latex(L(0)) 0 @@ -3202,7 +3215,7 @@ def __call__(self, g, *, check=True): sage: L. = LazyLaurentSeriesRing(QQ) sage: f = 1 + z - sage: g = L(None, valuation=0) + sage: g = L.undefined(valuation=0) sage: f(g) == f.polynomial()(g) True """ @@ -3496,7 +3509,7 @@ def revert(self): raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() - g = P(None, valuation=1) + g = P.undefined(valuation=1) g.define(z / ((self / z)(g))) return g @@ -3969,15 +3982,15 @@ def __call__(self, *g, check=True): sage: L. = LazyPowerSeriesRing(QQ) sage: f = 1 - z - sage: g = L(None, valuation=1) + sage: g = L.undefined(valuation=1) sage: f(g) == f.polynomial()(g) True - sage: g = L(None, valuation=1) + sage: g = L.undefined(valuation=1) sage: g.define(z / (1 - g)) sage: g z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) - sage: gp = L(None, valuation=1) + sage: gp = L.undefined(valuation=1) sage: gp.define(z / f(gp)) sage: gp z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) @@ -4247,7 +4260,7 @@ def revert(self): raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() - g = P(None, valuation=1) + g = P.undefined(valuation=1) g.define(z / ((self / z)(g))) return g @@ -4882,7 +4895,7 @@ def revert(self): X = R(Partition([1])) b = coeff_stream[1][Partition([1])] - g = P(None, valuation=1) + g = P.undefined(valuation=1) g.define(~b * X - (self - b * X)(g)) return g diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ad332222c32..5ebfd5c6e4a 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -119,7 +119,10 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No coefficients when evaluated at integers. Examples are provided below. - EXAMPLES:: + EXAMPLES: + + If ``x`` can be converted into an element of the underlying + Laurent polynomial ring, we do this:: sage: L = LazyLaurentSeriesRing(GF(2), 'z') sage: L(2) @@ -127,18 +130,29 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: L(3) 1 - sage: L. = LazyLaurentSeriesRing(ZZ) + In particular, ``x`` can be a Laurent polynomial:: + sage: P. = LaurentPolynomialRing(QQ) + sage: p = x^-2 + 3*x^3 + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: L(p) + x^-2 + 3*x^3 + + sage: L(p, valuation=0) + 1 + 3*x^5 + + sage: L(p, valuation=1) + x + 3*x^6 + + If ``x`` is callable, its evaluation at the integers, + beginning at ``valuation``, defines the coefficients of the series:: + + sage: L. = LazyLaurentSeriesRing(ZZ) sage: L(lambda i: i, valuation=5, constant=1, degree=10) 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13) sage: L(lambda i: i, valuation=5, constant=(1, 10)) 5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13) - sage: X = L(constant=5, degree=2); X - 5*z^2 + 5*z^3 + 5*z^4 + O(z^5) - sage: X.valuation() - 2 - sage: def g(i): ....: if i < 0: ....: return 1 @@ -155,6 +169,13 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: f[30] -219 + We can omit ``x``, when defining a series with constant coefficients:: + + sage: X = L(constant=5, degree=2); X + 5*z^2 + 5*z^3 + 5*z^4 + O(z^5) + sage: X.valuation() + 2 + sage: L(valuation=2, constant=1) z^2 + z^3 + z^4 + O(z^5) sage: L(constant=1) @@ -175,19 +196,15 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: g z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13) - Finally, ``x`` can be a Laurent polynomial:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: p = x^-2 + 3*x^3 - sage: L. = LazyLaurentSeriesRing(ZZ) - sage: L(p) - x^-2 + 3*x^3 - - sage: L(p, valuation=0) - 1 + 3*x^5 + If ``x`` is explicitly passed as ``None``, the resulting + series is undefined. This can be used to define it + implicitly, see + :meth:`sage.rings.lazy_series.LazyModuleElement.define`:: - sage: L(p, valuation=1) - x + 3*x^6 + sage: f = L(None, valuation=-1) + sage: f.define(z^-1 + z^2*f^2) + sage: f + z^-1 + 1 + 2*z + 5*z^2 + 14*z^3 + 42*z^4 + 132*z^5 + O(z^6) We construct a lazy Laurent series over another lazy Laurent series:: @@ -471,7 +488,7 @@ def undefined(self, valuation=None): - ``valuation`` -- integer; a lower bound for the valuation of the series Power series can be defined recursively (see - :meth:`sage.rings.lazy_series.LazyModuleElement.define()` for + :meth:`sage.rings.lazy_series.LazyModuleElement.define` for more examples). EXAMPLES:: @@ -482,6 +499,8 @@ def undefined(self, valuation=None): sage: s z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8) """ + if valuation is None: + valuation = self._minimal_valuation coeff_stream = Stream_uninitialized(self._sparse, valuation) return self.element_class(self, coeff_stream) @@ -815,7 +834,7 @@ class LazyLaurentSeriesRing(LazySeriesRing): z - z^2 + z^3 + 5*z^4 + 5*z^5 + 5*z^6 + O(z^7) Power series can be defined recursively (see - :meth:`sage.rings.lazy_series.LazyModuleElement.define()` for + :meth:`sage.rings.lazy_series.LazyModuleElement.define` for more examples):: sage: L. = LazyLaurentSeriesRing(ZZ) From e8c76361936e15440a2f27fcd2cccd2c21054ba9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 15 Sep 2022 09:53:54 +0200 Subject: [PATCH 098/350] advertise passing None to the constructor --- src/sage/rings/lazy_series_ring.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 5ebfd5c6e4a..51845485609 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -498,6 +498,13 @@ def undefined(self, valuation=None): sage: s.define(z + (s^2+s(z^2))/2) sage: s z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8) + + Alternatively:: + + sage: f = L(None, valuation=-1) + sage: f.define(z^-1 + z^2*f^2) + sage: f + z^-1 + 1 + 2*z + 5*z^2 + 14*z^3 + 42*z^4 + 132*z^5 + O(z^6) """ if valuation is None: valuation = self._minimal_valuation From b33e5da3b6edfbaa959d6f164963db533b9862b8 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 15 Sep 2022 16:36:42 +0800 Subject: [PATCH 099/350] remove methods deprecated in #32744 --- .../elliptic_curves/ell_curve_isogeny.py | 338 +++--------------- 1 file changed, 54 insertions(+), 284 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 516a713e422..f6a90401f01 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -1273,6 +1273,52 @@ def __neg__(self): sage: P = E((7,13)) sage: phi(P) + negphi(P) == 0 True + + sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) + sage: f = E.torsion_polynomial(3)/3 + sage: phi = EllipticCurveIsogeny(E, f, E) + sage: phi.rational_maps() == E.multiplication_by_m(3) + False + sage: negphi = -phi + sage: negphi.rational_maps() == E.multiplication_by_m(3) + True + + sage: E = EllipticCurve(GF(17), [-2, 3, -5, 7, -11]) + sage: R. = GF(17)[] + sage: f = x+6 + sage: phi = EllipticCurveIsogeny(E, f) + sage: phi + Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 + sage: phi.rational_maps() + ((x^2 + 6*x + 4)/(x + 6), (x^2*y - 5*x*y + 8*x - 2*y)/(x^2 - 5*x + 2)) + sage: negphi = -phi + sage: negphi + Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 + sage: negphi.rational_maps() + ((x^2 + 6*x + 4)/(x + 6), + (2*x^3 - x^2*y - 5*x^2 + 5*x*y - 4*x + 2*y + 7)/(x^2 - 5*x + 2)) + + sage: E = EllipticCurve('11a1') + sage: R. = QQ[] + sage: f = x^2 - 21*x + 80 + sage: phi = EllipticCurveIsogeny(E, f) + sage: (xmap1, ymap1) = phi.rational_maps() + sage: negphi = -phi + sage: (xmap2, ymap2) = negphi.rational_maps() + sage: xmap1 == xmap2 + True + sage: ymap1 == -ymap2 - E.a1()*xmap2 - E.a3() + True + + sage: K. = NumberField(x^2 + 1) + sage: E = EllipticCurve(K, [0,0,0,1,0]) + sage: R. = K[] + sage: phi = EllipticCurveIsogeny(E, x-a) + sage: phi.rational_maps() + ((x^2 + (-a)*x - 2)/(x + (-a)), (x^2*y + (-2*a)*x*y + y)/(x^2 + (-2*a)*x - 1)) + sage: negphi = -phi + sage: negphi.rational_maps() + ((x^2 + (-a)*x - 2)/(x + (-a)), (-x^2*y + (2*a)*x*y - y)/(x^2 + (-2*a)*x - 1)) """ output = copy(self) E2 = output._codomain @@ -1342,8 +1388,7 @@ def __clear_cached_values(self): sage: phi = EllipticCurveIsogeny(E, x) sage: old_ratl_maps = phi.rational_maps() sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi.set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (-1,0,0,0))) - ... + sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (-1,0,0,0))) sage: old_ratl_maps == phi.rational_maps() False sage: old_ratl_maps[1] == -phi.rational_maps()[1] @@ -1355,8 +1400,7 @@ def __clear_cached_values(self): sage: phi = EllipticCurveIsogeny(E, f) sage: old_ratl_maps = phi.rational_maps() sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi.set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (-13,13,-13,13))) - ... + sage: phi._set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (-13,13,-13,13))) sage: old_ratl_maps == phi.rational_maps() False sage: phi._EllipticCurveIsogeny__clear_cached_values() @@ -1381,12 +1425,10 @@ def __perform_inheritance_housekeeping(self): sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: E2 = phi.codomain() sage: post_isom = WeierstrassIsomorphism(E2, (41, 37, 31, 29)) - sage: phi.set_post_isomorphism(post_isom) - ... + sage: phi._set_post_isomorphism(post_isom) sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() sage: pre_isom = E1pr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(pre_isom) - ... + sage: phi._set_pre_isomorphism(pre_isom) """ EllipticCurveHom.__init__(self, self._domain, self._codomain) @@ -1579,8 +1621,7 @@ def __set_pre_isomorphism(self, domain, isomorphism): sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: E1pr = WeierstrassIsomorphism(E, (-1, 2, -3, 4)).codomain() sage: pre_isom = E1pr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(pre_isom) - ... + sage: phi._set_pre_isomorphism(pre_isom) sage: phi._EllipticCurveIsogeny__set_pre_isomorphism(E, WeierstrassIsomorphism(E, (-1, 3, -3, 4))) sage: E == phi.domain() True @@ -1622,8 +1663,7 @@ def __set_post_isomorphism(self, codomain, isomorphism): sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism sage: E2 = phi.codomain() sage: isom = WeierstrassIsomorphism(E2, (-1,2,-3,4)) - sage: phi.set_post_isomorphism(isom) - ... + sage: phi._set_post_isomorphism(isom) sage: phi._EllipticCurveIsogeny__set_post_isomorphism(E2, WeierstrassIsomorphism(phi.codomain(), (1,-2,3,-4))) sage: E2 == phi.codomain() True @@ -2713,76 +2753,6 @@ def kernel_polynomial(self): return self.__kernel_polynomial - def set_pre_isomorphism(self, preWI): - r""" - Modify this isogeny by precomposing with a Weierstrass isomorphism. - - .. WARNING:: - - Isogenies will be immutable in a future release of Sage. - This method is deprecated in favor of using the ``*`` operator - to compose elliptic-curve morphisms. - - EXAMPLES:: - - sage: E = EllipticCurve(GF(31), [1,1,0,1,-1]) - sage: R. = GF(31)[] - sage: f = x^3 + 9*x^2 + x + 30 - sage: phi = EllipticCurveIsogeny(E, f) - sage: Epr = E.short_weierstrass_model() - sage: isom = Epr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(isom) - ... - sage: phi.rational_maps() - ((-6*x^4 - 3*x^3 + 12*x^2 + 10*x - 1)/(x^3 + x - 12), (3*x^7 + x^6*y - 14*x^6 - 3*x^5 + 5*x^4*y + 7*x^4 + 8*x^3*y - 8*x^3 - 5*x^2*y + 5*x^2 - 14*x*y + 14*x - 6*y - 6)/(x^6 + 2*x^4 + 7*x^3 + x^2 + 7*x - 11)) - sage: phi(Epr((0,22))) - (13 : 21 : 1) - sage: phi(Epr((3,7))) - (14 : 17 : 1) - - sage: E = EllipticCurve(GF(29), [0,0,0,1,0]) - sage: R. = GF(29)[] - sage: f = x^2 + 5 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: inv_isom = WeierstrassIsomorphism(E, (1,-2,5,10)) - sage: Epr = inv_isom.codomain() - sage: isom = Epr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(isom) - ... - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 + 10*x*y + 20*y = x^3 + 27*x^2 + 6 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 20*x over Finite Field of size 29 - sage: phi(Epr((12,1))) - (26 : 0 : 1) - sage: phi(Epr((2,9))) - (0 : 0 : 1) - sage: phi(Epr((21,12))) - (3 : 0 : 1) - sage: phi.rational_maps()[0] - (x^5 - 10*x^4 - 6*x^3 - 7*x^2 - x + 3)/(x^4 - 8*x^3 + 5*x^2 - 14*x - 6) - - sage: E = EllipticCurve('11a1') - sage: R. = QQ[] - sage: f = x^2 - 21*x + 80 - sage: phi = EllipticCurveIsogeny(E, f); phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: Epr = E.short_weierstrass_model() - sage: isom = Epr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(isom) - ... - sage: phi - Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 - 13392*x - 1080432 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field - sage: phi(Epr((168,1188))) - (0 : 1 : 0) - """ - from sage.misc.superseded import deprecation - deprecation(32388, 'Elliptic-curve isogenies will be immutable in a future release of Sage.' - ' Use phi*psi instead of phi.set_pre_isomorphism(psi) to obtain the composite isogeny.') - return self._set_pre_isomorphism(preWI) - def _set_pre_isomorphism(self, preWI): """ Modify this isogeny by pre-composing with a @@ -2790,9 +2760,7 @@ def _set_pre_isomorphism(self, preWI): For internal use only. - TESTS: - - These tests were copied from :meth:`set_pre_isomorphism`:: + TESTS:: sage: E = EllipticCurve(GF(31), [1,1,0,1,-1]) sage: R. = GF(31)[] @@ -2865,58 +2833,6 @@ def _set_pre_isomorphism(self, preWI): self.__set_pre_isomorphism(domain, isom) - def set_post_isomorphism(self, postWI): - r""" - Modify this isogeny by postcomposing with a Weierstrass isomorphism. - - .. WARNING:: - - Isogenies will be immutable in a future release of Sage. - This method is deprecated in favor of using the ``*`` operator - to compose elliptic-curve morphisms. - - EXAMPLES:: - - sage: E = EllipticCurve(j=GF(31)(0)) - sage: R. = GF(31)[] - sage: phi = EllipticCurveIsogeny(E, x+18) - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: phi.set_post_isomorphism(WeierstrassIsomorphism(phi.codomain(), (6,8,10,12))) - ... - sage: phi - Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 31 to Elliptic Curve defined by y^2 + 24*x*y + 7*y = x^3 + 22*x^2 + 16*x + 20 over Finite Field of size 31 - - sage: E = EllipticCurve(j=GF(47)(0)) - sage: f = E.torsion_polynomial(3)/3 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: post_isom = E2.isomorphism_to(E) - sage: phi.set_post_isomorphism(post_isom) - ... - sage: phi.rational_maps() == E.multiplication_by_m(3) - False - sage: phi.switch_sign() - ... - sage: phi.rational_maps() == E.multiplication_by_m(3) - True - - Example over a number field:: - - sage: R. = QQ[] - sage: K. = NumberField(x^2 + 2) - sage: E = EllipticCurve(j=K(1728)) - sage: ker_list = E.torsion_points() - sage: phi = EllipticCurveIsogeny(E, ker_list) - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: post_isom = WeierstrassIsomorphism(phi.codomain(), (a,2,3,5)) - sage: phi - Isogeny of degree 4 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^2 + 2 to Elliptic Curve defined by y^2 = x^3 + (-44)*x + 112 over Number Field in a with defining polynomial x^2 + 2 - """ - from sage.misc.superseded import deprecation - deprecation(32388, 'Elliptic-curve isogenies will be immutable in a future release of Sage.' - ' Use psi*phi instead of phi.set_post_isomorphism(psi) to obtain the composite isogeny.') - return self._set_post_isomorphism(postWI) - def _set_post_isomorphism(self, postWI): """ Modify this isogeny by post-composing with a @@ -2924,9 +2840,7 @@ def _set_post_isomorphism(self, postWI): For internal use only. - TESTS: - - These tests were copied from :meth:`set_post_isomorphism`:: + TESTS:: sage: E = EllipticCurve(j=GF(31)(0)) sage: R. = GF(31)[] @@ -2979,150 +2893,6 @@ def _set_post_isomorphism(self, postWI): self.__set_post_isomorphism(codomain, isom) - def get_pre_isomorphism(self): - r""" - Return the pre-isomorphism of this isogeny, or ``None``. - - .. NOTE:: - - Pre- and post-isomorphisms are an implementation detail of - how isogenies are currently represented in Sage. They have - limited inherent mathematical meaning and this method may - disappear in a future release. - - EXAMPLES:: - - sage: E = EllipticCurve(GF(31), [1,1,0,1,-1]) - sage: R. = GF(31)[] - sage: f = x^3 + 9*x^2 + x + 30 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi.get_post_isomorphism() - sage: Epr = E.short_weierstrass_model() - sage: isom = Epr.isomorphism_to(E) - sage: phi.set_pre_isomorphism(isom) - ... - sage: isom == phi.get_pre_isomorphism() - True - - sage: E = EllipticCurve(GF(83), [1,0,1,1,0]) - sage: R. = GF(83)[]; f = x+24 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: phi2 = EllipticCurveIsogeny(E, None, E2, 2) - sage: phi2.get_pre_isomorphism() - Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x over Finite Field of size 83 - To: Elliptic Curve defined by y^2 = x^3 + 62*x + 74 over Finite Field of size 83 - Via: (u,r,s,t) = (1, 76, 41, 3) - """ - return self.__pre_isomorphism - - def get_post_isomorphism(self): - r""" - Return the post-isomorphism of this isogeny, or ``None``. - - .. NOTE:: - - Pre- and post-isomorphisms are an implementation detail of - how isogenies are currently represented in Sage. They have - limited inherent mathematical meaning and this method may - disappear in a future release. - - EXAMPLES:: - - sage: E = EllipticCurve(j=GF(31)(0)) - sage: R. = GF(31)[] - sage: phi = EllipticCurveIsogeny(E, x+18) - sage: phi.get_post_isomorphism() - sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism - sage: isom = WeierstrassIsomorphism(phi.codomain(), (6,8,10,12)) - sage: phi.set_post_isomorphism(isom) - ... - sage: isom == phi.get_post_isomorphism() - True - - sage: E = EllipticCurve(GF(83), [1,0,1,1,0]) - sage: R. = GF(83)[]; f = x+24 - sage: phi = EllipticCurveIsogeny(E, f) - sage: E2 = phi.codomain() - sage: phi2 = EllipticCurveIsogeny(E, None, E2, 2) - sage: phi2.get_post_isomorphism() - Elliptic-curve morphism: - From: Elliptic Curve defined by y^2 = x^3 + 65*x + 69 over Finite Field of size 83 - To: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + 16 over Finite Field of size 83 - Via: (u,r,s,t) = (1, 7, 42, 42) - """ - return self.__post_isomorphism - - - def switch_sign(self): - r""" - Compose this isogeny with `[-1]` (negation). - - .. WARNING:: - - Isogenies will be immutable in a future version of Sage. - This method is deprecated in favor of using the unary ``-`` - operator to negate elliptic-curve morphisms. - - EXAMPLES:: - - sage: E = EllipticCurve(GF(23), [0,0,0,1,0]) - sage: f = E.torsion_polynomial(3)/3 - sage: phi = EllipticCurveIsogeny(E, f, E) - sage: phi.rational_maps() == E.multiplication_by_m(3) - False - sage: phi.switch_sign() - ... - sage: phi.rational_maps() == E.multiplication_by_m(3) - True - - sage: E = EllipticCurve(GF(17), [-2, 3, -5, 7, -11]) - sage: R. = GF(17)[] - sage: f = x+6 - sage: phi = EllipticCurveIsogeny(E, f) - sage: phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 - sage: phi.rational_maps() - ((x^2 + 6*x + 4)/(x + 6), (x^2*y - 5*x*y + 8*x - 2*y)/(x^2 - 5*x + 2)) - sage: phi.switch_sign() - ... - sage: phi - Isogeny of degree 2 from Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 7*x + 6 over Finite Field of size 17 to Elliptic Curve defined by y^2 + 15*x*y + 12*y = x^3 + 3*x^2 + 4*x + 8 over Finite Field of size 17 - sage: phi.rational_maps() - ((x^2 + 6*x + 4)/(x + 6), - (2*x^3 - x^2*y - 5*x^2 + 5*x*y - 4*x + 2*y + 7)/(x^2 - 5*x + 2)) - - sage: E = EllipticCurve('11a1') - sage: R. = QQ[] - sage: f = x^2 - 21*x + 80 - sage: phi = EllipticCurveIsogeny(E, f) - sage: (xmap1, ymap1) = phi.rational_maps() - sage: phi.switch_sign() - ... - sage: (xmap2, ymap2) = phi.rational_maps() - sage: xmap1 == xmap2 - True - sage: ymap1 == -ymap2 - E.a1()*xmap2 - E.a3() - True - - sage: K. = NumberField(x^2 + 1) - sage: E = EllipticCurve(K, [0,0,0,1,0]) - sage: R. = K[] - sage: phi = EllipticCurveIsogeny(E, x-a) - sage: phi.rational_maps() - ((x^2 + (-a)*x - 2)/(x + (-a)), (x^2*y + (-2*a)*x*y + y)/(x^2 + (-2*a)*x - 1)) - sage: phi.switch_sign() - ... - sage: phi.rational_maps() - ((x^2 + (-a)*x - 2)/(x + (-a)), (-x^2*y + (2*a)*x*y - y)/(x^2 + (-2*a)*x - 1)) - """ - from sage.misc.superseded import deprecation - deprecation(32388, 'Elliptic-curve isogenies will be immutable in a future release of Sage.' - ' Use -phi instead of phi.switch_sign() to obtain the negated isogeny.') - E2 = self._codomain - self._set_post_isomorphism(WeierstrassIsomorphism(E2, (-1, 0, -E2.a1(), -E2.a3()))) - def dual(self): r""" Return the isogeny dual to this isogeny. From f541f3d184e8b2468da5c2953383a4979996ec5c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 15 Sep 2022 10:53:03 +0200 Subject: [PATCH 100/350] add links to relaxed p-adics --- src/sage/rings/lazy_series_ring.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 51845485609..ed60a1e2e0c 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -14,6 +14,11 @@ :class:`LazySymmetricFunctions` | The ring of (possibly multivariate) lazy symmetric functions. :class:`LazyDirichletSeriesRing` | The ring of lazy Dirichlet series. +.. SEEALSO:: + + :class:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric`, + :func:`sage.rings.padics.factory.ZpER` + AUTHORS: - Kwankyu Lee (2019-02-24): initial version @@ -491,6 +496,10 @@ def undefined(self, valuation=None): :meth:`sage.rings.lazy_series.LazyModuleElement.define` for more examples). + .. SEEALSO:: + + :meth:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric.unknown` + EXAMPLES:: sage: L. = LazyPowerSeriesRing(QQ) From 1df62c8481a2bf52542f5e50a6b5d8610a8ac4b9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 15 Sep 2022 13:54:13 +0200 Subject: [PATCH 101/350] fix wrong ring in doctest --- src/sage/rings/lazy_series_ring.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ed60a1e2e0c..acaef041566 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -510,6 +510,7 @@ def undefined(self, valuation=None): Alternatively:: + sage: L. = LazyLaurentSeriesRing(QQ) sage: f = L(None, valuation=-1) sage: f.define(z^-1 + z^2*f^2) sage: f From 23d951f0e9593c03d22744e6a25f8723cd95342e Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 16 Sep 2022 10:53:18 +0900 Subject: [PATCH 102/350] Doing some reviewer changes. --- .../combinat/species/generating_series.py | 85 +++++++++++-------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 6fd835912b6..54d418b9f2a 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -52,7 +52,7 @@ from sage.rings.lazy_series import LazyPowerSeries, LazySymmetricFunction from sage.rings.lazy_series_ring import LazyPowerSeriesRing, LazySymmetricFunctions from sage.rings.integer import Integer -from sage.rings.rational_field import RationalField +from sage.rings.rational_field import QQ from sage.arith.all import divisors from sage.combinat.partition import Partition, Partitions from sage.combinat.sf.sf import SymmetricFunctions @@ -74,7 +74,6 @@ class OrdinaryGeneratingSeries(LazyPowerSeries): sage: f = R(lambda n: n) sage: f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) - """ def count(self, n): """ @@ -91,7 +90,6 @@ def count(self, n): sage: f = R(range(20)) sage: f.count(10) 10 - """ return self.coefficient(n) @@ -107,7 +105,6 @@ def counts(self, n): sage: f = R(range(20)) sage: f.counts(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - """ return [self.count(i) for i in range(n)] @@ -134,18 +131,20 @@ class OrdinaryGeneratingSeriesRing(LazyPowerSeriesRing): TESTS: - We test to make sure that caching works.:: + We test to make sure that caching works:: sage: R is OrdinaryGeneratingSeriesRing(QQ) True - """ def __init__(self, base_ring): """ + Initialize ``self``. + TESTS:: - self: R = OrdinaryGeneratingSeriesRing(QQ); R - Lazy Taylor Series Ring in z over Rational Field + sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: R = OrdinaryGeneratingSeriesRing(QQ) + sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements"]) """ super().__init__(base_ring, names="z") @@ -167,7 +166,6 @@ class ExponentialGeneratingSeries(LazyPowerSeries): sage: f = R(lambda n: n) sage: f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) - """ def count(self, n): """ @@ -180,7 +178,6 @@ def count(self, n): sage: f = R(lambda n: 1) sage: [f.count(i) for i in range(7)] [1, 1, 2, 6, 24, 120, 720] - """ return factorial(n) * self.coefficient(n) @@ -196,7 +193,6 @@ def counts(self, n): sage: f = R(range(20)) sage: f.counts(5) [0, 1, 4, 18, 96] - """ return [self.count(i) for i in range(n)] @@ -211,7 +207,7 @@ def functorial_composition(self, y): .. MATH:: - f \Box g = \sum_{n=0}^{\infty} f_{g_n} \frac{x^n}{n!} + f \Box g = \sum_{n=0}^{\infty} f_{g_n} \frac{x^n}{n!}. REFERENCES: @@ -232,7 +228,6 @@ def functorial_composition(self, y): sage: g2 = P2.generating_series() sage: g1.functorial_composition(g2)[:10] [1, 1, 1, 4/3, 8/3, 128/15, 2048/45, 131072/315, 2097152/315, 536870912/2835] - """ P = self.parent() return P(lambda n: self.count(y.count(n)) / factorial(n), 0) @@ -261,14 +256,16 @@ class ExponentialGeneratingSeriesRing(LazyPowerSeriesRing): sage: R is ExponentialGeneratingSeriesRing(QQ) True - """ def __init__(self, base_ring): """ + Initialize ``self``. + TESTS:: - self: R = ExponentialGeneratingSeriesRing(QQ); R - Lazy Taylor Series Ring in z over Rational Field + sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: R = ExponentialGeneratingSeriesRing(QQ) + sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements""]) """ super().__init__(base_ring, names="z") @@ -299,7 +296,7 @@ def count(self, t): def coefficient_cycle_type(self, t): """ - Returns the coefficient of a cycle type ``t`` in ``self``. + Return the coefficient of a cycle type ``t`` in ``self``. EXAMPLES:: @@ -320,6 +317,8 @@ def coefficient_cycle_type(self, t): def isotype_generating_series(self): """ + Return the isotype generating series of ``self``. + EXAMPLES:: sage: P = species.PermutationSpecies() @@ -330,11 +329,12 @@ def isotype_generating_series(self): """ R = self.base_ring() OGS = OrdinaryGeneratingSeriesRing(R) - return OGS(lambda n: self._ogs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) + return OGS(lambda n: self._ogs_gen(n, self._coeff_stream._approximate_order), + self._coeff_stream._approximate_order) def _ogs_gen(self, n, ao): """ - Returns a generator for the coefficients of the ordinary generating + Return a generator for the coefficients of the ordinary generating series obtained from a cycle index series. EXAMPLES:: @@ -350,6 +350,8 @@ def _ogs_gen(self, n, ao): def generating_series(self): """ + Return the generating series of ``self``. + EXAMPLES:: sage: P = species.PartitionSpecies() @@ -360,11 +362,12 @@ def generating_series(self): """ R = self.base_ring() EGS = ExponentialGeneratingSeriesRing(R) - return EGS(lambda n: self._egs_gen(n, self._coeff_stream._approximate_order), self._coeff_stream._approximate_order) + return EGS(lambda n: self._egs_gen(n, self._coeff_stream._approximate_order), + self._coeff_stream._approximate_order) def _egs_gen(self, n, ao): """ - Returns a generator for the coefficients of the exponential + Return a generator for the coefficients of the exponential generating series obtained from a cycle index series. EXAMPLES:: @@ -428,10 +431,9 @@ def pointing(self): sage: X = species.SingletonSpecies().cycle_index_series() sage: E.pointing()[:8] == (X*E)[:8] True - """ X = self.parent()([1], valuation=1) - return X*self.derivative_with_respect_to_p1() + return X * self.derivative_with_respect_to_p1() def exponential(self): r""" @@ -530,22 +532,30 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): TESTS: - We test to make sure that caching works. - - :: + We test to make sure that caching works:: sage: R is CycleIndexSeriesRing(QQ) True - """ Element = CycleIndexSeries def __init__(self, base_ring, sparse=True): + """ + Initialize ``self``. + + TESTS:: + + sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: R = CycleIndexSeriesRing(QQ) + sage: TestSuite(R).run(skip=["_test_elements", "_test_quo_rem"]) + """ p = SymmetricFunctions(base_ring).power() super().__init__(p) - def __repr__(self): + def _repr_(self): """ + Return a string representation of ``self``. + EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing @@ -556,9 +566,10 @@ def __repr__(self): @cached_function -def _exp_term(n, R = RationalField()): - """ - Compute the order-n term of the cycle index series of the species `E` of sets. +def _exp_term(n, R=QQ): + r""" + Compute the order-``n`` term of the cycle index series of the species + `E` of sets. EXAMPLES:: @@ -571,7 +582,7 @@ def _exp_term(n, R = RationalField()): @cached_function -def ExponentialCycleIndexSeries(R = RationalField()): +def ExponentialCycleIndexSeries(R=QQ): r""" Return the cycle index series of the species `E` of sets. @@ -595,10 +606,11 @@ def ExponentialCycleIndexSeries(R = RationalField()): @cached_function -def _cl_term(n, R = RationalField()): +def _cl_term(n, R=QQ): r""" - Compute the order-n term of the cycle index series of the virtual species - `\Omega`, the compositional inverse of the species `E^{+}` of nonempty sets. + Compute the order-``n`` term of the cycle index series of + the virtual species `\Omega`, the compositional inverse of + the species `E^{+}` of nonempty sets. EXAMPLES:: @@ -619,7 +631,7 @@ def _cl_term(n, R = RationalField()): return res @cached_function -def LogarithmCycleIndexSeries(R = RationalField()): +def LogarithmCycleIndexSeries(R=QQ): r""" Return the cycle index series of the virtual species `\Omega`, the compositional inverse of the species `E^{+}` of nonempty sets. @@ -647,3 +659,4 @@ def LogarithmCycleIndexSeries(R = RationalField()): """ CIS = CycleIndexSeriesRing(R) return CIS(_cl_term) + From 6969549f284c5d145d77ba6e8061061f4ca856b7 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 16 Sep 2022 11:27:16 +0900 Subject: [PATCH 103/350] Implementing methods for DVF. --- src/sage/rings/lazy_series_ring.py | 102 +++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 1bfdffef6d8..7555869fa8e 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1116,6 +1116,36 @@ def _monomial(self, c, n): """ return self._laurent_poly_ring(c).shift(n) + def uniformizer(self): + """ + Return a uniformizer of ``self``.. + + EXAMPLES:: + + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L.uniformizer() + z + """ + R = self.base_ring() + if R not in Fields(): + raise TypeError("the base ring is not a field") + return self.gen() + + def residue_field(self): + """ + Return the residue field of the ring of integers of ``self``. + + EXAMPLES:: + + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L.residue_field() + Rational Field + """ + R = self.base_ring() + if R not in Fields(): + raise TypeError("the base ring is not a field") + return R + ###################################################################### @@ -1147,6 +1177,27 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyTaylorSeriesRing(ZZ, 't') sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + sage: L = LazyTaylorSeriesRing(QQ, 't') + sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero', '_test_quo_rem']) + + Check that :trac:`34470` is fixed:: + + sage: L. = LazyTaylorSeriesRing(QQ) + sage: L in CompleteDiscreteValuationRings + True + sage: L.uniformizer() + t + sage: lcm(1/(1 - t^2) - 1, t) + t^2 + + sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L in PrincipalIdealDomains + False + + sage: L = LazyTaylorSeriesRing(QQ, 's, t') + sage: L in PrincipalIdealDomains + False """ from sage.structure.category_object import normalize_names names = normalize_names(-1, names) @@ -1156,10 +1207,9 @@ def __init__(self, base_ring, names, sparse=True, category=None): if self._arity == 1: self._internal_poly_ring = self._laurent_poly_ring else: - coeff_ring = PolynomialRing(base_ring, names) - self._internal_poly_ring = PolynomialRing(coeff_ring, "DUMMY_VARIABLE") + self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE") category = Algebras(base_ring.category()) - if base_ring in Fields(): + if self._arity == 1 and base_ring in Fields(): category &= CompleteDiscreteValuationRings() elif base_ring in IntegralDomains(): category &= IntegralDomains() @@ -1481,6 +1531,40 @@ def _an_element_(self): coeff_stream = Stream_exact([R.one()], self._sparse, order=1, constant=c) return self.element_class(self, coeff_stream) + def uniformizer(self): + """ + Return a uniformizer of ``self``.. + + EXAMPLES:: + + sage: L = LazyTaylorSeriesRing(QQ, 'x') + sage: L.uniformizer() + x + """ + R = self.base_ring() + if R not in Fields(): + raise TypeError("the base ring is not a field") + if self._arity != 1: + raise TypeError("the arity must be one") + return self.gen() + + def residue_field(self): + """ + Return the residue field of the ring of integers of ``self``. + + EXAMPLES:: + + sage: L = LazyTaylorSeriesRing(QQ, 'x') + sage: L.residue_field() + Rational Field + """ + R = self.base_ring() + if R not in Fields(): + raise TypeError("the base ring is not a field") + if self._arity != 1: + raise TypeError("the arity must be one") + return R + ###################################################################### @@ -1537,6 +1621,13 @@ def __init__(self, basis, sparse=True, category=None): sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + + Check that :trac:`34470` is fixed:: + + sage: s = SymmetricFunctions(QQ).s() + sage: L = LazySymmetricFunctions(s) + sage: L in PrincipalIdealDomains + False """ base_ring = basis.base_ring() if basis in Algebras.TensorProducts: @@ -1546,9 +1637,7 @@ def __init__(self, basis, sparse=True, category=None): raise ValueError("basis should be a graded algebra") self._arity = 1 category = Algebras(base_ring.category()) - if base_ring in Fields(): - category &= CompleteDiscreteValuationRings() - elif base_ring in IntegralDomains(): + if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): category = category.Commutative() @@ -2067,3 +2156,4 @@ def _monomial(self, c, n): return L(c) * L(n) ** -L(self.variable_name()) except (ValueError, TypeError): return '({})/{}^{}'.format(self.base_ring()(c), n, self.variable_name()) + From c549b06c78030da4c0c34dec3503fbe478400fb0 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 12:07:28 +0200 Subject: [PATCH 104/350] fix typo --- src/sage/categories/unique_factorization_domains.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/categories/unique_factorization_domains.py b/src/sage/categories/unique_factorization_domains.py index 49a41b97098..ccc96acbf80 100644 --- a/src/sage/categories/unique_factorization_domains.py +++ b/src/sage/categories/unique_factorization_domains.py @@ -16,9 +16,11 @@ class UniqueFactorizationDomains(Category_singleton): """ - The category of unique factorization domains - constructive unique factorization domains, i.e. where one can constructively - factor members into a product of a finite number of irreducible elements + The category of (constructive) unique factorization domains. + + In a constructive unique factorization domain we can + constructively factor members into a product of a finite number + of irreducible elements. EXAMPLES:: @@ -30,6 +32,7 @@ class UniqueFactorizationDomains(Category_singleton): TESTS:: sage: TestSuite(UniqueFactorizationDomains()).run() + """ def super_categories(self): From 0a8b4c643a2f9ba6ce96653a2c21da31df62751a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 12 Sep 2022 15:09:49 +0200 Subject: [PATCH 105/350] implement _im_gens_, part 1 --- src/sage/rings/lazy_series.py | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 4e2f35f2c3b..5f7c0266d11 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2934,6 +2934,32 @@ class LazyLaurentSeries(LazyCauchyProductSeries): sage: f = 1 / (1 - z - z^2) sage: TestSuite(f).run() """ + def _im_gens_(self, codomain, im_gens, base_map=None): + """ + Returns the image of ``self`` under the map that sends the + generators of the parent of ``self`` to the elements of the + tuple ``im_gens``. + + EXAMPLES:: + + sage: Z. = ZZ[] + sage: K. = NumberField(x^2 + 1) + sage: R. = LazyLaurentSeriesRing(K) + sage: f = R(lambda n: i^n, valuation=-2) + sage: f + -t^-2 - i*t^-1 + 1 + i*t - t^2 - i*t^3 + t^4 + O(t^5) + sage: f._im_gens_(R, [t + t^2]) + -t^-2 + (-i + 2)*t^-1 + (i - 2) + 4*t + (2*i - 6)*t^2 + (-2*i + 4)*t^3 + (-2*i - 7)*t^4 + O(t^5) + + sage: cc = K.hom([-i]) + sage: f._im_gens_(R, [t + t^2], base_map=cc) + -t^-2 + (i + 2)*t^-1 + (-i - 2) + 4*t + (-2*i - 6)*t^2 + (2*i + 4)*t^3 + (2*i - 7)*t^4 + O(t^5) + + """ + if base_map is None: + return codomain(self(im_gens[0])) + + return codomain(self.map_coefficients(base_map)(im_gens[0])) def __call__(self, g, *, check=True): r""" @@ -3844,6 +3870,32 @@ def compute_coefficients(self, i): deprecation(32367, "the method compute_coefficients obsolete and has no effect.") return + def _im_gens_(self, codomain, im_gens, base_map=None): + """ + Returns the image of ``self`` under the map that sends the + generators of the parent of ``self`` to the elements of the + tuple ``im_gens``. + + EXAMPLES:: + + sage: Z. = QQ[] + sage: R. = LazyPowerSeriesRing(Z) + sage: f = 1/(1-q-t) + sage: f + 1 + (q+t) + (q^2+2*q*t+t^2) + (q^3+3*q^2*t+3*q*t^2+t^3) + (q^4+4*q^3*t+6*q^2*t^2+4*q*t^3+t^4) + (q^5+5*q^4*t+10*q^3*t^2+10*q^2*t^3+5*q*t^4+t^5) + (q^6+6*q^5*t+15*q^4*t^2+20*q^3*t^3+15*q^2*t^4+6*q*t^5+t^6) + O(q,t)^7 + sage: S. = LazyPowerSeriesRing(Z) + sage: f._im_gens_(S, [t, x*t]) + 1 + ((x+1)*t) + ((x^2+2*x+1)*t^2) + ((x^3+3*x^2+3*x+1)*t^3) + ((x^4+4*x^3+6*x^2+4*x+1)*t^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*t^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*t^6) + O(t^7) + + sage: cc = Z.hom([-x]) + sage: f._im_gens_(S, [t, t], base_map=cc) + + """ + if base_map is None: + return codomain(self(*im_gens)) + + return codomain(self.map_coefficients(base_map)(*im_gens)) + def __call__(self, *g, check=True): r""" Return the composition of ``self`` with ``g``. From 380ddc9137af427094d30700f15043b7193af844 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 13 Sep 2022 00:19:55 +0200 Subject: [PATCH 106/350] adapt doctests --- src/sage/rings/lazy_series.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 5f7c0266d11..23992898376 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3883,13 +3883,14 @@ def _im_gens_(self, codomain, im_gens, base_map=None): sage: f = 1/(1-q-t) sage: f 1 + (q+t) + (q^2+2*q*t+t^2) + (q^3+3*q^2*t+3*q*t^2+t^3) + (q^4+4*q^3*t+6*q^2*t^2+4*q*t^3+t^4) + (q^5+5*q^4*t+10*q^3*t^2+10*q^2*t^3+5*q*t^4+t^5) + (q^6+6*q^5*t+15*q^4*t^2+20*q^3*t^3+15*q^2*t^4+6*q*t^5+t^6) + O(q,t)^7 - sage: S. = LazyPowerSeriesRing(Z) - sage: f._im_gens_(S, [t, x*t]) - 1 + ((x+1)*t) + ((x^2+2*x+1)*t^2) + ((x^3+3*x^2+3*x+1)*t^3) + ((x^4+4*x^3+6*x^2+4*x+1)*t^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*t^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*t^6) + O(t^7) + sage: S. = LazyPowerSeriesRing(Z) + sage: f._im_gens_(S, [s, x*s]) + 1 + ((x+1)*s) + ((x^2+2*x+1)*s^2) + ((x^3+3*x^2+3*x+1)*s^3) + ((x^4+4*x^3+6*x^2+4*x+1)*s^4) + ((x^5+5*x^4+10*x^3+10*x^2+5*x+1)*s^5) + ((x^6+6*x^5+15*x^4+20*x^3+15*x^2+6*x+1)*s^6) + O(s^7) sage: cc = Z.hom([-x]) - sage: f._im_gens_(S, [t, t], base_map=cc) - + sage: f = 1/(1+x*q-t) + sage: f._im_gens_(S, [s, x*s], base_map=cc) + 1 + 2*x*s + 4*x^2*s^2 + 8*x^3*s^3 + 16*x^4*s^4 + 32*x^5*s^5 + 64*x^6*s^6 + O(s^7) """ if base_map is None: return codomain(self(*im_gens)) From 69d44abf4ce2ec4fb652ec8e39dac42cd044537f Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 16 Sep 2022 22:17:29 +0900 Subject: [PATCH 107/350] Removing old use of LazyTaylorSeriesRing from my changes. --- src/sage/rings/lazy_series_ring.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 9131f852f7a..60393b51d70 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1232,12 +1232,12 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) - sage: L = LazyTaylorSeriesRing(QQ, 't') + sage: L = LazyPowerSeriesRing(QQ, 't') sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero', '_test_quo_rem']) Check that :trac:`34470` is fixed:: - sage: L. = LazyTaylorSeriesRing(QQ) + sage: L. = LazyPowerSeriesRing(QQ) sage: L in CompleteDiscreteValuationRings True sage: L.uniformizer() @@ -1245,11 +1245,11 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: lcm(1/(1 - t^2) - 1, t) t^2 - sage: L. = LazyTaylorSeriesRing(ZZ) + sage: L. = LazyPowerSeriesRing(ZZ) sage: L in PrincipalIdealDomains False - sage: L = LazyTaylorSeriesRing(QQ, 's, t') + sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: L in PrincipalIdealDomains False """ @@ -1610,7 +1610,7 @@ def uniformizer(self): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(QQ, 'x') + sage: L = LazyPowerSeriesRing(QQ, 'x') sage: L.uniformizer() x """ @@ -1627,7 +1627,7 @@ def residue_field(self): EXAMPLES:: - sage: L = LazyTaylorSeriesRing(QQ, 'x') + sage: L = LazyPowerSeriesRing(QQ, 'x') sage: L.residue_field() Rational Field """ From e3e331c49b9a464abd3d37b03e72a3a6dfdf8f51 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 16:28:24 +0200 Subject: [PATCH 108/350] add and correct some_elements for all rings, run all tests in the TestSuite (many fail) --- src/sage/rings/lazy_series_ring.py | 106 ++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index de37fa0cb7d..8a556eaf039 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -901,27 +901,32 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: sage: L = LazyLaurentSeriesRing(ZZ, 't') - sage: elts = L.some_elements()[:-2] # skip the non-exact elements - sage: TestSuite(L).run(elements=elts, skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + sage: TestSuite(L).run() sage: L.category() Category of infinite commutative no zero divisors algebras over (euclidean domains and infinite enumerated sets and metric spaces) sage: L = LazyLaurentSeriesRing(QQ, 't') + sage: TestSuite(L).run() sage: L.category() Join of Category of complete discrete valuation fields and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets - sage: L = LazyLaurentSeriesRing(ZZ['x,y'], 't') + + sage: L = LazyLaurentSeriesRing(ZZ['x, y'], 't') + sage: TestSuite(L).run() sage: L.category() Category of infinite commutative no zero divisors algebras over (unique factorization domains and commutative algebras over (euclidean domains and infinite enumerated sets and metric spaces) and infinite sets) + sage: E. = ExteriorAlgebra(QQ) sage: L = LazyLaurentSeriesRing(E, 't') # not tested """ self._sparse = sparse + if len(names) != 1: + raise ValueError("only univariate lazy Laurent series are implemented") self._arity = 1 self._minimal_valuation = None # We always use the dense because our CS_exact is implemented densely @@ -1230,13 +1235,16 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: sage: L = LazyPowerSeriesRing(ZZ, 't') - sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(ZZ, 's, t') - sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(QQ, 't') - sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero', '_test_quo_rem']) + sage: TestSuite(L).run() + + sage: L = LazyPowerSeriesRing(QQ, 's, t') + sage: TestSuite(L).run() Check that :trac:`34470` is fixed:: @@ -1610,7 +1618,7 @@ def _an_element_(self): def uniformizer(self): """ - Return a uniformizer of ``self``.. + Return a uniformizer of ``self``. EXAMPLES:: @@ -1642,6 +1650,49 @@ def residue_field(self): raise TypeError("the arity must be one") return R + def some_elements(self): + """ + Return a list of elements of ``self``. + + EXAMPLES:: + + sage: L = LazyPowerSeriesRing(ZZ, 'z') + sage: L.some_elements() + [0, + 1, + z, + z + z^2 + z^3 + z^4 + O(z^5), + -12 - 8*z + z^2 + z^3, + 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), + z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] + + sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') + sage: L.some_elements() + [0, + 1, + z, + z + q*z^2 + q*z^3 + q*z^4 + O(z^5), + z + z^2 + z^3, + 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6), + z + z^2 + z^4 + z^5 + O(z^7)] + + sage: L = LazyPowerSeriesRing(GF(3), 'q, t') + sage: L.some_elements() + [0, 1, q, 1, q + q^2 + q^3, + 1 + q + q^2 + (-q^3) + (-q^4) + (-q^5) + (-q^6) + O(q,t)^7, + 1 + (q+t) + (q^2-q*t+t^2) + (q^3+t^3) + + (q^4+q^3*t+q*t^3+t^4) + + (q^5-q^4*t+q^3*t^2+q^2*t^3-q*t^4+t^5) + + (q^6-q^3*t^3+t^6) + O(q,t)^7] + """ + z = self.gen(0) + elts = [self.zero(), self.one(), z, self.an_element()] + if self._arity == 1: + elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: n**2)]) + else: + elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: sum(self.gens())**n)]) + return elts + ###################################################################### @@ -1697,7 +1748,11 @@ def __init__(self, basis, sparse=True, category=None): sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) - sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + sage: TestSuite(L).run() + + sage: s = SymmetricFunctions(QQ).s() + sage: L = LazySymmetricFunctions(s) + sage: TestSuite(L).run() Check that :trac:`34470` is fixed:: @@ -2044,7 +2099,10 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: sage: L = LazyDirichletSeriesRing(ZZ, 't') - sage: TestSuite(L).run(skip=['_test_elements', '_test_associativity', '_test_distributivity', '_test_zero']) + sage: TestSuite(L).run() + + sage: L = LazyDirichletSeriesRing(QQ, 't') + sage: TestSuite(L).run() """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") @@ -2235,6 +2293,36 @@ def _an_element_(self): c = self.base_ring().an_element() return self.element_class(self, Stream_exact([], self._sparse, constant=c, order=4)) + def some_elements(self): + """ + Return a list of elements of ``self``. + + EXAMPLES:: + + sage: L = LazyDirichletSeriesRing(ZZ, 'z') + sage: L.some_elements() + [0, 1, + 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z)), + 1/(2^z) - 1/(3^z) + 2/4^z - 2/5^z + 3/6^z - 3/7^z + 4/8^z - 4/9^z, + 1/(2^z) - 1/(3^z) + 2/4^z - 2/5^z + 3/6^z - 3/7^z + 4/8^z - 4/9^z + 1/(10^z) + 1/(11^z) + 1/(12^z) + O(1/(13^z)), + 1 + 4/2^z + 9/3^z + 16/4^z + 25/5^z + 36/6^z + 49/7^z + O(1/(8^z))] + + sage: L = LazyDirichletSeriesRing(QQ, 'z') + sage: L.some_elements() + [0, 1, + 1/2/4^z + 1/2/5^z + 1/2/6^z + O(1/(7^z)), + 1/2 - 1/2/2^z + 2/3^z - 2/4^z + 1/(6^z) - 1/(7^z) + 42/8^z + 2/3/9^z, + 1/2 - 1/2/2^z + 2/3^z - 2/4^z + 1/(6^z) - 1/(7^z) + 42/8^z + 2/3/9^z + 1/2/10^z + 1/2/11^z + 1/2/12^z + O(1/(13^z)), + 1 + 4/2^z + 9/3^z + 16/4^z + 25/5^z + 36/6^z + 49/7^z + O(1/(8^z))] + """ + R = self.base_ring() + some_numbers = [c for c, _ in zip(R.some_elements(), range(9))] + elts = [self.zero(), self.one(), self.an_element(), + self(some_numbers), + self(some_numbers, constant = R.an_element()), + self(lambda n: n**2)] + return elts + def _monomial(self, c, n): r""" Return the interpretation of the coefficient ``c`` at index ``n``. From 00aaca080f0be83e5cede0970a035dc084923596 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 18:37:33 +0200 Subject: [PATCH 109/350] introduce halting precision --- src/sage/rings/lazy_series.py | 15 ++++++++++++--- src/sage/rings/lazy_series_ring.py | 10 ++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 23992898376..e7117863580 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -785,7 +785,10 @@ def _richcmp_(self, other, op): return True if self._coeff_stream != other._coeff_stream: return False - raise ValueError("undecidable") + prec = self.parent().options.halting_precision + if prec == None: + raise ValueError("undecidable") + return all(self[i] == other[i] for i in range(m, n + prec)) # Both are Stream_exact, which implements a full check return self._coeff_stream == other._coeff_stream @@ -895,9 +898,15 @@ def __bool__(self): else: if any(a for a in self._coeff_stream._cache): return True - if self[self._coeff_stream._approximate_order]: + + v = self._coeff_stream._approximate_order + if self[v]: return True - raise ValueError("undecidable as lazy Laurent series") + + prec = self.parent().options.halting_precision + if prec == None: + raise ValueError("undecidable as lazy Laurent series") + return any(self[i] for i in range(v, v + prec)) def define(self, s): r""" diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 8a556eaf039..959a382fbbf 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -540,8 +540,9 @@ class options(GlobalOptions): sage: LLS. = LazyLaurentSeriesRing(QQ) sage: LLS.options Current options for lazy series rings - - constant_length: 3 - - display_length: 7 + - constant_length: 3 + - display_length: 7 + - halting_precision: None sage: LLS.options.display_length 7 @@ -574,6 +575,9 @@ class options(GlobalOptions): constant_length = dict(default=3, description='the number of coefficients to display for nonzero constant series', checker=lambda x: x in ZZ and x > 0) + halting_precision = dict(default=None, + description='the number of coefficients, beginning with the approximate valuation, to check in equality tests', + checker=lambda x: x is None or x in ZZ and x > 0) @cached_method def one(self): @@ -901,6 +905,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: sage: L = LazyLaurentSeriesRing(ZZ, 't') + sage: LazyLaurentSeriesRing.options.halting_precision(20) sage: TestSuite(L).run() sage: L.category() Category of infinite commutative no zero divisors algebras over @@ -1234,6 +1239,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: + sage: LazyPowerSeriesRing.options.halting_precision(20) sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run() From f9dd62e7b9db93db213eb4d8b10e7e1f77920a5d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 22:27:08 +0200 Subject: [PATCH 110/350] fix equality of exact series, do not produce coefficients of polynomials by iterating over them --- src/sage/data_structures/stream.py | 27 +++++++++++++++++--- src/sage/rings/lazy_series.py | 40 ++++++++++++++++++++++++------ src/sage/rings/lazy_series_ring.py | 25 +++++++++++++------ 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 0b0c1aa9d87..2fd3fadc3ca 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -544,14 +544,25 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, assert order + len(initial_coefficients) <= self._degree - # We do not insist that the last entry of - # initial_coefficients is different from constant in case - # comparisons can be expensive such as in the symbolic ring, - # but we remove zeros + # we remove leading and trailing zeros from + # initial_coefficients + + # if the degree is order + len(initial_coefficients), we also + # insist that the last entry of initial_coefficients is + # different from constant, because __eq__ below would become + # complicated otherwise + + # TODO: simplify for i, v in enumerate(initial_coefficients): if v: order += i initial_coefficients = initial_coefficients[i:] + if order + len(initial_coefficients) == self._degree: + for j, w in enumerate(reversed(initial_coefficients)): + if w != constant: + break + initial_coefficients.pop() + self._degree -= 1 for j, w in enumerate(reversed(initial_coefficients)): if w: break @@ -600,6 +611,14 @@ def __getitem__(self, n): sage: t = Stream_exact([0, 2, 0], False, order=-2, degree=2, constant=1) sage: t == s True + + sage: s = Stream_exact([0,1,2,1,0,0,1,1], False, constant=1) + sage: [s[i] for i in range(10)] + [0, 1, 2, 1, 0, 0, 1, 1, 1, 1] + + sage: t = Stream_exact([0,1,2,1,0,0], False, constant=1) + sage: s == t + True """ if n >= self._degree: return self._constant diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index e7117863580..2d73b0bfca1 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -760,6 +760,15 @@ def _richcmp_(self, other, op): Traceback (most recent call last): ... ValueError: undecidable + + TESTS:: + + sage: L. = LazyLaurentSeriesRing(QQ) + sage: f = L([0,0,1,0,1,0,0,1], constant=1) + sage: g = L([0,0,1,0,1,0,0], degree=7, constant=1) + sage: f == g + True + """ if op is op_EQ: if isinstance(self._coeff_stream, Stream_zero): # self == 0 @@ -2497,6 +2506,9 @@ def _mul_(self, other): sage: L([1], constant=3)^2 1 + 6*z + 15*z^2 + 24*z^3 + 33*z^4 + 42*z^5 + 51*z^6 + O(z^7) + + sage: (1+z) * L([1,0,1], constant=1) + 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6) """ P = self.parent() left = self._coeff_stream @@ -2515,11 +2527,11 @@ def _mul_(self, other): and right.order() == 0 and not right._constant): return self # right == 1 - # The product is exact if and only if both factors are exact # and one of the factors has eventually 0 coefficients: # (p + a x^d/(1-x))(q + b x^e/(1-x)) # = p q + (a x^d q + b x^e p)/(1-x) + a b x^(d+e)/(1-x)^2 + # TODO: this is not true in characteristic 2 if (isinstance(left, Stream_exact) and isinstance(right, Stream_exact) and not (left._constant and right._constant)): @@ -2538,6 +2550,7 @@ def _mul_(self, other): if right._constant: d = right._degree c = left._constant # this is zero + initial_coefficients.extend([c]*(d - rv - len(ir))) # left._constant must be 0 and thus len(il) >= 1 for k in range(len(il)-1): c += il[k] * right._constant @@ -2546,6 +2559,7 @@ def _mul_(self, other): elif left._constant: d = left._degree c = right._constant # this is zero + initial_coefficients.extend([c]*(d - lv - len(il))) # left._constant must be 0 and thus len(il) >= 1 for k in range(len(ir)-1): c += left._constant * ir[k] @@ -2802,6 +2816,14 @@ def _div_(self, other): sage: (x + y) / (1 - y) (x+y) + (x*y+y^2) + (x*y^2+y^3) + (x*y^3+y^4) + (x*y^4+y^5) + (x*y^5+y^6) + (x*y^6+y^7) + O(x,y)^8 + TESTS: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: t/L(1) + t + + sage: t^3*(1+2*t+3*t^2+4*t^3)/(t-t^2) + t^2 + 3*t^3 + 6*t^4 + 10*t^5 + 10*t^6 + 10*t^7 + O(t^8) """ if isinstance(other._coeff_stream, Stream_zero): raise ZeroDivisionError("cannot divide by 0") @@ -2831,9 +2853,11 @@ def _div_(self, other): den = den // g exponents = den.exponents() if len(exponents) == 1: + # dividing by z^k d = den[exponents[0]] - initial_coefficients = [c / d for c in num] - order = num.valuation() - den.valuation() + v = num.valuation() + initial_coefficients = [num[i] / d for i in range(v, num.degree() + 1)] + order = v - den.valuation() return P.element_class(P, Stream_exact(initial_coefficients, P._sparse, order=order, @@ -2842,6 +2866,7 @@ def _div_(self, other): if (len(exponents) == 2 and exponents[0] + 1 == exponents[1] and den[exponents[0]] == -den[exponents[1]]): + # dividing by z^k (1-z) quo, rem = num.quo_rem(den) # rem is a unit, i.e., in the Laurent case c*z^v v_rem = rem.exponents()[0] @@ -2858,7 +2883,8 @@ def _div_(self, other): order = quo.valuation() else: order = 0 - return P.element_class(P, Stream_exact(list(quo), + initial_coefficients = [quo[i] for i in range(order, quo.degree() + 1)] + return P.element_class(P, Stream_exact(initial_coefficients, P._sparse, order=order, degree=v, @@ -3483,7 +3509,7 @@ def revert(self): sage: f = L([-1, -1], valuation=1, constant=-1) sage: f.revert() - -z - z^2 - z^3 - z^4 - z^5 + O(z^6) + -z - z^2 - z^3 + O(z^4) sage: f = L([-1, 0, -1], valuation=1, constant=-1) sage: f.revert() @@ -3873,7 +3899,7 @@ def compute_coefficients(self, i): doctest:...: DeprecationWarning: the method compute_coefficients obsolete and has no effect. See https://trac.sagemath.org/32367 for details. sage: a - 1 + 2*z + 3*z^2 + 3*z^3 + 3*z^4 + 3*z^5 + O(z^6) + 1 + 2*z + 3*z^2 + 3*z^3 + 3*z^4 + O(z^5) """ from sage.misc.superseded import deprecation deprecation(32367, "the method compute_coefficients obsolete and has no effect.") @@ -4273,7 +4299,7 @@ def revert(self): sage: f = L([-1, -1], valuation=1, constant=-1) sage: f.revert() - (-z) + (-z^2) + (-z^3) + (-z^4) + (-z^5) + O(z^6) + (-z) + (-z^2) + (-z^3) + O(z^4) sage: f = L([-1, 0, -1], valuation=1, constant=-1) sage: f.revert() diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 959a382fbbf..e7be3e97473 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -124,6 +124,12 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No coefficients when evaluated at integers. Examples are provided below. + .. WARNING:: + + If ``x`` is provided as a list, any trailing zeros are + ignored, because ``x`` is immediately converted into a + polynomial. + EXAMPLES: If ``x`` can be converted into an element of the underlying @@ -286,7 +292,6 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: L(z^3/(1-z), valuation=0) 1 + z + z^2 + O(z^3) - sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: L(lambda n: 1/(n+1), degree=3) Traceback (most recent call last): ... @@ -386,6 +391,12 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No constant = BR(constant) if coefficients is None: +# if isinstance(x, (list, tuple)) and degree is None: +# if valuation is None: +# degree = len(x) +# else: +# degree = valuation + len(x) + # Try to build stuff using the internal polynomial ring constructor R = self._internal_poly_ring try: @@ -1037,7 +1048,7 @@ def _an_element_(self): sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: L.an_element() - z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + z^5 + O(z^6) + z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5) """ R = self.base_ring() coeff_stream = Stream_exact([R.an_element(), 3, 0, 2*R.an_element(), 1], @@ -1054,7 +1065,7 @@ def some_elements(self): sage: L.some_elements() [0, 1, z, -3*z^-4 + z^-3 - 12*z^-2 - 2*z^-1 - 10 - 8*z + z^2 + z^3, - z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + z^5 + O(z^6), + z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5), -2*z^-3 - 2*z^-2 + 4*z^-1 + 11 - z - 34*z^2 - 31*z^3 + O(z^4), 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)] @@ -1062,7 +1073,7 @@ def some_elements(self): sage: L.some_elements() [0, 1, z, z^-4 + z^-3 + z^2 + z^3, - z^-1 + z^2 + z^3 + z^4 + z^5 + O(z^6), + z^-1 + z^2 + z^3 + z^4 + O(z^5), 1 + z + z^3 + z^4 + z^6 + O(z^7), z^-1 + z + z^3 + O(z^5)] @@ -1070,7 +1081,7 @@ def some_elements(self): sage: L.some_elements() [0, 1, z, z^-3 + z^-1 + 2 + z + z^2 + z^3, - z^2 + z^3 + z^4 + z^5 + O(z^6), + z^2 + z^3 + z^4 + O(z^5), z^-3 + z^-2 + z^-1 + 2 + 2*z + 2*z^2 + O(z^3), z^-2 + z^-1 + z + z^2 + z^4 + O(z^5)] """ @@ -1615,7 +1626,7 @@ def _an_element_(self): sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.an_element() - z + z^2 + z^3 + z^4 + O(z^5) + z + z^2 + z^3 + O(z^4) """ c = self.base_ring().an_element() R = self._laurent_poly_ring @@ -1667,7 +1678,7 @@ def some_elements(self): [0, 1, z, - z + z^2 + z^3 + z^4 + O(z^5), + z + z^2 + z^3 + O(z^4), -12 - 8*z + z^2 + z^3, 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] From b9a66bed5b72672327ad1335461fe0833f11a0b5 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 22:42:04 +0200 Subject: [PATCH 111/350] implement missing required method lift_to_precision --- src/sage/rings/lazy_series.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 2d73b0bfca1..fe443391ecb 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -722,6 +722,35 @@ def prec(self): """ return infinity + def lift_to_precision(self, absprec=None): + """ + Return another element of the same parent with absolute + precision at least ``absprec``, congruent to this element + modulo the precision of this element. + + Since the precision of a lazy series is infinity, this method + returns the series itself, and the argument is ignored. + + EXAMPLES:: + + sage: P. = PowerSeriesRing(QQ, default_prec=2) + sage: R. = LazyPowerSeriesRing(P) + sage: f = R(lambda n: 1/(1-t)^n) + sage: f + 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + + ((1+3*t+O(t^2))*z^3) + + ((1+4*t+O(t^2))*z^4) + + ((1+5*t+O(t^2))*z^5) + + ((1+6*t+O(t^2))*z^6) + O(z^7) + sage: f.lift_to_precision() + 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + + ((1+3*t+O(t^2))*z^3) + + ((1+4*t+O(t^2))*z^4) + + ((1+5*t+O(t^2))*z^5) + + ((1+6*t+O(t^2))*z^6) + O(z^7) + """ + return self + def _richcmp_(self, other, op): r""" Compare ``self`` with ``other`` with respect to the comparison From 88109cc334038473f7ef9d6318a64fea4a8e5456 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 16 Sep 2022 22:55:32 +0200 Subject: [PATCH 112/350] fix precision also in species directory, do not forget to switch it off after doctest --- .../combinat/species/generating_series.py | 22 +++++++++++++--- src/sage/rings/lazy_series_ring.py | 26 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 54d418b9f2a..6d92f30cf1d 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -143,8 +143,13 @@ def __init__(self, base_ring): TESTS:: sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing + sage: OrdinaryGeneratingSeriesRing.options.halting_precision(15) sage: R = OrdinaryGeneratingSeriesRing(QQ) - sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements"]) + sage: TestSuite(R).run() + + Options are remembered across doctests:: + + sage: OrdinaryGeneratingSeriesRing.options.halting_precision(None) """ super().__init__(base_ring, names="z") @@ -264,8 +269,13 @@ def __init__(self, base_ring): TESTS:: sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing + sage: ExponentialGeneratingSeriesRing.options.halting_precision(15) sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements""]) + sage: TestSuite(R).run() + + Options are remembered across doctests:: + + sage: ExponentialGeneratingSeriesRing.options.halting_precision(None) """ super().__init__(base_ring, names="z") @@ -546,8 +556,13 @@ def __init__(self, base_ring, sparse=True): TESTS:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing + sage: CycleIndexSeriesRing.options.halting_precision(15) sage: R = CycleIndexSeriesRing(QQ) - sage: TestSuite(R).run(skip=["_test_elements", "_test_quo_rem"]) + sage: TestSuite(R).run() + + Options are remembered across doctests:: + + sage: CycleIndexSeriesRing.options.halting_precision(None) """ p = SymmetricFunctions(base_ring).power() super().__init__(p) @@ -659,4 +674,3 @@ def LogarithmCycleIndexSeries(R=QQ): """ CIS = CycleIndexSeriesRing(R) return CIS(_cl_term) - diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index e7be3e97473..07f13153b9e 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -915,8 +915,9 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: + sage: LazyLaurentSeriesRing.options.halting_precision(15) + sage: L = LazyLaurentSeriesRing(ZZ, 't') - sage: LazyLaurentSeriesRing.options.halting_precision(20) sage: TestSuite(L).run() sage: L.category() Category of infinite commutative no zero divisors algebras over @@ -939,6 +940,10 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: E. = ExteriorAlgebra(QQ) sage: L = LazyLaurentSeriesRing(E, 't') # not tested + + Options are remembered across doctests:: + + sage: LazyLaurentSeriesRing.options.halting_precision(None) """ self._sparse = sparse if len(names) != 1: @@ -1250,7 +1255,8 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: - sage: LazyPowerSeriesRing.options.halting_precision(20) + sage: LazyLaurentSeriesRing.options.halting_precision(15) + sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run() @@ -1263,6 +1269,10 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: TestSuite(L).run() + Options are remembered across doctests:: + + sage: LazyLaurentSeriesRing.options.halting_precision(None) + Check that :trac:`34470` is fixed:: sage: L. = LazyPowerSeriesRing(QQ) @@ -1763,6 +1773,8 @@ def __init__(self, basis, sparse=True, category=None): TESTS:: + sage: LazySymmetricFunctions.options.halting_precision(15) + sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() @@ -1771,6 +1783,10 @@ def __init__(self, basis, sparse=True, category=None): sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() + Options are remembered across doctests:: + + sage: LazySymmetricFunctions.options.halting_precision(None) + Check that :trac:`34470` is fixed:: sage: s = SymmetricFunctions(QQ).s() @@ -2115,11 +2131,17 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: + sage: LazyDirichletSeriesRing.options.halting_precision(15) + sage: L = LazyDirichletSeriesRing(ZZ, 't') sage: TestSuite(L).run() sage: L = LazyDirichletSeriesRing(QQ, 't') sage: TestSuite(L).run() + + Options are remembered across doctests:: + + sage: LazyDirichletSeriesRing.options.halting_precision(None) """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") From 08baf9a88210fee39bb5dd84064adddf7d1365e6 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 17 Sep 2022 10:05:48 +0200 Subject: [PATCH 113/350] fix punctuation in docstrings --- src/sage/rings/lazy_series.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index fe443391ecb..3100790088c 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2845,7 +2845,7 @@ def _div_(self, other): sage: (x + y) / (1 - y) (x+y) + (x*y+y^2) + (x*y^2+y^3) + (x*y^3+y^4) + (x*y^4+y^5) + (x*y^5+y^6) + (x*y^6+y^7) + O(x,y)^8 - TESTS: + TESTS:: sage: L. = LazyPowerSeriesRing(QQ) sage: t/L(1) @@ -3000,7 +3000,7 @@ class LazyLaurentSeries(LazyCauchyProductSeries): """ def _im_gens_(self, codomain, im_gens, base_map=None): """ - Returns the image of ``self`` under the map that sends the + Return the image of ``self`` under the map that sends the generators of the parent of ``self`` to the elements of the tuple ``im_gens``. @@ -3936,7 +3936,7 @@ def compute_coefficients(self, i): def _im_gens_(self, codomain, im_gens, base_map=None): """ - Returns the image of ``self`` under the map that sends the + Return the image of ``self`` under the map that sends the generators of the parent of ``self`` to the elements of the tuple ``im_gens``. @@ -3955,6 +3955,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): sage: f = 1/(1+x*q-t) sage: f._im_gens_(S, [s, x*s], base_map=cc) 1 + 2*x*s + 4*x^2*s^2 + 8*x^3*s^3 + 16*x^4*s^4 + 32*x^5*s^5 + 64*x^6*s^6 + O(s^7) + """ if base_map is None: return codomain(self(*im_gens)) From 5bd0331f4210eb4c76eca6bc8b28331931443117 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 17 Sep 2022 13:49:15 +0200 Subject: [PATCH 114/350] correct an_element and some_elements, implement is_unit, _test_invert --- src/sage/combinat/sf/sfa.py | 17 ++++ src/sage/data_structures/stream.py | 5 +- src/sage/rings/lazy_series.py | 97 +++++++++++++++++++++ src/sage/rings/lazy_series_ring.py | 134 +++++++++++++++++++++-------- 4 files changed, 216 insertions(+), 37 deletions(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 1fb9d204e34..cf78bcdb6ae 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -1722,6 +1722,23 @@ def degree_zero_coefficient(self): """ return self.coefficient([]) + def is_unit(self): + """ + Return whether this element is a unit in the ring. + + EXAMPLES:: + + sage: Sym = SymmetricFunctions(QQ) + sage: m = Sym.monomial() + sage: (2*m[2,1] + 3*m[[]]).is_unit() + False + + sage: (3/2*m([])).is_unit() + True + """ + return self.coefficient([]).is_unit() + + #SymmetricFunctionsBases.Filtered = FilteredSymmetricFunctionsBases #SymmetricFunctionsBases.Graded = GradedSymmetricFunctionsBases diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 2fd3fadc3ca..bf9f1db70c2 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1575,9 +1575,10 @@ def __init__(self, series): sage: g = Stream_dirichlet_invert(f) Traceback (most recent call last): ... - AssertionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero + ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero """ - assert series[1], "the Dirichlet inverse only exists if the coefficient with index 1 is non-zero" + if not series[1]: + raise ZeroDivisionError("the Dirichlet inverse only exists if the coefficient with index 1 is non-zero") super().__init__(series, series._is_sparse, 1) self._ainv = ~series[1] diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 3100790088c..eb653f9f53e 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2998,6 +2998,27 @@ class LazyLaurentSeries(LazyCauchyProductSeries): sage: f = 1 / (1 - z - z^2) sage: TestSuite(f).run() """ + def is_unit(self): + """ + Return whether this element is a unit in the ring. + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(ZZ) + sage: (2*z).is_unit() + False + + sage: (1+2*z).is_unit() + True + + sage: (1+2*z^-1).is_unit() + False + """ + if self.is_zero(): # now 0 != 1 + return False + a = self[self.valuation()] + return a.is_unit() + def _im_gens_(self, codomain, im_gens, base_map=None): """ Return the image of ``self`` under the map that sends the @@ -3896,6 +3917,30 @@ class LazyPowerSeries(LazyCauchyProductSeries): sage: g == f True """ + def is_unit(self): + """ + Return whether this element is a unit in the ring. + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(ZZ) + sage: (2*z).is_unit() + False + + sage: (1+2*z).is_unit() + True + + sage: (3+2*z).is_unit() + False + + sage: L. = LazyPowerSeriesRing(ZZ) + sage: (1+2*x+3*x*y).is_unit() + True + """ + if self.is_zero(): # now 0 != 1 + return False + return not self.valuation() and self[0].is_unit() + def exponential(self): r""" Return the exponential series of ``self``. @@ -4705,6 +4750,34 @@ class LazySymmetricFunction(LazyCompletionGradedAlgebraElement): sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) """ + def is_unit(self): + """ + Return whether this element is a unit in the ring. + + EXAMPLES:: + + sage: m = SymmetricFunctions(ZZ).m() + sage: L = LazySymmetricFunctions(m) + + sage: L(2*m[1]).is_unit() + False + + sage: L(1+2*m[1]).is_unit() + True + + sage: L(2+3*m[1]).is_unit() + False + + sage: m = SymmetricFunctions(QQ).m() + sage: L = LazySymmetricFunctions(m) + + sage: L(2+3*m[1]).is_unit() + True + """ + if self.is_zero(): # now 0 != 1 + return False + return not self.valuation() and self[0].is_unit() + def __call__(self, *args, check=True): r""" Return the composition of ``self`` with ``g``. @@ -5569,6 +5642,30 @@ class LazyDirichletSeries(LazyModuleElement): sage: g == f True """ + def is_unit(self): + """ + Return whether this element is a unit in the ring. + + EXAMPLES:: + + sage: D = LazyDirichletSeriesRing(ZZ, "s") + sage: D([0,2]).is_unit() + False + + sage: D([1,2]).is_unit() + True + + sage: D([3,2]).is_unit() + False + + sage: D = LazyDirichletSeriesRing(QQ, "s") + sage: D([3,2]).is_unit() + True + """ + if self.is_zero(): # now 0 != 1 + return False + return not self.valuation() and self[0].is_unit() + def valuation(self): r""" Return the valuation of ``self``. diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 07f13153b9e..74f4c0143e0 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -391,12 +391,6 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No constant = BR(constant) if coefficients is None: -# if isinstance(x, (list, tuple)) and degree is None: -# if valuation is None: -# degree = len(x) -# else: -# degree = valuation + len(x) - # Try to build stuff using the internal polynomial ring constructor R = self._internal_poly_ring try: @@ -759,6 +753,35 @@ def is_exact(self): """ return self.base_ring().is_exact() + def _test_invert(self, **options): + """ + Test multiplicative inversion of elements of this ring. + + INPUT: + + - ``options`` -- any keyword arguments accepted by :meth:`_tester` + + EXAMPLES:: + + sage: Zp(3)._test_invert() + + .. SEEALSO:: + + :class:`TestSuite` + """ + tester = self._tester(**options) + + elements = tester.some_elements() + for x in elements: + try: + y = ~x + except (ZeroDivisionError, ValueError): + tester.assertFalse(x.is_unit()) + else: + e = y * x + tester.assertFalse(x.is_zero()) + tester.assertTrue(e.is_one()) + tester.assertEqual(y.valuation(), -x.valuation()) class LazyLaurentSeriesRing(LazySeriesRing): r""" @@ -1287,9 +1310,12 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L in PrincipalIdealDomains False + The ideal generated by `s` and `t` is not principal:: + sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: L in PrincipalIdealDomains False + """ from sage.structure.category_object import normalize_names names = normalize_names(-1, names) @@ -1636,12 +1662,13 @@ def _an_element_(self): sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.an_element() - z + z^2 + z^3 + O(z^4) + z + + sage: L = LazyPowerSeriesRing(ZZ, 'x, y') + sage: L.an_element() + x """ - c = self.base_ring().an_element() - R = self._laurent_poly_ring - coeff_stream = Stream_exact([R.one()], self._sparse, order=1, constant=c) - return self.element_class(self, coeff_stream) + return self(self._laurent_poly_ring.an_element()) def uniformizer(self): """ @@ -1685,27 +1712,22 @@ def some_elements(self): sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.some_elements() - [0, - 1, - z, - z + z^2 + z^3 + O(z^4), + [0, 1, z, -12 - 8*z + z^2 + z^3, 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') sage: L.some_elements() - [0, - 1, - z, - z + q*z^2 + q*z^3 + q*z^4 + O(z^5), + [0, 1, z, z + z^2 + z^3, 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6), z + z^2 + z^4 + z^5 + O(z^7)] sage: L = LazyPowerSeriesRing(GF(3), 'q, t') sage: L.some_elements() - [0, 1, q, 1, q + q^2 + q^3, + [0, 1, q, + q + q^2 + q^3, 1 + q + q^2 + (-q^3) + (-q^4) + (-q^5) + (-q^6) + O(q,t)^7, 1 + (q+t) + (q^2-q*t+t^2) + (q^3+t^3) + (q^4+q^3*t+q*t^3+t^4) @@ -1713,7 +1735,7 @@ def some_elements(self): + (q^6-q^3*t^3+t^6) + O(q,t)^7] """ z = self.gen(0) - elts = [self.zero(), self.one(), z, self.an_element()] + elts = [self.zero(), self.one(), self.an_element()] if self._arity == 1: elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: n**2)]) else: @@ -1773,7 +1795,7 @@ def __init__(self, basis, sparse=True, category=None): TESTS:: - sage: LazySymmetricFunctions.options.halting_precision(15) + sage: LazySymmetricFunctions.options.halting_precision(7) sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) @@ -1787,9 +1809,10 @@ def __init__(self, basis, sparse=True, category=None): sage: LazySymmetricFunctions.options.halting_precision(None) - Check that :trac:`34470` is fixed:: + Check that :trac:`34470` is fixed. The ideal generated by + `p[1]` and `p[2]` is not principal:: - sage: s = SymmetricFunctions(QQ).s() + sage: p = SymmetricFunctions(QQ).p() sage: L = LazySymmetricFunctions(s) sage: L in PrincipalIdealDomains False @@ -1802,12 +1825,6 @@ def __init__(self, basis, sparse=True, category=None): ... ValueError: basis should be in GradedAlgebrasWithBasis - Check that :trac:`34470` is fixed:: - - sage: s = SymmetricFunctions(QQ).s() - sage: L = LazySymmetricFunctions(s) - sage: L in PrincipalIdealDomains - False """ base_ring = basis.base_ring() self._minimal_valuation = 0 @@ -2074,12 +2091,44 @@ def _an_element_(self): sage: m = SymmetricFunctions(ZZ).m() sage: L = LazySymmetricFunctions(m) sage: L.an_element() - m[] + 2*m[] + 2*m[1] + 3*m[2] """ - R = self._laurent_poly_ring - coeff_stream = Stream_exact([R.one()], self._sparse, order=1, constant=0) - return self.element_class(self, coeff_stream) + return self(self._laurent_poly_ring.an_element()) + + def some_elements(self): + """ + Return a list of elements of ``self``. + + EXAMPLES:: + + sage: m = SymmetricFunctions(GF(5)).m() + sage: L = LazySymmetricFunctions(m) + sage: L.some_elements() + [0, m[], 2*m[] + 2*m[1] + 3*m[2], + 3*m[] + 2*m[1] + (m[1,1]+m[2]) + + (2*m[1,1,1]+m[3]) + + (2*m[1,1,1,1]+4*m[2,1,1]+2*m[2,2]) + + (3*m[2,1,1,1]+3*m[3,1,1]+4*m[3,2]+m[5]) + + (2*m[2,2,1,1]+m[2,2,2]+2*m[3,2,1]+2*m[3,3]+m[4,1,1]+3*m[4,2]+4*m[5,1]+4*m[6]) + + O^7] + + sage: NCSF = NonCommutativeSymmetricFunctions(QQ) + sage: S = NCSF.Complete() + sage: L = S.formal_series_ring() + sage: L.some_elements() + [0, S[], 2*S[] + 2*S[1] + (3*S[1,1])] + """ + elt = self.an_element() + elts = [self.zero(), self.one(), elt] + try: + if elt.is_unit(): + elts.append(~elt) + else: + elts.append(~(1-elt[0]+elt)) + except NotImplementedError: + pass + return elts ###################################################################### @@ -2142,6 +2191,21 @@ def __init__(self, base_ring, names, sparse=True, category=None): Options are remembered across doctests:: sage: LazyDirichletSeriesRing.options.halting_precision(None) + + The ideal generated by `2^-s` and `3^-s` is not principal:: + + sage: L = LazyDirichletSeriesRing(QQ, 's') + sage: L in PrincipalIdealDomains + False + + In particular, it is not a :wikipedia:`discrete_valuation_ring`. + + .. TODO:: + + According to the answers in + https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd, + the ring of formal Dirichlet series is actually a + UniqueFactorizationDomain. """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") @@ -2358,7 +2422,7 @@ def some_elements(self): some_numbers = [c for c, _ in zip(R.some_elements(), range(9))] elts = [self.zero(), self.one(), self.an_element(), self(some_numbers), - self(some_numbers, constant = R.an_element()), + self(some_numbers, constant=R.an_element()), self(lambda n: n**2)] return elts From 1722eca9a24029683fd137eda0fbc063cd044fad Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 17 Sep 2022 17:00:46 +0200 Subject: [PATCH 115/350] fix is_unit --- src/sage/combinat/sf/sfa.py | 9 +++++---- src/sage/rings/lazy_series.py | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index cf78bcdb6ae..ce9a3fe8f26 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -1728,15 +1728,16 @@ def is_unit(self): EXAMPLES:: - sage: Sym = SymmetricFunctions(QQ) - sage: m = Sym.monomial() - sage: (2*m[2,1] + 3*m[[]]).is_unit() + sage: m = SymmetricFunctions(ZZ).monomial() + sage: (2*m[2,1] + m[[]]).is_unit() False + sage: m = SymmetricFunctions(QQ).monomial() sage: (3/2*m([])).is_unit() True """ - return self.coefficient([]).is_unit() + m = self.monomial_coefficients(copy=False) + return len(m) <= 1 and self.coefficient([]).is_unit() #SymmetricFunctionsBases.Filtered = FilteredSymmetricFunctionsBases diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index eb653f9f53e..fc20cf11de5 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3939,7 +3939,7 @@ def is_unit(self): """ if self.is_zero(): # now 0 != 1 return False - return not self.valuation() and self[0].is_unit() + return self[0].is_unit() def exponential(self): r""" @@ -4776,7 +4776,7 @@ def is_unit(self): """ if self.is_zero(): # now 0 != 1 return False - return not self.valuation() and self[0].is_unit() + return self[0].is_unit() def __call__(self, *args, check=True): r""" @@ -5664,7 +5664,7 @@ def is_unit(self): """ if self.is_zero(): # now 0 != 1 return False - return not self.valuation() and self[0].is_unit() + return self[1].is_unit() def valuation(self): r""" From cdf821a895d6c4ed46992d209cb5cdfbb6ae6d39 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 17 Sep 2022 23:10:33 +0200 Subject: [PATCH 116/350] improve equality, raise errors when trying to invert series which are known not to be invertible, be more careful not to compute terms --- src/sage/data_structures/stream.py | 118 ++++++++++++++++++++--------- src/sage/rings/lazy_series.py | 117 +++++++++++++++++++++------- src/sage/rings/lazy_series_ring.py | 8 +- 3 files changed, 177 insertions(+), 66 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index bf9f1db70c2..224559f8785 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -113,7 +113,7 @@ class Stream(): - ``approximate_order`` -- integer; a lower bound for the order of the stream """ - def __init__(self, sparse, approximate_order): + def __init__(self, sparse, approximate_order, true_order=None): """ Initialize ``self``. @@ -124,6 +124,7 @@ def __init__(self, sparse, approximate_order): """ self._is_sparse = sparse self._approximate_order = approximate_order + self._true_order = true_order def __ne__(self, other): """ @@ -160,7 +161,6 @@ def is_nonzero(self): """ return False - class Stream_inexact(Stream): """ An abstract base class for the stream when we do not know it is @@ -183,8 +183,8 @@ class Stream_inexact(Stream): """ def __init__(self, is_sparse, approximate_order): """ - Initialize the stream class for a Stream when it is not - or it cannot be determined if it is eventually geometric. + Initialize the stream class for a stream whose + coefficients are not necessarily eventally constant. TESTS:: @@ -193,6 +193,7 @@ def __init__(self, is_sparse, approximate_order): sage: g = Stream_function(lambda n: n, False, 0) sage: isinstance(g, Stream_inexact) True + """ super().__init__(is_sparse, approximate_order) @@ -200,7 +201,7 @@ def __init__(self, is_sparse, approximate_order): self._cache = dict() # cache of known coefficients else: self._cache = list() - self._offset = approximate_order + self._offset = approximate_order # self[n] = self._cache[n-self._offset] self._iter = self.iterate_coefficients() def is_nonzero(self): @@ -358,7 +359,7 @@ def iterate_coefficients(self): sage: [next(n) for i in range(10)] [1, 9, 44, 207, 991, 4752, 22769, 109089, 522676, 2504295] """ - n = self._approximate_order # TODO: shouldn't this be self._offset? + n = self._approximate_order while True: yield self.get_coefficient(n) n += 1 @@ -375,18 +376,20 @@ def order(self): sage: f.order() 1 """ + if self._true_order is not None: + return self._true_order if self._is_sparse: n = self._approximate_order cache = self._cache while True: if n in cache: if cache[n]: - self._approximate_order = n + self._approximate_order = self._true_order = n return n n += 1 else: if self[n]: - self._approximate_order = n + self._approximate_order = self._true_order = n return n n += 1 else: @@ -395,12 +398,12 @@ def order(self): while True: if n - self._offset < len(cache): if cache[n - self._offset]: - self._approximate_order = n + self._approximate_order = self._true_order = n return n n += 1 else: if self[n]: - self._approximate_order = n + self._approximate_order = self._true_order = n return n n += 1 @@ -575,7 +578,7 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, assert self._initial_coefficients or self._constant, "Stream_exact should only be used for non-zero streams" - super().__init__(is_sparse, order) + super().__init__(is_sparse, order, true_order=order) def __getitem__(self, n): """ @@ -629,8 +632,8 @@ def __getitem__(self, n): def order(self): r""" - Return the order of ``self``, which is the minimum index ``n`` such - that ``self[n]`` is nonzero. + Return the order of ``self``, which is the minimum index + ``n`` such that ``self[n]`` is nonzero. EXAMPLES:: @@ -638,8 +641,9 @@ def order(self): sage: s = Stream_exact([1], False) sage: s.order() 0 + """ - return self._approximate_order + return self._true_order def __hash__(self): """ @@ -697,7 +701,8 @@ def __eq__(self, other): def __ne__(self, other): """ - Test inequality between ``self`` and ``other``. + Test inequality between ``self`` and ``other``, where + other is exact or inexact, but not zero. INPUT: @@ -728,12 +733,24 @@ def __ne__(self, other): [0, 0, 0, 2, 1, 1, 1, 1] sage: [f[i] for i in range(-3, 5)] [0, 0, 0, 2, 1, 1, 1, 1] + """ if isinstance(other, type(self)): return (self._degree != other._degree or self._approximate_order != other._approximate_order or self._initial_coefficients != other._initial_coefficients or self._constant != other._constant) + # if other is not exact, we can at least compare with the + # elements in its cache + if other._is_sparse: + for i in other._cache: + if self[i] != other._cache[i]: + return True + else: + if other._offset > self._true_order: + return False + return any(self[i] != c for i, c in enumerate(other._cache, other._offset)) + return False def is_nonzero(self): @@ -1185,7 +1202,7 @@ def __init__(self, sparse): sage: s = Stream_zero(False) sage: TestSuite(s).run() """ - return super().__init__(sparse, 0) + return super().__init__(sparse, infinity, true_order=infinity) def __getitem__(self, n): """ @@ -1217,7 +1234,7 @@ def order(self): sage: s.order() +Infinity """ - return infinity + return self._true_order def __eq__(self, other): """ @@ -1577,11 +1594,11 @@ def __init__(self, series): ... ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero """ - if not series[1]: + if series._approximate_order > 1: raise ZeroDivisionError("the Dirichlet inverse only exists if the coefficient with index 1 is non-zero") - super().__init__(series, series._is_sparse, 1) - self._ainv = ~series[1] + super().__init__(series, series._is_sparse, 1) + self._ainv = None self._zero = ZZ.zero() def get_coefficient(self, n): @@ -1602,6 +1619,8 @@ def get_coefficient(self, n): sage: [g[i] for i in range(8)] [0, 1/3, -2/9, -2/9, -2/27, -2/9, 2/27, -2/9] """ + if self._ainv is None: + self._ainv = ~self._series[1] if n == 1: return self._ainv c = self._zero @@ -1647,7 +1666,8 @@ def __init__(self, f, g): sage: g = Stream_function(lambda n: n^2, True, 1) sage: h = Stream_cauchy_compose(f, g) """ - #assert g._approximate_order > 0 + if g._true_order is not None and g._true_order <= 0: + raise ValueError("can only compose with a series of positive valuation") if f._approximate_order < 0: ginv = Stream_cauchy_invert(g) # The constant part makes no contribution to the negative. @@ -1655,7 +1675,7 @@ def __init__(self, f, g): self._neg_powers = [Stream_zero(f._is_sparse), ginv] for i in range(1, -f._approximate_order): self._neg_powers.append(Stream_cauchy_mul(self._neg_powers[-1], ginv)) - # Placeholder None to make this 1-based. + # placeholder None to make this 1-based. self._pos_powers = [None, g] val = f._approximate_order * g._approximate_order super().__init__(f, g, f._is_sparse, val) @@ -1793,7 +1813,13 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): sage: g = Stream_function(lambda n: s[n-1,1], True, 2) sage: h = Stream_plethysm(f, g, p) """ - # assert g._approximate_order > 0 + if isinstance(f, Stream_exact): + self._degree_f = f._degree + else: + self._degree_f = None + if g._true_order is not None and g._true_order == 0 and self._degree_f is None: + raise ValueError("can only compute plethysm with a series of valuation 0 for symmetric functions of finite support") + val = f._approximate_order * g._approximate_order if ring is None: self._basis = p @@ -1804,10 +1830,7 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): self._powers = [g] # a cache for the powers of g R = self._basis.base_ring() self._degree_one = _variables_recursive(R, include=include, exclude=exclude) - if isinstance(f, Stream_exact) and not f._constant: - self._degree_f = f._degree - else: - self._degree_f = None + if HopfAlgebrasWithBasis(R).TensorProducts() in p.categories(): self._tensor_power = len(p._sets) p_f = p._sets[0] @@ -1869,7 +1892,7 @@ def compute_product(self, n, la): sage: from sage.data_structures.stream import Stream_plethysm, Stream_exact, Stream_function, Stream_zero sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() - sage: f = Stream_zero(True) # irrelevant for this test + sage: f = Stream_exact([1], False) # irrelevant for this test sage: g = Stream_exact([s[2], s[3]], False, 0, 4, 2) sage: h = Stream_plethysm(f, g, p) sage: A = h.compute_product(7, Partition([2, 1])); A @@ -1879,7 +1902,7 @@ def compute_product(self, n, la): True sage: p2 = tensor([p, p]) - sage: f = Stream_zero(True) # irrelevant for this test + sage: f = Stream_exact([1], True) # irrelevant for this test sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) for k in range(n+1)), True, 1) sage: h = Stream_plethysm(f, g, p2) sage: A = h.compute_product(7, Partition([2, 1])) @@ -1888,7 +1911,7 @@ def compute_product(self, n, la): sage: A == B True - sage: f = Stream_zero(True) # irrelevant for this test + sage: f = Stream_exact([1], True) # irrelevant for this test sage: g = Stream_function(lambda n: s[n], True, 0) sage: h = Stream_plethysm(f, g, p) sage: B = p[2, 2, 1](sum(s[i] for i in range(7))) @@ -1929,7 +1952,7 @@ def stretched_power_restrict_degree(self, i, m, d): sage: from sage.data_structures.stream import Stream_plethysm, Stream_exact, Stream_function, Stream_zero sage: s = SymmetricFunctions(QQ).s() sage: p = SymmetricFunctions(QQ).p() - sage: f = Stream_zero(False) # irrelevant for this test + sage: f = Stream_exact([1], False) # irrelevant for this test sage: g = Stream_exact([s[2], s[3]], False, 0, 4, 2) sage: h = Stream_plethysm(f, g, p) sage: A = h.stretched_power_restrict_degree(2, 3, 6) @@ -1937,7 +1960,7 @@ def stretched_power_restrict_degree(self, i, m, d): True sage: p2 = tensor([p, p]) - sage: f = Stream_zero(True) # irrelevant for this test + sage: f = Stream_exact([1], True) # irrelevant for this test sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) for k in range(n+1)), True, 1) sage: h = Stream_plethysm(f, g, p2) sage: A = h.stretched_power_restrict_degree(2, 3, 6) @@ -2210,6 +2233,9 @@ class Stream_cauchy_invert(Stream_unary): - ``series`` -- a :class:`Stream` + - ``approximate_order`` -- ``None``, or an upper (!) bound on the + order of ``series`` + EXAMPLES:: sage: from sage.data_structures.stream import (Stream_cauchy_invert, Stream_function) @@ -2217,8 +2243,9 @@ class Stream_cauchy_invert(Stream_unary): sage: g = Stream_cauchy_invert(f) sage: [g[i] for i in range(10)] [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0] + """ - def __init__(self, series): + def __init__(self, series, approximate_order=None): """ Initialize ``self``. @@ -2228,10 +2255,14 @@ def __init__(self, series): sage: f = Stream_exact([1, -1], False) sage: g = Stream_cauchy_invert(f) """ - v = series.order() - super().__init__(series, series._is_sparse, -v) + if approximate_order is None: + v = series.order() + self._ainv = ~series[v] + else: + v = approximate_order + self._ainv = None - self._ainv = ~series[v] + super().__init__(series, series._is_sparse, -v) self._zero = ZZ.zero() def get_coefficient(self, n): @@ -2252,9 +2283,16 @@ def get_coefficient(self, n): sage: [g.get_coefficient(i) for i in range(10)] [-2, 1, 0, 0, 0, 0, 0, 0, 0, 0] """ + if self._ainv is None: + self._approximate_order = -self._series.order() + self._ainv = ~self._series[self._approximate_order] + + # if self._ainv is not None, self._approximate_order is the + # true order v = self._approximate_order if n == v: return self._ainv + c = self._zero for k in range(v, n): l = self[k] @@ -2275,11 +2313,19 @@ def iterate_coefficients(self): sage: [next(n) for i in range(10)] [1, -4, 7, -8, 8, -8, 8, -8, 8, -8] """ + if self._ainv is None: + self._approximate_order = -self._series.order() + self._ainv = ~self._series[self._approximate_order] + + # if self._ainv is not None, self._approximate_order is the + # true order v = self._approximate_order n = 0 # Counts the number of places from v. yield self._ainv # Note that the first entry of the cache will correspond to # z^v, when the stream corresponds to a Laurent series. + + # TODO: don't we need to distinguish between sparse and dense here? while True: n += 1 c = self._zero diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index fc20cf11de5..b88a9738c98 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -800,36 +800,39 @@ def _richcmp_(self, other, op): """ if op is op_EQ: - if isinstance(self._coeff_stream, Stream_zero): # self == 0 + if isinstance(self._coeff_stream, Stream_zero): if isinstance(other._coeff_stream, Stream_zero): return True if other._coeff_stream.is_nonzero(): return False - # other == 0 but self likely != 0 - elif (isinstance(other._coeff_stream, Stream_zero) - and self._coeff_stream.is_nonzero()): - return False - - if (not isinstance(self._coeff_stream, Stream_exact) - or not isinstance(other._coeff_stream, Stream_exact)): - # One of the lazy laurent series is not known to eventually be constant - # Implement the checking of the caches here. - n = min(self._coeff_stream._approximate_order, other._coeff_stream._approximate_order) - m = max(self._coeff_stream._approximate_order, other._coeff_stream._approximate_order) - for i in range(n, m): - if self[i] != other[i]: - return False + elif isinstance(other._coeff_stream, Stream_zero): + if self._coeff_stream.is_nonzero(): + return False + elif isinstance(self._coeff_stream, Stream_exact): + if isinstance(other._coeff_stream, Stream_exact): + return self._coeff_stream == other._coeff_stream + if self._coeff_stream != other._coeff_stream: + return False + elif isinstance(other._coeff_stream, Stream_exact): + if other._coeff_stream != self._coeff_stream: + return False + else: + # both streams are inexact, perhaps they are equal by + # construction if self._coeff_stream == other._coeff_stream: return True + # perhaps their caches are different if self._coeff_stream != other._coeff_stream: return False - prec = self.parent().options.halting_precision - if prec == None: - raise ValueError("undecidable") - return all(self[i] == other[i] for i in range(m, n + prec)) - # Both are Stream_exact, which implements a full check - return self._coeff_stream == other._coeff_stream + # undecidable otherwise + prec = self.parent().options.halting_precision + if prec == None: + raise ValueError("undecidable") + # at least one of the approximate orders is not infinity + m = min(self._coeff_stream._approximate_order, + other._coeff_stream._approximate_order) + return all(self[i] == other[i] for i in range(m, m + prec)) if op is op_NE: return not (self == other) @@ -947,8 +950,7 @@ def __bool__(self): return any(self[i] for i in range(v, v + prec)) def define(self, s): - r""" - Define an equation by ``self = s``. + r"""Define an equation by ``self = s``. INPUT: @@ -1113,6 +1115,25 @@ def define(self, s): ... ValueError: the valuation must be specified for undefined series + For power series and Dirichlet series there is a minimal + valuation, which is why the following work:: + + sage: P. = LazyPowerSeriesRing(QQ) + sage: f = P.undefined() + sage: f.define(1 - ~f*x) + sage: f + 1 - x - x^2 - 2*x^3 - 5*x^4 - 14*x^5 - 42*x^6 + O(x^7) + + sage: D = LazyDirichletSeriesRing(QQ, "s") + sage: g = D([0, 1]) + sage: f = D.undefined() + sage: f.define(1 + ~f*g) + sage: f + 1 + 1/(2^s) - 1/(4^s) + O(1/(8^s)) + + sage: oeis(f[:30]) # optional, internet + 0: A122698: a(1)=a(2)=1 then a(n) = Sum_{d|n, 1 = LazyPowerSeriesRing(QQ) + sage: ~(x + x^2) + Traceback (most recent call last): + ... + ZeroDivisionError: cannot divide by a series of positive valuation """ P = self.parent() coeff_stream = self._coeff_stream + if P._minimal_valuation is not None and coeff_stream._approximate_order > 0: + raise ZeroDivisionError("cannot divide by a series of positive valuation") + # the inverse is exact if and only if coeff_stream corresponds to one of # cx^d/(1-x) ... (c, ...) # cx^d ... (c, 0, ...) @@ -2779,7 +2808,9 @@ def __invert__(self): # (f^-1)^-1 = f if isinstance(coeff_stream, Stream_cauchy_invert): return P.element_class(P, coeff_stream._series) - return P.element_class(P, Stream_cauchy_invert(coeff_stream)) + + return P.element_class(P, Stream_cauchy_invert(coeff_stream, + approximate_order=P._minimal_valuation)) def _div_(self, other): r""" @@ -2848,11 +2879,20 @@ def _div_(self, other): TESTS:: sage: L. = LazyPowerSeriesRing(QQ) - sage: t/L(1) + sage: t / L(1) t sage: t^3*(1+2*t+3*t^2+4*t^3)/(t-t^2) t^2 + 3*t^3 + 6*t^4 + 10*t^5 + 10*t^6 + 10*t^7 + O(t^8) + + sage: t^3*((1+2*t+3*t^2+4*t^3)/(t-t^2)) + Traceback (most recent call last): + ... + ZeroDivisionError: cannot divide by a series of larger valuation + + sage: L(lambda n: n) / (t + t^2) + 1 + t + 2*t^2 + 2*t^3 + 3*t^4 + 3*t^5 + O(t^6) + """ if isinstance(other._coeff_stream, Stream_zero): raise ZeroDivisionError("cannot divide by 0") @@ -2862,6 +2902,11 @@ def _div_(self, other): if isinstance(left, Stream_zero): return P.zero() right = other._coeff_stream + if (P._minimal_valuation is not None + and left._true_order is not None + and left._true_order < right._approximate_order): + raise ZeroDivisionError("cannot divide by a series of larger valuation") + R = P._internal_poly_ring if (isinstance(left, Stream_exact) and isinstance(right, Stream_exact) @@ -2924,7 +2969,8 @@ def _div_(self, other): degree=v, constant=constant)) - return P.element_class(P, Stream_cauchy_mul(left, Stream_cauchy_invert(right))) + right_inverse = Stream_cauchy_invert(right) + return P.element_class(P, Stream_cauchy_mul(left, right_inverse)) class LazyLaurentSeries(LazyCauchyProductSeries): @@ -3621,6 +3667,7 @@ def revert(self): z = P.gen() g = P.undefined(valuation=1) + # TODO: shift instead of (self / z) should be more efficient g.define(z / ((self / z)(g))) return g @@ -4424,6 +4471,7 @@ def revert(self): z = P.gen() g = P.undefined(valuation=1) + # TODO: shift instead of (self / z) should be more efficient g.define(z / ((self / z)(g))) return g @@ -5785,6 +5833,23 @@ def __invert__(self): sage: ~L(constant=1) - L(moebius) O(1/(8^z)) + Trying to invert a non-invertible 'exact' series raises a + ``ZeroDivisionError``: + + sage: _ = ~L([0,1], constant=1) + Traceback (most recent call last): + ... + ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero + + If the series is not 'exact', we cannot do this without + actually computing a term. + + sage: f = ~L(lambda n: n-1) + sage: f[1] + Traceback (most recent call last): + ... + ZeroDivisionError: rational division by zero + """ P = self.parent() return P.element_class(P, Stream_dirichlet_invert(self._coeff_stream)) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 74f4c0143e0..ca2ccf29f2c 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -773,11 +773,11 @@ def _test_invert(self, **options): elements = tester.some_elements() for x in elements: - try: + # because of lazyness, we cannot try to invert x, because + # this will always succeed, except if the series is + # 'exact' + if x.is_unit(): y = ~x - except (ZeroDivisionError, ValueError): - tester.assertFalse(x.is_unit()) - else: e = y * x tester.assertFalse(x.is_zero()) tester.assertTrue(e.is_one()) From 54bb1d846a2d67bac36bbadc658d5e9fce574d60 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 18 Sep 2022 13:34:37 +0200 Subject: [PATCH 117/350] add _test_revert and add more rings to test --- src/sage/rings/lazy_series_ring.py | 96 ++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ca2ccf29f2c..6cd4706a61e 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -763,7 +763,10 @@ def _test_invert(self, **options): EXAMPLES:: - sage: Zp(3)._test_invert() + sage: LazyLaurentSeriesRing.options.halting_precision(5) + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L._test_invert() + sage: LazyLaurentSeriesRing.options._reset() .. SEEALSO:: @@ -783,6 +786,47 @@ def _test_invert(self, **options): tester.assertTrue(e.is_one()) tester.assertEqual(y.valuation(), -x.valuation()) + def _test_revert(self, **options): + """ + Test compositional inverse of elements of this ring. + + INPUT: + + - ``options`` -- any keyword arguments accepted by :meth:`_tester` + + EXAMPLES:: + + sage: LazyLaurentSeriesRing.options.halting_precision(5) + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L._test_revert() + sage: LazyLaurentSeriesRing.options._reset() + + .. SEEALSO:: + + :class:`TestSuite` + """ + if not hasattr(self.element_class, "revert") or self._arity != 1: + return + tester = self._tester(**options) + + elements = tester.some_elements() + count = 0 + for x in elements: + vx = x.valuation() + try: + y = x.revert() + vy = y.valuation() + except ValueError: + tester.assertFalse(vx == 1) + else: + count += 1 + e1 = y(x) + e2 = x(y) + tester.assertEqual(e1, e2, "y(x) and x(y) differ for x = %s and y = %s" %(x, y)) + # tester.assertEqual(e1, self.gen()) + # we want to test at least 2 elements + tester.assertGreater(count, 1, msg="only %s elements in %s.some_elements() have a compositional inverse" % (count, self)) + class LazyLaurentSeriesRing(LazySeriesRing): r""" The ring of lazy Laurent series. @@ -961,6 +1005,15 @@ def __init__(self, base_ring, names, sparse=True, category=None): (euclidean domains and infinite enumerated sets and metric spaces) and infinite sets) + sage: L = LazyLaurentSeriesRing(GF(5), 't') + sage: TestSuite(L).run() + + sage: L = LazyLaurentSeriesRing(GF(5)['x'], 't') + sage: TestSuite(L).run() + + sage: L = LazyLaurentSeriesRing(GF(5)['x, y'], 't') + sage: TestSuite(L).run() + sage: E. = ExteriorAlgebra(QQ) sage: L = LazyLaurentSeriesRing(E, 't') # not tested @@ -1090,7 +1143,7 @@ def some_elements(self): EXAMPLES:: sage: L = LazyLaurentSeriesRing(ZZ, 'z') - sage: L.some_elements() + sage: L.some_elements()[:7] [0, 1, z, -3*z^-4 + z^-3 - 12*z^-2 - 2*z^-1 - 10 - 8*z + z^2 + z^3, z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5), @@ -1098,7 +1151,7 @@ def some_elements(self): 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)] sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: L.some_elements() + sage: L.some_elements()[:7] [0, 1, z, z^-4 + z^-3 + z^2 + z^3, z^-1 + z^2 + z^3 + z^4 + O(z^5), @@ -1106,7 +1159,7 @@ def some_elements(self): z^-1 + z + z^3 + O(z^5)] sage: L = LazyLaurentSeriesRing(GF(3), 'z') - sage: L.some_elements() + sage: L.some_elements()[:7] [0, 1, z, z^-3 + z^-1 + 2 + z + z^2 + z^3, z^2 + z^3 + z^4 + O(z^5), @@ -1115,7 +1168,10 @@ def some_elements(self): """ z = self.gen() elts = [self.zero(), self.one(), z, (z-3)*(z**-2+2+z)**2, self.an_element(), - (1 - 2*z**-3)/(1 - z + 3*z**2), self(lambda n: n**2, valuation=-2)] + (1 - 2*z**-3)/(1 - z + 3*z**2), + self(lambda n: n**2, valuation=-2), + self(lambda n: n**2, valuation=1), + self([3, 2, 1], valuation=1, constant=1)] return elts def series(self, coefficient, valuation, degree=None, constant=None): @@ -1292,6 +1348,12 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: TestSuite(L).run() + sage: L = LazyPowerSeriesRing(GF(5), 't') + sage: TestSuite(L).run() + + sage: L = LazyPowerSeriesRing(GF(5), 's, t') + sage: TestSuite(L).run() + Options are remembered across doctests:: sage: LazyLaurentSeriesRing.options.halting_precision(None) @@ -1711,21 +1773,21 @@ def some_elements(self): EXAMPLES:: sage: L = LazyPowerSeriesRing(ZZ, 'z') - sage: L.some_elements() + sage: L.some_elements()[:6] [0, 1, z, -12 - 8*z + z^2 + z^3, 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') - sage: L.some_elements() + sage: L.some_elements()[:6] [0, 1, z, z + z^2 + z^3, 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6), z + z^2 + z^4 + z^5 + O(z^7)] sage: L = LazyPowerSeriesRing(GF(3), 'q, t') - sage: L.some_elements() + sage: L.some_elements()[:6] [0, 1, q, q + q^2 + q^3, 1 + q + q^2 + (-q^3) + (-q^4) + (-q^5) + (-q^6) + O(q,t)^7, @@ -1805,6 +1867,14 @@ def __init__(self, basis, sparse=True, category=None): sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() + sage: s = SymmetricFunctions(QQ["q"]).s() + sage: L = LazySymmetricFunctions(s) + sage: TestSuite(L).run() + + sage: s = SymmetricFunctions(GF(5)).s() + sage: L = LazySymmetricFunctions(s) + sage: TestSuite(L).run() + Options are remembered across doctests:: sage: LazySymmetricFunctions.options.halting_precision(None) @@ -2104,7 +2174,7 @@ def some_elements(self): sage: m = SymmetricFunctions(GF(5)).m() sage: L = LazySymmetricFunctions(m) sage: L.some_elements() - [0, m[], 2*m[] + 2*m[1] + 3*m[2], + [0, m[], 2*m[] + 2*m[1] + 3*m[2], 2*m[1] + 3*m[2], 3*m[] + 2*m[1] + (m[1,1]+m[2]) + (2*m[1,1,1]+m[3]) + (2*m[1,1,1,1]+4*m[2,1,1]+2*m[2,2]) @@ -2116,16 +2186,17 @@ def some_elements(self): sage: S = NCSF.Complete() sage: L = S.formal_series_ring() sage: L.some_elements() - [0, S[], 2*S[] + 2*S[1] + (3*S[1,1])] + [0, S[], 2*S[] + 2*S[1] + (3*S[1,1]), 2*S[1] + (3*S[1,1])] """ elt = self.an_element() elts = [self.zero(), self.one(), elt] + elts.append(elt - elt[0]) try: if elt.is_unit(): elts.append(~elt) else: - elts.append(~(1-elt[0]+elt)) + elts.append(~(1 - elt[0] + elt)) except NotImplementedError: pass return elts @@ -2175,7 +2246,7 @@ class LazyDirichletSeriesRing(LazySeriesRing): Element = LazyDirichletSeries def __init__(self, base_ring, names, sparse=True, category=None): - """ + r""" Initialize the ring. TESTS:: @@ -2206,6 +2277,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd, the ring of formal Dirichlet series is actually a UniqueFactorizationDomain. + """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") From 3d5b8cf4c836ceb8813aa6311fe18b1f5fbffc6a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 18 Sep 2022 20:42:05 +0900 Subject: [PATCH 118/350] Last little things from the patchbot. --- src/sage/combinat/species/all.py | 7 +++++-- src/sage/combinat/species/generating_series.py | 2 +- src/sage/combinat/species/library.py | 17 ++++++++++------- src/sage/rings/lazy_series.py | 9 +++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 95c495603bb..9480757bd88 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -44,5 +44,8 @@ from sage.misc.namespace_package import install_doc install_doc(__package__, __doc__) -from .recursive_species import CombinatorialSpecies -from . import library as species +from sage.misc.lazy_import import lazy_import +lazy_import("sage.combinat.species.recursive_species", "CombinatorialSpecies") +lazy_import("sage.combinat.species", "library", as_="species") +del lazy_import + diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 54d418b9f2a..f807b040c2a 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -265,7 +265,7 @@ def __init__(self, base_ring): sage: from sage.combinat.species.generating_series import ExponentialGeneratingSeriesRing sage: R = ExponentialGeneratingSeriesRing(QQ) - sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements""]) + sage: TestSuite(R).run(skip=["_test_associativity", "_test_distributivity", "_test_elements"]) """ super().__init__(base_ring, names="z") diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index 4b63b1a4730..1be68456688 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -35,7 +35,7 @@ @cached_function def SimpleGraphSpecies(): """ - Returns the species of simple graphs. + Return the species of simple graphs. EXAMPLES:: @@ -73,11 +73,10 @@ def SimpleGraphSpecies(): @cached_function def BinaryTreeSpecies(): r""" - Return the species of binary trees on n leaves. + Return the species of binary trees on `n` leaves. - The species of - binary trees B is defined by B = X + B\*B where X is the singleton - species. + The species of binary trees `B` is defined by `B = X + B \cdot B`, + where `X` is the singleton species. EXAMPLES:: @@ -111,8 +110,9 @@ def BinaryTreeSpecies(): @cached_function def BinaryForestSpecies(): """ - Returns the species of binary forests. Binary forests are defined - as sets of binary trees. + Return the species of binary forests. + + Binary forests are defined as sets of binary trees. EXAMPLES:: @@ -140,3 +140,6 @@ def BinaryForestSpecies(): S = SetSpecies() F = S(B) return F + +del cached_function # so it doesn't get picked up by tab completion + diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 23992898376..2cd8dba99de 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2936,7 +2936,7 @@ class LazyLaurentSeries(LazyCauchyProductSeries): """ def _im_gens_(self, codomain, im_gens, base_map=None): """ - Returns the image of ``self`` under the map that sends the + Return the image of ``self`` under the map that sends the generators of the parent of ``self`` to the elements of the tuple ``im_gens``. @@ -2949,12 +2949,13 @@ def _im_gens_(self, codomain, im_gens, base_map=None): sage: f -t^-2 - i*t^-1 + 1 + i*t - t^2 - i*t^3 + t^4 + O(t^5) sage: f._im_gens_(R, [t + t^2]) - -t^-2 + (-i + 2)*t^-1 + (i - 2) + 4*t + (2*i - 6)*t^2 + (-2*i + 4)*t^3 + (-2*i - 7)*t^4 + O(t^5) + -t^-2 + (-i + 2)*t^-1 + (i - 2) + 4*t + (2*i - 6)*t^2 + + (-2*i + 4)*t^3 + (-2*i - 7)*t^4 + O(t^5) sage: cc = K.hom([-i]) sage: f._im_gens_(R, [t + t^2], base_map=cc) - -t^-2 + (i + 2)*t^-1 + (-i - 2) + 4*t + (-2*i - 6)*t^2 + (2*i + 4)*t^3 + (2*i - 7)*t^4 + O(t^5) - + -t^-2 + (i + 2)*t^-1 + (-i - 2) + 4*t + (-2*i - 6)*t^2 + + (2*i + 4)*t^3 + (2*i - 7)*t^4 + O(t^5) """ if base_map is None: return codomain(self(im_gens[0])) From 60f0664c21b596ef0bd539cdfe61f3552ac75373 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 18 Sep 2022 14:21:26 +0200 Subject: [PATCH 119/350] fix more _an_element and some_element with incorrect coefficients --- src/sage/rings/lazy_series_ring.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 6cd4706a61e..1635aada162 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1129,12 +1129,12 @@ def _an_element_(self): sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: L.an_element() - z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5) + z^-2 + z^3 + z^4 + z^5 + O(z^6) """ - R = self.base_ring() - coeff_stream = Stream_exact([R.an_element(), 3, 0, 2*R.an_element(), 1], - self._sparse, order=-2, constant=R.one()) - return self.element_class(self, coeff_stream) + return self(self._laurent_poly_ring.an_element(), + valuation=-2, + degree=3, + constant=self.base_ring().an_element()) def some_elements(self): """ @@ -1146,7 +1146,7 @@ def some_elements(self): sage: L.some_elements()[:7] [0, 1, z, -3*z^-4 + z^-3 - 12*z^-2 - 2*z^-1 - 10 - 8*z + z^2 + z^3, - z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5), + z^-2 + z^3 + z^4 + z^5 + O(z^6), -2*z^-3 - 2*z^-2 + 4*z^-1 + 11 - z - 34*z^2 - 31*z^3 + O(z^4), 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)] @@ -1154,7 +1154,7 @@ def some_elements(self): sage: L.some_elements()[:7] [0, 1, z, z^-4 + z^-3 + z^2 + z^3, - z^-1 + z^2 + z^3 + z^4 + O(z^5), + z^-2, 1 + z + z^3 + z^4 + z^6 + O(z^7), z^-1 + z + z^3 + O(z^5)] @@ -1162,7 +1162,7 @@ def some_elements(self): sage: L.some_elements()[:7] [0, 1, z, z^-3 + z^-1 + 2 + z + z^2 + z^3, - z^2 + z^3 + z^4 + O(z^5), + z^-2, z^-3 + z^-2 + z^-1 + 2 + 2*z + 2*z^2 + O(z^3), z^-2 + z^-1 + z + z^2 + z^4 + O(z^5)] """ @@ -1724,12 +1724,15 @@ def _an_element_(self): sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.an_element() - z + z + z^2 + z^3 + O(z^4) sage: L = LazyPowerSeriesRing(ZZ, 'x, y') sage: L.an_element() x """ + if self._arity == 1: + return self(self._laurent_poly_ring.an_element(), + constant=self.base_ring().an_element()) return self(self._laurent_poly_ring.an_element()) def uniformizer(self): @@ -1774,14 +1777,14 @@ def some_elements(self): sage: L = LazyPowerSeriesRing(ZZ, 'z') sage: L.some_elements()[:6] - [0, 1, z, + [0, 1, z + z^2 + z^3 + O(z^4), -12 - 8*z + z^2 + z^3, 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') sage: L.some_elements()[:6] - [0, 1, z, + [0, 1, z + q*z^2 + q*z^3 + q*z^4 + O(z^5), z + z^2 + z^3, 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6), z + z^2 + z^4 + z^5 + O(z^7)] From fbccb39ebef9bf107463c9955c8f254aa1dfe685 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 18 Sep 2022 16:06:44 +0200 Subject: [PATCH 120/350] normalize degree in Stream_exact for correct equality --- src/sage/data_structures/stream.py | 39 +++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 224559f8785..2d6bf53b52a 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -521,6 +521,13 @@ class Stream_exact(Stream): of the first element which is known to be equal to ``constant`` - ``constant`` -- integer (default: 0); the coefficient of every index larger than or equal to ``degree`` + + .. WARNING:: + + The convention for ``order`` is different to the one in + :class:`sage.rings.lazy_series_ring.LazySeriesRing`, where + the input is shifted to have the prescribed order. + """ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, order=None): """ @@ -533,18 +540,44 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, Traceback (most recent call last): ... AssertionError: Stream_exact should only be used for non-zero streams + + sage: s = Stream_exact([0, 0, 1, 0, 0], False) + sage: s._initial_coefficients, s._true_order, s._degree + ((1,), 2, 3) + + sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=0) + sage: s._initial_coefficients, s._true_order, s._degree + ((1,), 2, 3) + + sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=0, degree=10) + sage: s._initial_coefficients, s._true_order, s._degree + ((1,), 2, 3) + + sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=1) + sage: s._initial_coefficients, s._true_order, s._degree + ((1,), 2, 5) + + sage: s = Stream_exact([0, 0, 1, 2, 1, 1], False, constant=1) + sage: s._initial_coefficients, s._true_order, s._degree + ((1, 2), 2, 4) + + sage: s = Stream_exact([0, 0, 1, 2, 1, 1], False, constant=1, order=-2) + sage: s._initial_coefficients, s._true_order, s._degree + ((1, 2), 0, 2) """ if constant is None: self._constant = ZZ.zero() else: self._constant = constant + if order is None: order = 0 - if degree is None: + if (degree is None + or (not self._constant + and degree > order + len(initial_coefficients))): self._degree = order + len(initial_coefficients) else: self._degree = degree - assert order + len(initial_coefficients) <= self._degree # we remove leading and trailing zeros from @@ -562,7 +595,7 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, initial_coefficients = initial_coefficients[i:] if order + len(initial_coefficients) == self._degree: for j, w in enumerate(reversed(initial_coefficients)): - if w != constant: + if w != self._constant: break initial_coefficients.pop() self._degree -= 1 From 840539d33b8cefc94844f4790765564da8604cc6 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 19 Sep 2022 01:11:02 +0900 Subject: [PATCH 121/350] More tests, more bugs fixed. --- src/sage/data_structures/stream.py | 20 ++- src/sage/rings/lazy_series.py | 150 ++++++++++++++++-- src/sage/rings/lazy_series_ring.py | 110 ++++++++----- .../rings/polynomial/laurent_polynomial.pyx | 17 +- 4 files changed, 237 insertions(+), 60 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 224559f8785..89ca3031ab9 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1620,7 +1620,10 @@ def get_coefficient(self, n): [0, 1/3, -2/9, -2/9, -2/27, -2/9, 2/27, -2/9] """ if self._ainv is None: - self._ainv = ~self._series[1] + try: + self._ainv = ~self._series[1] + except TypeError: + self._ainv = self._series[1].inverse_of_unit() if n == 1: return self._ainv c = self._zero @@ -2257,7 +2260,10 @@ def __init__(self, series, approximate_order=None): """ if approximate_order is None: v = series.order() - self._ainv = ~series[v] + try: + self._ainv = ~series[v] + except TypeError: + self._ainv = series[v].inverse_of_unit() else: v = approximate_order self._ainv = None @@ -2285,7 +2291,10 @@ def get_coefficient(self, n): """ if self._ainv is None: self._approximate_order = -self._series.order() - self._ainv = ~self._series[self._approximate_order] + try: + self._ainv = ~self._series[self._approximate_order] + except TypeError: + self._ainv = self._series[self._approximate_order].inverse_of_unit() # if self._ainv is not None, self._approximate_order is the # true order @@ -2315,7 +2324,10 @@ def iterate_coefficients(self): """ if self._ainv is None: self._approximate_order = -self._series.order() - self._ainv = ~self._series[self._approximate_order] + try: + self._ainv = ~self._series[self._approximate_order] + except TypeError: + self._ainv = self._series[self._approximate_order].inverse_of_unit() # if self._ainv is not None, self._approximate_order is the # true order diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index a5d780fffae..abb08d7b47d 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3054,11 +3054,14 @@ def is_unit(self): sage: (2*z).is_unit() False - sage: (1+2*z).is_unit() + sage: (1 + 2*z).is_unit() True - sage: (1+2*z^-1).is_unit() + sage: (1 + 2*z^-1).is_unit() False + + sage: (z^3 + 4 - z^-2).is_unit() + True """ if self.is_zero(): # now 0 != 1 return False @@ -3943,7 +3946,6 @@ def _format_series(self, formatter, format_strings=False): return strformat("O({})".format(formatter(z**m))) return formatter(poly) + strformat(" + O({})".format(formatter(z**m))) - class LazyPowerSeries(LazyCauchyProductSeries): r""" A Taylor series where the coefficients are computed lazily. @@ -3975,14 +3977,14 @@ def is_unit(self): sage: (2*z).is_unit() False - sage: (1+2*z).is_unit() + sage: (1 + 2*z).is_unit() True - sage: (3+2*z).is_unit() + sage: (3 + 2*z).is_unit() False sage: L. = LazyPowerSeriesRing(ZZ) - sage: (1+2*x+3*x*y).is_unit() + sage: (-1 + 2*x + 3*x*y).is_unit() True """ if self.is_zero(): # now 0 != 1 @@ -4710,6 +4712,123 @@ def polynomial(self, degree=None, names=None): return R(self[0:m]) return R.sum(self[0:m]) +class LazyPowerSeries_gcd(LazyPowerSeries): + """ + A lazy power series that also implements the GCD algorithm. + """ + def gcd(self, other): + r""" + Return the greatest common divisor of ``self`` and ``other``. + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: a = 16*x^5 / (1 - 5*x) + sage: b = (22*x^2 + x^8) / (1 - 4*x^2) + sage: a.gcd(b) + x^2 + """ + P = self.parent() + if P._arity != 1: + raise NotImplementedError("only implemented for arity one") + if not self or not other: + return P.zero() + sv = self.valuation() + ov = other.valuation() + val = min(sv, ov) + assert val is not infinity + # This assumes the base ring is a field + return P.gen(0) ** val + + def xgcd(self, f): + r""" + Return the extended gcd of ``self`` and ``f``. + + OUTPUT: + + A triple ``(g, s, t)`` such that ``g`` is the gcd of ``self`` + and ``f``, and ``s`` and ``t`` are cofactors satisfying the + Bezout identity + + .. MATH:: + + g = s \cdot \mathrm{self} + t \cdot f. + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: a = 16*x^5 / (1 - 2*x) + sage: b = (22*x^3 + x^8) / (1 - 3*x^2) + sage: g, s, t = a.xgcd(b) + sage: g + x^3 + sage: s + 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) + sage: t + 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) + + sage: LazyPowerSeriesRing.options.halting_precision(20) # verify up to degree 20 + + sage: g == s * a + t * b + True + + sage: a = 16*x^5 / (1 - 2*x) + sage: b = (-16*x^5 + x^8) / (1 - 3*x^2) + sage: g, s, t = a.xgcd(b) + sage: g + x^5 + sage: s + 1/16 - 1/16*x - 3/16*x^2 + 1/8*x^3 - 17/256*x^4 + 9/128*x^5 + 1/128*x^6 + O(x^7) + sage: t + 1/16*x - 1/16*x^2 - 3/16*x^3 + 1/8*x^4 - 17/256*x^5 + 9/128*x^6 + 1/128*x^7 + O(x^8) + sage: g == s * a + t * b + True + + sage: L. = LazyPowerSeriesRing(GF(2)) + sage: a = L(lambda n: n % 2, valuation=3); a + x^3 + x^5 + x^7 + x^9 + O(x^10) + sage: b = L(lambda n: binomial(n,2) % 2, valuation=3); b + x^3 + x^6 + x^7 + O(x^10) + sage: g, s, t = a.xgcd(b) + sage: g + x^3 + sage: s + 1 + x + x^3 + x^4 + x^5 + O(x^7) + sage: t + x + x^2 + x^4 + x^5 + x^6 + O(x^8) + sage: g == s * a + t * b + True + + sage: LazyPowerSeriesRing.options._reset() # reset the options + """ + P = self.parent() + if P._arity != 1: + raise NotImplementedError("only implemented for arity one") + # one of the elements is zero + if not self: + return (P.zero(), P.zero(), P.one()) + if not f: + return (P.zero(), P.one(), P.zero()) + # get the valuations + sv = self.valuation() + sc = self[sv] + fv = f.valuation() + fc = f[fv] + val = min(sv, fv) + assert val is not infinity + # This assumes the base ring is a field + x = P.gen(0) + unit = (self + f).shift(-val) + if not unit[0]: + # this only happens if they have the same valuation + # we multiply f by the generator to avoid any cancellations + unit = (self + f.shift(1)).shift(-val) + unit = ~unit + return (x**val, + unit, + unit * x) + unit = ~unit + return (x**val, unit, unit) class LazyCompletionGradedAlgebraElement(LazyCauchyProductSeries): """ @@ -4811,16 +4930,16 @@ def is_unit(self): sage: L(2*m[1]).is_unit() False - sage: L(1+2*m[1]).is_unit() + sage: L(-1 + 2*m[1]).is_unit() True - sage: L(2+3*m[1]).is_unit() + sage: L(2 + m[1]).is_unit() False sage: m = SymmetricFunctions(QQ).m() sage: L = LazySymmetricFunctions(m) - sage: L(2+3*m[1]).is_unit() + sage: L(2 + 3*m[1]).is_unit() True """ if self.is_zero(): # now 0 != 1 @@ -5698,17 +5817,17 @@ def is_unit(self): EXAMPLES:: sage: D = LazyDirichletSeriesRing(ZZ, "s") - sage: D([0,2]).is_unit() + sage: D([0, 2]).is_unit() False - sage: D([1,2]).is_unit() + sage: D([-1, 2]).is_unit() True - sage: D([3,2]).is_unit() + sage: D([3, 2]).is_unit() False sage: D = LazyDirichletSeriesRing(QQ, "s") - sage: D([3,2]).is_unit() + sage: D([3, 2]).is_unit() True """ if self.is_zero(): # now 0 != 1 @@ -5835,7 +5954,7 @@ def __invert__(self): O(1/(8^z)) Trying to invert a non-invertible 'exact' series raises a - ``ZeroDivisionError``: + ``ZeroDivisionError``:: sage: _ = ~L([0,1], constant=1) Traceback (most recent call last): @@ -5843,14 +5962,13 @@ def __invert__(self): ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero If the series is not 'exact', we cannot do this without - actually computing a term. + actually computing a term:: sage: f = ~L(lambda n: n-1) sage: f[1] Traceback (most recent call last): ... ZeroDivisionError: rational division by zero - """ P = self.parent() return P.element_class(P, Stream_dirichlet_invert(self._coeff_stream)) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ca2ccf29f2c..a23b4d89dac 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -45,7 +45,9 @@ from sage.categories.algebras import Algebras from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.rings import Rings +from sage.categories.unique_factorization_domains import UniqueFactorizationDomains from sage.categories.integral_domains import IntegralDomains +from sage.categories.euclidean_domains import EuclideanDomains from sage.categories.fields import Fields from sage.categories.complete_discrete_valuation import (CompleteDiscreteValuationFields, CompleteDiscreteValuationRings) @@ -58,6 +60,7 @@ from sage.rings.lazy_series import (LazyModuleElement, LazyLaurentSeries, LazyPowerSeries, + LazyPowerSeries_gcd, LazyCompletionGradedAlgebraElement, LazySymmetricFunction, LazyDirichletSeries) @@ -393,6 +396,7 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No if coefficients is None: # Try to build stuff using the internal polynomial ring constructor R = self._internal_poly_ring + try: x = R(x) except (TypeError, ValueError): @@ -773,15 +777,15 @@ def _test_invert(self, **options): elements = tester.some_elements() for x in elements: - # because of lazyness, we cannot try to invert x, because - # this will always succeed, except if the series is - # 'exact' - if x.is_unit(): - y = ~x - e = y * x - tester.assertFalse(x.is_zero()) - tester.assertTrue(e.is_one()) - tester.assertEqual(y.valuation(), -x.valuation()) + # because of laziness, we cannot try to invert x, because + # this will always succeed, except if the series is 'exact' + if not x.is_unit(): + continue + y = ~x + e = y * x + tester.assertFalse(x.is_zero()) + tester.assertTrue(e.is_one()) + tester.assertEqual(y.valuation(), -x.valuation()) class LazyLaurentSeriesRing(LazySeriesRing): r""" @@ -961,12 +965,17 @@ def __init__(self, base_ring, names, sparse=True, category=None): (euclidean domains and infinite enumerated sets and metric spaces) and infinite sets) + sage: L = LazyLaurentSeriesRing(Zmod(6), 't') + sage: TestSuite(L).run() + sage: L.category() + Category of infinite commutative algebras over + (finite commutative rings and subquotients of monoids + and quotients of semigroups and finite enumerated sets) + sage: E. = ExteriorAlgebra(QQ) sage: L = LazyLaurentSeriesRing(E, 't') # not tested - Options are remembered across doctests:: - - sage: LazyLaurentSeriesRing.options.halting_precision(None) + sage: LazyLaurentSeriesRing.options._reset() # reset the options """ self._sparse = sparse if len(names) != 1: @@ -980,11 +989,10 @@ def __init__(self, base_ring, names, sparse=True, category=None): category = Algebras(base_ring.category()) if base_ring in Fields(): category &= CompleteDiscreteValuationFields() - else: - if "Commutative" in base_ring.category().axioms(): - category = category.Commutative() - if base_ring in IntegralDomains(): - category &= IntegralDomains() + elif base_ring in IntegralDomains(): + category &= IntegralDomains() + elif "Commutative" in base_ring.category().axioms(): + category = category.Commutative() if base_ring.is_zero(): category = category.Finite() @@ -1077,9 +1085,15 @@ def _an_element_(self): sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: L.an_element() z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + O(z^5) + + sage: L = LazyLaurentSeriesRing(GF(3), 'z') + sage: GF(3).an_element() + 0 + sage: L.an_element() + z^2 + z^3 + z^4 + O(z^5) """ R = self.base_ring() - coeff_stream = Stream_exact([R.an_element(), 3, 0, 2*R.an_element(), 1], + coeff_stream = Stream_exact([R.an_element(), R(3), R.zero(), 2*R.an_element(), R.one()], self._sparse, order=-2, constant=R.one()) return self.element_class(self, coeff_stream) @@ -1278,23 +1292,34 @@ def __init__(self, base_ring, names, sparse=True, category=None): TESTS:: - sage: LazyLaurentSeriesRing.options.halting_precision(15) + sage: LazyPowerSeriesRing.options.halting_precision(15) sage: L = LazyPowerSeriesRing(ZZ, 't') sage: TestSuite(L).run() - sage: L = LazyPowerSeriesRing(ZZ, 's, t') sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(QQ, 't') sage: TestSuite(L).run() - sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: TestSuite(L).run() - Options are remembered across doctests:: + sage: L = LazyPowerSeriesRing(Zmod(6), 't') + sage: TestSuite(L).run() + sage: L = LazyPowerSeriesRing(Zmod(6), 's, t') + sage: TestSuite(L).run() + + sage: L = LazyPowerSeriesRing(QQ['q'], 't') + sage: TestSuite(L).run() + sage: L = LazyPowerSeriesRing(QQ['q'], 's, t') + sage: TestSuite(L).run() # long time + + sage: L = LazyPowerSeriesRing(ZZ['q'], 't') + sage: TestSuite(L).run() + sage: L = LazyPowerSeriesRing(ZZ['q'], 's, t') + sage: TestSuite(L).run() # long time - sage: LazyLaurentSeriesRing.options.halting_precision(None) + sage: LazyPowerSeriesRing.options._reset() # reset the options Check that :trac:`34470` is fixed:: @@ -1315,7 +1340,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: L in PrincipalIdealDomains False - """ from sage.structure.category_object import normalize_names names = normalize_names(-1, names) @@ -1328,10 +1352,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): else: self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE") category = Algebras(base_ring.category()) - if self._arity == 1 and base_ring in Fields(): - category &= CompleteDiscreteValuationRings() - self.uniformizer = lambda: self.gen() - elif base_ring in IntegralDomains(): + if self._arity == 1: + if base_ring in Fields(): + category &= CompleteDiscreteValuationRings() + self.Element = LazyPowerSeries_gcd + elif base_ring in Fields(): + category &= UniqueFactorizationDomains() + self.Element = LazyPowerSeries_gcd + if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): category = category.Commutative() @@ -1739,7 +1767,9 @@ def some_elements(self): if self._arity == 1: elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: n**2)]) else: - elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: sum(self.gens())**n)]) + PR = self._laurent_poly_ring + sum_gens = PR.sum(PR.gens()) + elts.extend([(z-3)*(2+z)**2, (1 - 2*z**3)/(1 - z + 3*z**2), self(lambda n: sum_gens**n)]) return elts ###################################################################### @@ -1805,9 +1835,7 @@ def __init__(self, basis, sparse=True, category=None): sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() - Options are remembered across doctests:: - - sage: LazySymmetricFunctions.options.halting_precision(None) + sage: LazySymmetricFunctions.options._reset() # reset the options Check that :trac:`34470` is fixed. The ideal generated by `p[1]` and `p[2]` is not principal:: @@ -2105,6 +2133,7 @@ def some_elements(self): sage: L = LazySymmetricFunctions(m) sage: L.some_elements() [0, m[], 2*m[] + 2*m[1] + 3*m[2], + m[1] + (m[1,1]+m[2]), 3*m[] + 2*m[1] + (m[1,1]+m[2]) + (2*m[1,1,1]+m[3]) + (2*m[1,1,1,1]+4*m[2,1,1]+2*m[2,2]) @@ -2116,11 +2145,14 @@ def some_elements(self): sage: S = NCSF.Complete() sage: L = S.formal_series_ring() sage: L.some_elements() - [0, S[], 2*S[] + 2*S[1] + (3*S[1,1])] - + [0, S[], 2*S[] + 2*S[1] + (3*S[1,1]), S[1] + (S[1,1]+S[2])] """ elt = self.an_element() elts = [self.zero(), self.one(), elt] + it = iter(self._laurent_poly_ring.basis()) + temp = self.sum(b for _ in range(4) if (b := next(it)).degree()) + if temp: + elts.append(temp) try: if elt.is_unit(): elts.append(~elt) @@ -2188,9 +2220,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyDirichletSeriesRing(QQ, 't') sage: TestSuite(L).run() - Options are remembered across doctests:: - - sage: LazyDirichletSeriesRing.options.halting_precision(None) + sage: LazyDirichletSeriesRing.options._reset() # reset the options The ideal generated by `2^-s` and `3^-s` is not principal:: @@ -2204,8 +2234,8 @@ def __init__(self, base_ring, names, sparse=True, category=None): According to the answers in https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd, - the ring of formal Dirichlet series is actually a - UniqueFactorizationDomain. + in particular, see :arxiv:`math/0105219`, the ring of formal + Dirichlet series is actually in :class:`UniqueFactorizationDomains`. """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") @@ -2217,6 +2247,8 @@ def __init__(self, base_ring, names, sparse=True, category=None): self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=True) category = Algebras(base_ring.category()) + #if base_ring in Fields(): + # category &= UniqueFactorizationDomains() if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index c82cf65eb0f..c72b68ead03 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1118,12 +1118,27 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): x^3 + 3*x^4 + 3*x^5 + 10*x^6 + 18*x^7 + 9*x^8 + 27*x^9 + 27*x^10 + 27*x^12 sage: g^4 x^-40 - 4*x^-29 + 6*x^-18 - 4*x^-7 + x^4 + + sage: R. = LaurentPolynomialRing(Zmod(6)) + sage: x^-2 + x^-2 + sage: (5*x^2)^-4 + x^-8 + sage: (5*x^-4)^-3 + 5*x^12 """ cdef LaurentPolynomial_univariate self = _self cdef long right = r if right != r: raise ValueError("exponent must be an integer") - return self._parent.element_class(self._parent, self.__u**right, self.__n*right) + try: + return self._parent.element_class(self._parent, self.__u**right, self.__n*right) + except TypeError as err: + # we need to handle the special case of negative powers and a unit + if not self.__u.is_constant() or not self.__u.leading_coefficient().is_unit(): + raise + c = self._parent._R(self.__u.leading_coefficient() ** right) + return self._parent.element_class(self._parent, c, self.__n*right) cpdef _floordiv_(self, rhs): """ From 7cbde499aaf0914108b9880549bd817f5f30c3ea Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 18 Sep 2022 18:31:30 +0200 Subject: [PATCH 122/350] fix reversion of symmetric functions, improve some_elements and tests --- src/sage/rings/lazy_series.py | 9 ++++++- src/sage/rings/lazy_series_ring.py | 41 +++++++++++++++++++----------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index b88a9738c98..8ac0d7edd63 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3651,6 +3651,8 @@ def revert(self): if coeff_stream.order() != 1: raise ValueError("compositional inverse does not exist") + # TODO: coefficients should not be checked here, it prevents + # us from using self.define in some cases! if any(coeff_stream[i] for i in range(coeff_stream._approximate_order, -1)): raise ValueError("compositional inverse does not exist") @@ -4463,6 +4465,8 @@ def revert(self): if coeff_stream.order() != 1: raise ValueError("compositional inverse does not exist") + # TODO: coefficients should not be checked here, it prevents + # us from using self.define in some cases! if not coeff_stream[1]: raise ValueError("compositional inverse does not exist") @@ -5126,6 +5130,8 @@ def revert(self): order=0) return P.element_class(P, coeff_stream) + # TODO: coefficients should not be checked here, it prevents + # us from using self.define in some cases! if not coeff_stream[1]: raise ValueError("compositional inverse does not exist") @@ -5134,8 +5140,9 @@ def revert(self): X = R(Partition([1])) b = coeff_stream[1][Partition([1])] + b_inv = R.base_ring()(~b) g = P.undefined(valuation=1) - g.define(~b * X - (self - b * X)(g)) + g.define(b_inv * (X - (self - b * X)(g))) return g plethystic_inverse = revert diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 1635aada162..a43eb9e3c30 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -816,8 +816,11 @@ def _test_revert(self, **options): try: y = x.revert() vy = y.valuation() - except ValueError: - tester.assertFalse(vx == 1) + m = y[vy] + except (ValueError, TypeError): + tester.assertFalse(vx == 1 and x[vx].is_unit(), + ("the series %s should be reversible " + "- its valuation is one and its leading coefficient is a unit") % x) else: count += 1 e1 = y(x) @@ -1855,32 +1858,33 @@ class LazyCompletionGradedAlgebra(LazySeriesRing): Element = LazyCompletionGradedAlgebraElement def __init__(self, basis, sparse=True, category=None): - """ - Initialize ``self``. + """Initialize ``self``. TESTS:: - sage: LazySymmetricFunctions.options.halting_precision(7) + sage: LazySymmetricFunctions.options.halting_precision(6) - sage: s = SymmetricFunctions(ZZ).s() + sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() - sage: s = SymmetricFunctions(QQ).s() - sage: L = LazySymmetricFunctions(s) + sage: p = SymmetricFunctions(GF(5)).p() + sage: L = LazySymmetricFunctions(p) sage: TestSuite(L).run() - sage: s = SymmetricFunctions(QQ["q"]).s() + Reversion will only work when the base ring is a field:: + + sage: TestSuite(L).run(skip=['_test_revert']) + sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) - sage: TestSuite(L).run() - sage: s = SymmetricFunctions(GF(5)).s() + sage: s = SymmetricFunctions(QQ["q"]).s() sage: L = LazySymmetricFunctions(s) - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip=['_test_revert']) Options are remembered across doctests:: - sage: LazySymmetricFunctions.options.halting_precision(None) + sage: LazySymmetricFunctions.options._reset() Check that :trac:`34470` is fixed. The ideal generated by `p[1]` and `p[2]` is not principal:: @@ -2176,7 +2180,7 @@ def some_elements(self): sage: m = SymmetricFunctions(GF(5)).m() sage: L = LazySymmetricFunctions(m) - sage: L.some_elements() + sage: L.some_elements()[:5] [0, m[], 2*m[] + 2*m[1] + 3*m[2], 2*m[1] + 3*m[2], 3*m[] + 2*m[1] + (m[1,1]+m[2]) + (2*m[1,1,1]+m[3]) @@ -2188,13 +2192,15 @@ def some_elements(self): sage: NCSF = NonCommutativeSymmetricFunctions(QQ) sage: S = NCSF.Complete() sage: L = S.formal_series_ring() - sage: L.some_elements() + sage: L.some_elements()[:4] [0, S[], 2*S[] + 2*S[1] + (3*S[1,1]), 2*S[1] + (3*S[1,1])] """ elt = self.an_element() elts = [self.zero(), self.one(), elt] + # an element with no constant term elts.append(elt - elt[0]) + # the inverse of an element try: if elt.is_unit(): elts.append(~elt) @@ -2202,6 +2208,11 @@ def some_elements(self): elts.append(~(1 - elt[0] + elt)) except NotImplementedError: pass + # an element with no constant term and an invertible + # coefficient of the linear term + if self._arity == 1: + x = list(self._laurent_poly_ring.basis(1))[0] + elts.append((1 - elt[0] + elt) * x) return elts ###################################################################### From b15e36dff297148e3c68836f83a8ca6aaafd6c46 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 19 Sep 2022 01:38:31 +0200 Subject: [PATCH 123/350] skip test_revert when base ring is not a field --- src/sage/rings/lazy_series_ring.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index c6b44ce2b37..15e257ac7c3 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -1022,7 +1022,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() sage: L = LazyLaurentSeriesRing(Zmod(6), 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip=['_test_revert']) sage: L.category() Category of infinite commutative algebras over (finite commutative rings and subquotients of monoids @@ -1364,9 +1364,9 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(Zmod(6), 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip=['_test_revert']) sage: L = LazyPowerSeriesRing(Zmod(6), 's, t') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip=['_test_revert']) sage: L = LazyPowerSeriesRing(QQ['q'], 't') sage: TestSuite(L).run() From 8e7b76de63876e8ab5fcbcdfb7b049de2e087e0d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 19 Sep 2022 01:46:19 +0200 Subject: [PATCH 124/350] fix and simplify wrong doctest --- src/sage/rings/lazy_series.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index ff82f2d78f5..d848b872da1 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -5196,14 +5196,14 @@ def revert(self): sage: f.revert() 1/2*p[1] - sage: f = L(2*p[1] + p[2] + p[1,1]) + sage: f = L(2*p[1] + p[1,1]) sage: f.revert() - 1/2*p[1] + (-1/4*p[1,1]-1/2*p[2]) + (1/4*p[1,1,1]+1/2*p[2,1]) - + (-5/16*p[1,1,1,1]-3/4*p[2,1,1]+1/2*p[4]) - + (7/16*p[1,1,1,1,1]+5/4*p[2,1,1,1]+1/2*p[2,2,1]-1/2*p[4,1]) - + (-21/32*p[1,1,1,1,1,1]-35/16*p[2,1,1,1,1]-3/2*p[2,2,1,1]-1/4*p[2,2,2]+3/4*p[4,1,1]) - + (33/32*p[1,1,1,1,1,1,1]+63/16*p[2,1,1,1,1,1]+15/4*p[2,2,1,1,1]+3/4*p[2,2,2,1]-5/4*p[4,1,1,1]-p[4,2,1]) - + O^8 + 1/2*p[1] + (-1/8*p[1,1]) + (1/16*p[1,1,1]) + (-5/128*p[1,1,1,1]) + + (7/256*p[1,1,1,1,1]) + (-21/1024*p[1,1,1,1,1,1]) + + (33/2048*p[1,1,1,1,1,1,1]) + O^8 + + sage: f.revert()(f) + p[1] + O^8 ALGORITHM: From b47407b38c76f7cc6f58777bf8d6cf5feb19d4f5 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 19 Sep 2022 16:22:32 +0900 Subject: [PATCH 125/350] Implementing _floordiv_, Stream._true_order to boolean, first fraction field, more tests, marking long tests. --- src/sage/data_structures/stream.py | 81 +++++---- src/sage/rings/lazy_series.py | 102 +++++++++-- src/sage/rings/lazy_series_ring.py | 271 +++++++++++++++++++++++++---- 3 files changed, 376 insertions(+), 78 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index c2a9b90296d..cbef85d64dd 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -112,8 +112,9 @@ class Stream(): - ``sparse`` -- boolean; whether the implementation of the stream is sparse - ``approximate_order`` -- integer; a lower bound for the order of the stream + - ``true_order`` -- boolean; if the approximate order is the actual order """ - def __init__(self, sparse, approximate_order, true_order=None): + def __init__(self, sparse, approximate_order, true_order=False): """ Initialize ``self``. @@ -376,20 +377,22 @@ def order(self): sage: f.order() 1 """ - if self._true_order is not None: - return self._true_order + if self._true_order: + return self._approximate_order if self._is_sparse: n = self._approximate_order cache = self._cache while True: if n in cache: if cache[n]: - self._approximate_order = self._true_order = n + self._approximate_order = n + self._true_order = True return n n += 1 else: if self[n]: - self._approximate_order = self._true_order = n + self._approximate_order = n + self._true_order = True return n n += 1 else: @@ -398,12 +401,14 @@ def order(self): while True: if n - self._offset < len(cache): if cache[n - self._offset]: - self._approximate_order = self._true_order = n + self._approximate_order = n + self._true_order = True return n n += 1 else: if self[n]: - self._approximate_order = self._true_order = n + self._approximate_order = n + self._true_order = True return n n += 1 @@ -542,28 +547,40 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, AssertionError: Stream_exact should only be used for non-zero streams sage: s = Stream_exact([0, 0, 1, 0, 0], False) - sage: s._initial_coefficients, s._true_order, s._degree - ((1,), 2, 3) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1,), 2, 3, True) sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=0) - sage: s._initial_coefficients, s._true_order, s._degree - ((1,), 2, 3) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1,), 2, 3, True) sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=0, degree=10) - sage: s._initial_coefficients, s._true_order, s._degree - ((1,), 2, 3) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1,), 2, 3, True) sage: s = Stream_exact([0, 0, 1, 0, 0], False, constant=1) - sage: s._initial_coefficients, s._true_order, s._degree - ((1,), 2, 5) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1,), 2, 5, True) + + sage: s = Stream_exact([0, 0, 1, 0, 1], False, constant=1, degree=10) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1, 0, 1), 2, 10, True) + + sage: s = Stream_exact([0, 0, 1, 0, 1], False, constant=1, degree=5) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1,), 2, 4, True) + + sage: s = Stream_exact([0, 0, 1, 2, 0, 1], False, constant=1) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1, 2), 2, 5, True) sage: s = Stream_exact([0, 0, 1, 2, 1, 1], False, constant=1) - sage: s._initial_coefficients, s._true_order, s._degree - ((1, 2), 2, 4) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1, 2), 2, 4, True) sage: s = Stream_exact([0, 0, 1, 2, 1, 1], False, constant=1, order=-2) - sage: s._initial_coefficients, s._true_order, s._degree - ((1, 2), 0, 2) + sage: s._initial_coefficients, s._approximate_order, s._degree, s._true_order + ((1, 2), 0, 2, True) """ if constant is None: self._constant = ZZ.zero() @@ -588,18 +605,20 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, # different from constant, because __eq__ below would become # complicated otherwise - # TODO: simplify for i, v in enumerate(initial_coefficients): if v: + # We have found the first nonzero coefficient order += i initial_coefficients = initial_coefficients[i:] if order + len(initial_coefficients) == self._degree: - for j, w in enumerate(reversed(initial_coefficients)): + # Strip off the constant values at the end + for w in reversed(initial_coefficients): if w != self._constant: break initial_coefficients.pop() self._degree -= 1 - for j, w in enumerate(reversed(initial_coefficients)): + # Strip off all remaining zeros at the end + for w in reversed(initial_coefficients): if w: break initial_coefficients.pop() @@ -611,7 +630,7 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, assert self._initial_coefficients or self._constant, "Stream_exact should only be used for non-zero streams" - super().__init__(is_sparse, order, true_order=order) + super().__init__(is_sparse, order, true_order=True) def __getitem__(self, n): """ @@ -676,7 +695,7 @@ def order(self): 0 """ - return self._true_order + return self._approximate_order def __hash__(self): """ @@ -780,7 +799,7 @@ def __ne__(self, other): if self[i] != other._cache[i]: return True else: - if other._offset > self._true_order: + if other._offset > self._approximate_order: return False return any(self[i] != c for i, c in enumerate(other._cache, other._offset)) @@ -1267,7 +1286,7 @@ def order(self): sage: s.order() +Infinity """ - return self._true_order + return self._approximate_order # == infinity def __eq__(self, other): """ @@ -1702,7 +1721,7 @@ def __init__(self, f, g): sage: g = Stream_function(lambda n: n^2, True, 1) sage: h = Stream_cauchy_compose(f, g) """ - if g._true_order is not None and g._true_order <= 0: + if g._true_order and g._approximate_order <= 0: raise ValueError("can only compose with a series of positive valuation") if f._approximate_order < 0: ginv = Stream_cauchy_invert(g) @@ -1853,7 +1872,7 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): self._degree_f = f._degree else: self._degree_f = None - if g._true_order is not None and g._true_order == 0 and self._degree_f is None: + if g._true_order and g._approximate_order == 0 and self._degree_f is None: raise ValueError("can only compute plethysm with a series of valuation 0 for symmetric functions of finite support") val = f._approximate_order * g._approximate_order @@ -2000,9 +2019,9 @@ def stretched_power_restrict_degree(self, i, m, d): sage: g = Stream_function(lambda n: sum(tensor([p[k], p[n-k]]) for k in range(n+1)), True, 1) sage: h = Stream_plethysm(f, g, p2) sage: A = h.stretched_power_restrict_degree(2, 3, 6) - sage: B = p[2,2,2](sum(g[n] for n in range(7))) - sage: B = p2.element_class(p2, {m: c for m, c in B if sum(mu.size() for mu in m) == 12}) - sage: A == B + sage: B = p[2,2,2](sum(g[n] for n in range(7))) # long time + sage: B = p2.element_class(p2, {m: c for m, c in B if sum(mu.size() for mu in m) == 12}) # long time + sage: A == B # long time True """ while len(self._powers) < m: diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index abb08d7b47d..da3f266ee96 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -218,6 +218,7 @@ from sage.combinat.partition import Partition, Partitions from sage.misc.misc_c import prod from sage.misc.derivative import derivative_parse +from sage.categories.integral_domains import IntegralDomains from sage.rings.infinity import infinity from sage.rings.integer_ring import ZZ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing @@ -2882,17 +2883,14 @@ def _div_(self, other): sage: t / L(1) t - sage: t^3*(1+2*t+3*t^2+4*t^3)/(t-t^2) + sage: t^3 * (1+2*t+3*t^2+4*t^3) / (t-t^2) t^2 + 3*t^3 + 6*t^4 + 10*t^5 + 10*t^6 + 10*t^7 + O(t^8) - sage: t^3*((1+2*t+3*t^2+4*t^3)/(t-t^2)) - Traceback (most recent call last): - ... - ZeroDivisionError: cannot divide by a series of larger valuation + sage: t^3 * ((1+2*t+3*t^2+4*t^3) / (t-t^2)) + t^2 + 3*t^3 + 6*t^4 + 10*t^5 + 10*t^6 + 10*t^7 + O(t^8) sage: L(lambda n: n) / (t + t^2) 1 + t + 2*t^2 + 2*t^3 + 3*t^4 + 3*t^5 + O(t^6) - """ if isinstance(other._coeff_stream, Stream_zero): raise ZeroDivisionError("cannot divide by 0") @@ -2903,9 +2901,12 @@ def _div_(self, other): return P.zero() right = other._coeff_stream if (P._minimal_valuation is not None - and left._true_order is not None - and left._true_order < right._approximate_order): - raise ZeroDivisionError("cannot divide by a series of larger valuation") + and left._true_order + and left._approximate_order < right._approximate_order): + F = P.fraction_field() + num = F.element_class(F, left) + den = F.element_class(F, right) + return num / den R = P._internal_poly_ring if (isinstance(left, Stream_exact) @@ -2973,6 +2974,37 @@ def _div_(self, other): return P.element_class(P, Stream_cauchy_mul(left, right_inverse)) + def _floordiv_(self, other): + r""" + Return ``self`` floor divided by ``other``. + + INPUT: + + - ``other`` -- nonzero series + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(QQ) + sage: g = (x + 2*x^2) / (1 - x - x^2) + sage: x // g + 1 - 3*x + 5*x^2 - 10*x^3 + 20*x^4 - 40*x^5 + 80*x^6 + O(x^7) + sage: 1 // g + x^-1 - 3 + 5*x - 10*x^2 + 20*x^3 - 40*x^4 + 80*x^5 + O(x^6) + sage: x^-3 // g + x^-4 - 3*x^-3 + 5*x^-2 - 10*x^-1 + 20 - 40*x + 80*x^2 + O(x^3) + sage: f = (x + x^2) / (1 - x) + sage: f // g + 1 - x + x^2 - 4*x^3 + 6*x^4 - 14*x^5 + 26*x^6 + O(x^7) + sage: g // f + 1 + x + 3*x^3 + x^4 + 6*x^5 + 5*x^6 + O(x^7) + """ + if isinstance(other._coeff_stream, Stream_zero): + raise ZeroDivisionError("cannot divide by 0") + P = self.parent() + if P not in IntegralDomains(): + raise TypeError("must be an integral domain") + return P(self / other) + class LazyLaurentSeries(LazyCauchyProductSeries): r""" A Laurent series where the coefficients are computed lazily. @@ -4689,7 +4721,6 @@ def polynomial(self, degree=None, names=None): sage: f = z-z^2 sage: f.polynomial() -z^2 + z - """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing S = self.parent() @@ -4712,6 +4743,57 @@ def polynomial(self, degree=None, names=None): return R(self[0:m]) return R.sum(self[0:m]) + def _floordiv_(self, other): + r""" + Return ``self`` floor divided by ``other``. + + INPUT: + + - ``other`` -- nonzero series + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(ZZ) + sage: g = x^2 + y*x + sage: x // g + 0 + sage: g = (x^2 + y*x) / (1 - x + x*y) + sage: x // g + 0 + sage: f = (x + y) / (1 - x - y + x*y) + sage: f // g + 0 + + sage: L. = LazyPowerSeriesRing(QQ) + sage: g = (x + 2*x^2) / (1 - x - x^2) + sage: 3 // g + 0 + sage: x // g + 1 - 3*x + 5*x^2 - 10*x^3 + 20*x^4 - 40*x^5 + 80*x^6 + O(x^7) + sage: x^2 // g + x - 3*x^2 + 5*x^3 - 10*x^4 + 20*x^5 - 40*x^6 + 80*x^7 + O(x^8) + sage: f = (x + x^2) / (1 - x) + sage: f // g + 1 - x + x^2 - 4*x^3 + 6*x^4 - 14*x^5 + 26*x^6 + O(x^7) + """ + if isinstance(other._coeff_stream, Stream_zero): + raise ZeroDivisionError("cannot divide by 0") + P = self.parent() + if P not in IntegralDomains(): + raise TypeError("must be an integral domain") + left = self._coeff_stream + right_order = other._coeff_stream._approximate_order + if left._approximate_order < right_order: + if left._true_order: + return P.zero() + while left._approximate_order < right_order: + # TODO: Implement a bound on computing the order of a Stream + if left[left._approximate_order]: + left._true_order = True + return P.zero() + left._approximate_order += 1 + return super()._floordiv_(other) + class LazyPowerSeries_gcd(LazyPowerSeries): """ A lazy power series that also implements the GCD algorithm. diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index a23b4d89dac..51a021feead 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -81,6 +81,24 @@ class LazySeriesRing(UniqueRepresentation, Parent): """ Abstract base class for lazy series. """ + # This will never be called directly (as it is an ABC), but we copy it + # for use in other subclasses. + @staticmethod + def __classcall_private__(cls, base_ring, names, sparse=True, *args, **kwds): + """ + Normalize input to ensure a unique representation. + + EXAMPLES:: + + sage: L. = LazyLaurentSeriesRing(QQ) + sage: Lp = LazyLaurentSeriesRing(QQ, 'z') + sage: L is Lp + True + """ + from sage.structure.category_object import normalize_names + names = normalize_names(-1, names) + return super().__classcall__(cls, base_ring, names, sparse, *args, **kwds) + def _element_constructor_(self, x=None, valuation=None, degree=None, constant=None, coefficients=None): r""" Construct a lazy series from ``x``. @@ -269,6 +287,49 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No sage: s[1] 0 + Converting various series from a univariate power series:: + + sage: L = LazyLaurentSeriesRing(GF(2), 'z') + sage: R = LazyPowerSeriesRing(ZZ, 'z') + sage: L.has_coerce_map_from(R) + True + sage: L(R(lambda n: n)) + z + z^3 + z^5 + O(z^7) + sage: L(R([2,4,6])) == L.zero() + True + sage: L(R([2,4,6], valuation=2, constant=4)) == L.zero() + True + sage: L(R([2,4,6], valuation=2, constant=5)) + z^5 + z^6 + z^7 + O(z^8) + sage: L(R([2,3,4], valuation=2, constant=4)) + z^3 + sage: L(R([2,3,4], valuation=2, constant=5)) + z^3 + z^5 + z^6 + z^7 + O(z^8) + + Can only convert from known to be constant multivariate power series:: + + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: R. = LazyPowerSeriesRing(QQ) + sage: L(R(2)) + 2 + sage: L(R.zero()) + 0 + sage: L(x) + Traceback (most recent call last): + ... + ValueError: unable to convert ... + sage: L(1 / (1 - x - y)) + Traceback (most recent call last): + ... + ValueError: unable to convert ... + sage: P. = QQ[] + sage: f = R(lambda n: (x+y)^n if n == 0 else P.zero()); f + 1 + O(x,y)^7 + sage: L(f) + Traceback (most recent call last): + ... + ValueError: unable to convert ... + TESTS: Checking the valuation is consistent:: @@ -463,6 +524,36 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No return ret return ret.shift(valuation - x._coeff_stream.order()) + # Handle when it is a power series + if isinstance(x, LazyPowerSeries): + stream = x._coeff_stream + if isinstance(stream, Stream_zero): + return self.zero() + elif isinstance(stream, Stream_exact): + BR = self.base_ring() + if x.parent()._arity != 1: + # Special case for constant series + if stream._degree == 1: + return self(BR(stream[0])) + else: + coeffs = [BR(val) for val in stream._initial_coefficients] + valuation = stream._approximate_order + for i, c in enumerate(coeffs): + if c: + valuation += i + coeffs = coeffs[i:] + break + else: + valuation += len(coeffs) + coeffs = [] + return self(coeffs, + degree=stream._degree, + constant=BR(stream._constant), + valuation=valuation) + elif x.parent()._arity == 1: + return self.element_class(self, stream) + raise ValueError(f"unable to convert {x} into {self}") + else: x = coefficients @@ -677,6 +768,20 @@ def _coerce_map_from_(self, S): True sage: L.has_coerce_map_from(GF(2)) True + sage: R = LazyPowerSeriesRing(ZZ, 'z') + sage: L.has_coerce_map_from(R) + True + + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: R = LazyPowerSeriesRing(QQ, 'z') + sage: L.has_coerce_map_from(R) + True + sage: R = LazyPowerSeriesRing(ZZ, 'z') + sage: L.has_coerce_map_from(R) + True + sage: R = LazyPowerSeriesRing(ZZ['t'], 'z') + sage: L.has_coerce_map_from(R) + False sage: L = LazyPowerSeriesRing(GF(2), 'z') sage: L.has_coerce_map_from(ZZ) @@ -695,7 +800,14 @@ def _coerce_map_from_(self, S): return True R = self._laurent_poly_ring - return R.has_coerce_map_from(S) + if R.has_coerce_map_from(S): + return True + + if (isinstance(S, LazySeriesRing) + and self._laurent_poly_ring.has_coerce_map_from(S._laurent_poly_ring)): + return True + + return None def _coerce_map_from_base_ring(self): """ @@ -767,7 +879,8 @@ def _test_invert(self, **options): EXAMPLES:: - sage: Zp(3)._test_invert() + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L._test_invert() .. SEEALSO:: @@ -932,17 +1045,19 @@ class LazyLaurentSeriesRing(LazySeriesRing): sage: L. = LazyLaurentSeriesRing(ZZ, sparse=False) sage: L.is_sparse() False - """ Element = LazyLaurentSeries + # Follow the "generic" normalization + __classcall_private__ = LazySeriesRing.__classcall_private__ + def __init__(self, base_ring, names, sparse=True, category=None): """ Initialize ``self``. TESTS:: - sage: LazyLaurentSeriesRing.options.halting_precision(15) + sage: LazyLaurentSeriesRing.options.halting_precision(12) sage: L = LazyLaurentSeriesRing(ZZ, 't') sage: TestSuite(L).run() @@ -1286,23 +1401,26 @@ class LazyPowerSeriesRing(LazySeriesRing): """ Element = LazyPowerSeries + # Follow the "generic" normalization + __classcall_private__ = LazySeriesRing.__classcall_private__ + def __init__(self, base_ring, names, sparse=True, category=None): """ Initialize ``self``. TESTS:: - sage: LazyPowerSeriesRing.options.halting_precision(15) + sage: LazyPowerSeriesRing.options.halting_precision(12) sage: L = LazyPowerSeriesRing(ZZ, 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(ZZ, 's, t') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(QQ, 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(QQ, 's, t') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(Zmod(6), 't') sage: TestSuite(L).run() @@ -1310,14 +1428,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(QQ['q'], 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(QQ['q'], 's, t') - sage: TestSuite(L).run() # long time + sage: TestSuite(L).run(skip="_test_fraction_field") # long time sage: L = LazyPowerSeriesRing(ZZ['q'], 't') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip="_test_fraction_field") sage: L = LazyPowerSeriesRing(ZZ['q'], 's, t') - sage: TestSuite(L).run() # long time + sage: TestSuite(L).run(skip="_test_fraction_field") # long time sage: LazyPowerSeriesRing.options._reset() # reset the options @@ -1341,8 +1459,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L in PrincipalIdealDomains False """ - from sage.structure.category_object import normalize_names - names = normalize_names(-1, names) self._sparse = sparse self._minimal_valuation = 0 self._laurent_poly_ring = PolynomialRing(base_ring, names) @@ -1597,6 +1713,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No assert degree is None coeff_stream = Stream_uninitialized(self._sparse, valuation) return self.element_class(self, coeff_stream) + try: # Try to build stuff using the polynomial ring constructor x = R(x) @@ -1608,6 +1725,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No if self._arity > 1 and constant: raise ValueError("constant must be zero for multivariate Taylor series") constant = BR(constant) + if x in R: if not x and not constant: coeff_stream = Stream_zero(self._sparse) @@ -1639,9 +1757,30 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No if isinstance(x, LazyPowerSeries): if x._coeff_stream._is_sparse is self._sparse: - return self.element_class(self, x._coeff_stream) + stream = x._coeff_stream + if isinstance(stream, Stream_exact): + if self._arity == 1: + BR = self.base_ring() + else: + BR = self._laurent_poly_ring + coeffs = [BR(val) for val in stream._initial_coefficients] + valuation = stream._approximate_order + for i, c in enumerate(coeffs): + if c: + valuation += i + coeffs = coeffs[i:] + break + else: + valuation += len(coeffs) + coeffs = [] + return self(coeffs, + degree=stream._degree, + constant=self.base_ring()(stream._constant), + valuation=valuation) + return self.element_class(self, stream) # TODO: Implement a way to make a self._sparse copy raise NotImplementedError("cannot convert between sparse and dense") + if callable(x) or isinstance(x, (GeneratorType, map, filter)): if valuation is None: valuation = 0 @@ -1732,6 +1871,30 @@ def residue_field(self): raise TypeError("the arity must be one") return R + def fraction_field(self): + """ + Return the fraction field of ``self``. + + If this is with a single variable over a field, then the fraction + field is the field of (lazy) formal Laurent series. + + .. TODO:: + + Implement other fraction fields. + + EXAMPLES:: + + sage: L. = LazyPowerSeriesRing(QQ) + sage: L.fraction_field() + Lazy Laurent Series Ring in x over Rational Field + """ + if self not in IntegralDomains(): + raise TypeError("must be an integral domain") + R = self.base_ring() + if self._arity == 1 and R in Fields(): + return LazyLaurentSeriesRing(R, names=self.variable_names()) + raise NotImplementedError("the fraction field is not yet implemented") + def some_elements(self): """ Return a list of elements of ``self``. @@ -1825,7 +1988,7 @@ def __init__(self, basis, sparse=True, category=None): TESTS:: - sage: LazySymmetricFunctions.options.halting_precision(7) + sage: LazySymmetricFunctions.options.halting_precision(6) sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) @@ -1922,7 +2085,7 @@ def _monomial(self, c, n): L = self._laurent_poly_ring return L(c) - def _element_constructor_(self, x=None, valuation=None, degree=None, check=True): + def _element_constructor_(self, x=None, valuation=None, degree=None, constant=None, check=True): r""" Construct a lazy element in ``self`` from ``x``. @@ -2190,7 +2353,7 @@ class LazySymmetricFunctions(LazyCompletionGradedAlgebra): ###################################################################### class LazyDirichletSeriesRing(LazySeriesRing): - """ + r""" The ring of lazy Dirichlet series. INPUT: @@ -2199,20 +2362,70 @@ class LazyDirichletSeriesRing(LazySeriesRing): - ``names`` -- name of the generator of this Dirichlet series ring - ``sparse`` -- (default: ``True``) whether this series is sparse or not + Unlike formal univariate Laurent/power series (over a field), + the ring of formal Dirichlet series is not a + :wikipedia:`discrete_valuation_ring`. On the other hand, it + is a :wikipedia:`local_ring`. The unique maximal ideal + consists of all non-invertible series, i.e., series with + vanishing constant term. + + .. TODO:: + + According to the answers in + https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd, + (which, in particular, references :arxiv:`math/0105219`) + the ring of formal Dirichlet series is actually a + :wikipedia:`Unique_factorization_domain` over `\ZZ`. + + .. NOTE:: + + An interesting valuation is described in Emil Daniel + Schwab; Gheorghe Silberberg *A note on some discrete + valuation rings of arithmetical functions*, Archivum + Mathematicum, Vol. 36 (2000), No. 2, 103-109, + http://dml.cz/dmlcz/107723. Let `J_k` be the ideal of + Dirichlet series whose coefficient `f[n]` of `n^s` + vanishes if `n` has less than `k` prime factors, counting + multiplicities. For any Dirichlet series `f`, let `D(f)` + be the largest integer `k` such that `f` is in `J_k`. + Then `D` is surjective, `D(f g) = D(f) + D(g)` for + nonzero `f` and `g`, and `D(f + g) \geq \min(D(f), D(g))` + provided that `f + g` is nonzero. + + For example, `J_1` are series with no constant term, and + `J_2` are series such that `f[1]` and `f[p]` for prime + `p` vanish. + + Since this is a chain of increasing ideals, the ring of + formal Dirichlet series is not a + :wikipedia:`Noetherian_ring`. + + Evidently, this valuation cannot be computed for a given + series. + EXAMPLES:: sage: LazyDirichletSeriesRing(ZZ, 't') Lazy Dirichlet Series Ring in t over Integer Ring + + The ideal generated by `2^-s` and `3^-s` is not principal:: + + sage: L = LazyDirichletSeriesRing(QQ, 's') + sage: L in PrincipalIdealDomains + False """ Element = LazyDirichletSeries + # Follow the "generic" normalization + __classcall_private__ = LazySeriesRing.__classcall_private__ + def __init__(self, base_ring, names, sparse=True, category=None): """ Initialize the ring. TESTS:: - sage: LazyDirichletSeriesRing.options.halting_precision(15) + sage: LazyDirichletSeriesRing.options.halting_precision(12) sage: L = LazyDirichletSeriesRing(ZZ, 't') sage: TestSuite(L).run() @@ -2221,21 +2434,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() sage: LazyDirichletSeriesRing.options._reset() # reset the options - - The ideal generated by `2^-s` and `3^-s` is not principal:: - - sage: L = LazyDirichletSeriesRing(QQ, 's') - sage: L in PrincipalIdealDomains - False - - In particular, it is not a :wikipedia:`discrete_valuation_ring`. - - .. TODO:: - - According to the answers in - https://mathoverflow.net/questions/5522/dirichlet-series-with-integer-coefficients-as-a-ufd, - in particular, see :arxiv:`math/0105219`, the ring of formal - Dirichlet series is actually in :class:`UniqueFactorizationDomains`. """ if base_ring.characteristic() > 0: raise ValueError("positive characteristic not allowed for Dirichlet series") @@ -2247,8 +2445,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=True) category = Algebras(base_ring.category()) - #if base_ring in Fields(): - # category &= UniqueFactorizationDomains() if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): @@ -2498,3 +2694,4 @@ def _skip_leading_zeros(iterator): yield c break yield from iterator + From e077b6655df290286c71404f4756babc97965f24 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Mon, 19 Sep 2022 17:10:22 +0900 Subject: [PATCH 126/350] Using dynamic classes for FPS gcd. --- src/sage/combinat/species/generating_series.py | 14 ++++---------- src/sage/rings/lazy_series.py | 2 +- src/sage/rings/lazy_series_ring.py | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 6d92f30cf1d..c6c30f301b6 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -147,9 +147,7 @@ def __init__(self, base_ring): sage: R = OrdinaryGeneratingSeriesRing(QQ) sage: TestSuite(R).run() - Options are remembered across doctests:: - - sage: OrdinaryGeneratingSeriesRing.options.halting_precision(None) + sage: OrdinaryGeneratingSeriesRing.options._reset() # reset options """ super().__init__(base_ring, names="z") @@ -273,9 +271,7 @@ def __init__(self, base_ring): sage: R = ExponentialGeneratingSeriesRing(QQ) sage: TestSuite(R).run() - Options are remembered across doctests:: - - sage: ExponentialGeneratingSeriesRing.options.halting_precision(None) + sage: ExponentialGeneratingSeriesRing.options._reset() # reset options """ super().__init__(base_ring, names="z") @@ -556,13 +552,11 @@ def __init__(self, base_ring, sparse=True): TESTS:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing.options.halting_precision(15) + sage: CycleIndexSeriesRing.options.halting_precision(12) sage: R = CycleIndexSeriesRing(QQ) sage: TestSuite(R).run() - Options are remembered across doctests:: - - sage: CycleIndexSeriesRing.options.halting_precision(None) + sage: CycleIndexSeriesRing.options._reset() # reset options """ p = SymmetricFunctions(base_ring).power() super().__init__(p) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index da3f266ee96..02e0ebd5e43 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -4794,7 +4794,7 @@ def _floordiv_(self, other): left._approximate_order += 1 return super()._floordiv_(other) -class LazyPowerSeries_gcd(LazyPowerSeries): +class LazyPowerSeries_gcd_mixin: """ A lazy power series that also implements the GCD algorithm. """ diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 51a021feead..8d8f311c97b 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -60,7 +60,7 @@ from sage.rings.lazy_series import (LazyModuleElement, LazyLaurentSeries, LazyPowerSeries, - LazyPowerSeries_gcd, + LazyPowerSeries_gcd_mixin, LazyCompletionGradedAlgebraElement, LazySymmetricFunction, LazyDirichletSeries) @@ -871,7 +871,7 @@ def is_exact(self): def _test_invert(self, **options): """ - Test multiplicative inversion of elements of this ring. + Test multiplicative inversion of elements of ``self``. INPUT: @@ -879,8 +879,10 @@ def _test_invert(self, **options): EXAMPLES:: + sage: LazyLaurentSeriesRing.options.halting_precision(12) sage: L = LazyLaurentSeriesRing(QQ, 'z') sage: L._test_invert() + sage: LazyLaurentSeriesRing.options._reset() # reset the options .. SEEALSO:: @@ -1468,18 +1470,26 @@ def __init__(self, base_ring, names, sparse=True, category=None): else: self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE") category = Algebras(base_ring.category()) + mixin_gcd = False if self._arity == 1: if base_ring in Fields(): category &= CompleteDiscreteValuationRings() - self.Element = LazyPowerSeries_gcd + mixin_gcd = True elif base_ring in Fields(): category &= UniqueFactorizationDomains() - self.Element = LazyPowerSeries_gcd + mixin_gcd = True if base_ring in IntegralDomains(): category &= IntegralDomains() elif base_ring in Rings().Commutative(): category = category.Commutative() + if mixin_gcd: + from sage.structure.dynamic_class import dynamic_class + self.Element = dynamic_class( + f"{self.Element.__name__}_gcd", + (self.Element, LazyPowerSeries_gcd_mixin), + doccls=self.Element) + if base_ring.is_zero(): category = category.Finite() else: From ddc04a1a02b26270a89be3a2a56a193d6d794b42 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 20 Sep 2022 11:31:22 +0900 Subject: [PATCH 127/350] Fixing last pyflakes things. --- src/sage/rings/lazy_series.py | 2 -- src/sage/rings/lazy_series_ring.py | 1 - 2 files changed, 3 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 02e0ebd5e43..b370420f5c0 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -4893,9 +4893,7 @@ def xgcd(self, f): return (P.zero(), P.one(), P.zero()) # get the valuations sv = self.valuation() - sc = self[sv] fv = f.valuation() - fc = f[fv] val = min(sv, fv) assert val is not infinity # This assumes the base ring is a field diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 8d8f311c97b..57ba0724045 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -47,7 +47,6 @@ from sage.categories.rings import Rings from sage.categories.unique_factorization_domains import UniqueFactorizationDomains from sage.categories.integral_domains import IntegralDomains -from sage.categories.euclidean_domains import EuclideanDomains from sage.categories.fields import Fields from sage.categories.complete_discrete_valuation import (CompleteDiscreteValuationFields, CompleteDiscreteValuationRings) From 1dfeb141d5f661ea4ea3812f92472da2304a2ad5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 13:07:52 -0700 Subject: [PATCH 128/350] build/pkgs/gcc: Update to 12.2.0 --- build/pkgs/gcc/checksums.ini | 6 +++--- build/pkgs/gcc/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/gcc/checksums.ini b/build/pkgs/gcc/checksums.ini index 2ea976e85c1..996f8360f45 100644 --- a/build/pkgs/gcc/checksums.ini +++ b/build/pkgs/gcc/checksums.ini @@ -1,5 +1,5 @@ tarball=gcc-VERSION.tar.xz -sha1=cf86a48278f9a6f4b03d4390550577b20353b4e9 -md5=4ee3e8c4c99e7b3444eb79f00f5f7a7e -cksum=215110545 +sha1=5dce6dc0091b8049b530d1587513a07201691760 +md5=73bafd0af874439dcdb9fc063b6fb069 +cksum=2807184004 upstream_url=https://mirrors.kernel.org/gnu/gcc/gcc-VERSION/gcc-VERSION.tar.xz diff --git a/build/pkgs/gcc/package-version.txt b/build/pkgs/gcc/package-version.txt index f628d2eafc5..685332623b2 100644 --- a/build/pkgs/gcc/package-version.txt +++ b/build/pkgs/gcc/package-version.txt @@ -1 +1 @@ -11.3.0 +12.2.0 From 9ae559bbe825b1d400e636637c2df8f48809729b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 13:10:22 -0700 Subject: [PATCH 129/350] build/pkgs/gcc/patches/gcc-12.2.0-arm.patch: Import from https://raw.githubusercontent.com/Homebrew/formula-patches/1d184289/gcc/gcc-12.2.0-arm.diff --- build/pkgs/gcc/patches/gcc-12.2.0-arm.patch | 14243 ++++++++++++++++++ 1 file changed, 14243 insertions(+) create mode 100644 build/pkgs/gcc/patches/gcc-12.2.0-arm.patch diff --git a/build/pkgs/gcc/patches/gcc-12.2.0-arm.patch b/build/pkgs/gcc/patches/gcc-12.2.0-arm.patch new file mode 100644 index 00000000000..bcaade28c15 --- /dev/null +++ b/build/pkgs/gcc/patches/gcc-12.2.0-arm.patch @@ -0,0 +1,14243 @@ +diff --git a/Makefile.def b/Makefile.def +index 72d58549645..25b8563a808 100644 +--- a/Makefile.def ++++ b/Makefile.def +@@ -47,7 +47,8 @@ host_modules= { module= fixincludes; bootstrap=true; + host_modules= { module= flex; no_check_cross= true; }; + host_modules= { module= gas; bootstrap=true; }; + host_modules= { module= gcc; bootstrap=true; +- extra_make_flags="$(EXTRA_GCC_FLAGS)"; }; ++ extra_make_flags="$(EXTRA_GCC_FLAGS)"; ++ extra_configure_flags='--enable-pie-tools=@enable_pie_tools@'; }; + host_modules= { module= gmp; lib_path=.libs; bootstrap=true; + // Work around in-tree gmp configure bug with missing flex. + extra_configure_flags='--disable-shared LEX="touch lex.yy.c"'; +diff --git a/Makefile.in b/Makefile.in +index 593495e1650..807c5947895 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -112,6 +112,9 @@ GCC_SHLIB_SUBDIR = @GCC_SHLIB_SUBDIR@ + # If the build should make suitable code for shared host resources. + host_shared = @host_shared@ + ++# If we should build compilers and supporting tools as PIE. ++enable_pie_tools = @enable_pie_tools@ ++ + # Build programs are put under this directory. + BUILD_SUBDIR = @build_subdir@ + # This is set by the configure script to the arguments to use when configuring +@@ -12012,7 +12015,7 @@ configure-gcc: + $$s/$$module_srcdir/configure \ + --srcdir=$${topdir}/$$module_srcdir \ + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ +- --target=${target_alias} \ ++ --target=${target_alias} --enable-pie-tools=@enable_pie_tools@ \ + || exit 1 + @endif gcc + +@@ -12047,7 +12050,8 @@ configure-stage1-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + \ +- $(STAGE1_CONFIGURE_FLAGS) ++ $(STAGE1_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stage2-gcc maybe-configure-stage2-gcc +@@ -12080,7 +12084,8 @@ configure-stage2-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGE2_CONFIGURE_FLAGS) ++ $(STAGE2_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stage3-gcc maybe-configure-stage3-gcc +@@ -12113,7 +12118,8 @@ configure-stage3-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGE3_CONFIGURE_FLAGS) ++ $(STAGE3_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stage4-gcc maybe-configure-stage4-gcc +@@ -12146,7 +12152,8 @@ configure-stage4-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGE4_CONFIGURE_FLAGS) ++ $(STAGE4_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stageprofile-gcc maybe-configure-stageprofile-gcc +@@ -12179,7 +12186,8 @@ configure-stageprofile-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGEprofile_CONFIGURE_FLAGS) ++ $(STAGEprofile_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stagetrain-gcc maybe-configure-stagetrain-gcc +@@ -12212,7 +12220,8 @@ configure-stagetrain-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGEtrain_CONFIGURE_FLAGS) ++ $(STAGEtrain_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stagefeedback-gcc maybe-configure-stagefeedback-gcc +@@ -12245,7 +12254,8 @@ configure-stagefeedback-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGEfeedback_CONFIGURE_FLAGS) ++ $(STAGEfeedback_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stageautoprofile-gcc maybe-configure-stageautoprofile-gcc +@@ -12278,7 +12288,8 @@ configure-stageautoprofile-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGEautoprofile_CONFIGURE_FLAGS) ++ $(STAGEautoprofile_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + .PHONY: configure-stageautofeedback-gcc maybe-configure-stageautofeedback-gcc +@@ -12311,7 +12322,8 @@ configure-stageautofeedback-gcc: + $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ + --target=${target_alias} \ + --with-build-libsubdir=$(HOST_SUBDIR) \ +- $(STAGEautofeedback_CONFIGURE_FLAGS) ++ $(STAGEautofeedback_CONFIGURE_FLAGS) \ ++ --enable-pie-tools=@enable_pie_tools@ + @endif gcc-bootstrap + + +diff --git a/Makefile.tpl b/Makefile.tpl +index ef58fac2b9a..925da105c18 100644 +--- a/Makefile.tpl ++++ b/Makefile.tpl +@@ -115,6 +115,9 @@ GCC_SHLIB_SUBDIR = @GCC_SHLIB_SUBDIR@ + # If the build should make suitable code for shared host resources. + host_shared = @host_shared@ + ++# If we should build compilers and supporting tools as PIE. ++enable_pie_tools = @enable_pie_tools@ ++ + # Build programs are put under this directory. + BUILD_SUBDIR = @build_subdir@ + # This is set by the configure script to the arguments to use when configuring +diff --git a/config/mh-darwin b/config/mh-darwin +index b72835ae953..bb4112773c9 100644 +--- a/config/mh-darwin ++++ b/config/mh-darwin +@@ -11,7 +11,8 @@ + # non-bootstrapped compiler), later stages will be built by GCC which supports + # the required flags. + +-# We cannot use mdynamic-no-pic when building shared host resources. ++# We cannot use mdynamic-no-pic when building shared host resources, or for PIE ++# tool executables, which also enables host-shared. + + ifeq (${host_shared},no) + BOOTSTRAP_TOOL_CAN_USE_MDYNAMIC_NO_PIC := $(shell \ +diff --git a/configure b/configure +index 5dcaab14ae9..c690bbec82b 100755 +--- a/configure ++++ b/configure +@@ -685,6 +685,7 @@ get_gcc_base_ver + extra_host_zlib_configure_flags + extra_host_libiberty_configure_flags + stage1_languages ++enable_pie_tools + host_shared + extra_linker_plugin_flags + extra_linker_plugin_configure_flags +@@ -830,6 +831,7 @@ enable_lto + enable_linker_plugin_configure_flags + enable_linker_plugin_flags + enable_host_shared ++enable_pie_tools + enable_stage1_languages + enable_objc_gc + with_target_bdw_gc +@@ -1558,6 +1560,8 @@ Optional Features: + additional flags for configuring and building linker + plugins [none] + --enable-host-shared build host code as shared libraries ++ --enable-pie-tools build Position Independent Executables for the ++ compilers and other tools + --enable-stage1-languages[=all] + choose additional languages to build during stage1. + Mostly useful for compiler development +@@ -8410,6 +8414,20 @@ else + fi + fi + ++case $target in ++ *-darwin2* | *-darwin1[56789]*) ++ # For these versions, we default to using embedded rpaths. ++ if test "x$enable_darwin_at_rpath" != "xno"; then ++ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" ++ fi ++ ;; ++ *-darwin*) ++ # For these versions, we only use embedded rpaths on demand. ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" ++ fi ++ ;; ++esac + + + # GCC GRAPHITE dependency isl. +@@ -8663,6 +8681,42 @@ else + fi + + ++# Check whether --enable-pie-tools was given. ++# Checked early because it can affect host make fragments. ++# Check whether --enable-pie-tools was given. ++if test "${enable_pie_tools+set}" = set; then : ++ enableval=$enable_pie_tools; enable_pie_tools=$enableval ++ case $target in ++ aarch64-*-darwin1[1-9]*) ++ if test x$enable_pie_tools != xyes ; then ++ echo configure.ac: warning: aarch64-darwin must use PIE, pie-tools setting ignored. 1>&2 ++ enable_pie_tools=yes ++ host_shared=yes ++ fi ;; ++ *) ;; ++ esac ++else ++ case $target in ++ # PIE is the default for macOS 10.7+ so reflect that in the configure. ++ # However, we build 32b toolchains mdynamic-no-pic by default which is ++ # not compatible with PIE. ++ x86_64-*-darwin1[1-9]* | *-*-darwin2*) enable_pie_tools=yes ;; ++ *) enable_pie_tools=no ;; ++ esac ++fi ++ ++ ++case $target in ++ *-*-darwin*) ++ if test x$enable_pie_tools = xyes && test x$host_shared != xyes ; then ++ echo configure.ac: warning: for Darwin PIE requires PIC code, switching host-shared on 1>&2 ++ host_shared=yes ++ fi ;; ++ *) ;; ++esac ++ ++ ++ + + # By default, C and C++ are the only stage 1 languages. + stage1_languages=,c, +diff --git a/configure.ac b/configure.ac +index 85977482aee..72bd20fda66 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1827,6 +1827,20 @@ AC_ARG_WITH(boot-ldflags, + if test "$poststage1_libs" = ""; then + poststage1_ldflags="-static-libstdc++ -static-libgcc" + fi]) ++case $target in ++ *-darwin2* | *-darwin1[[56789]]*) ++ # For these versions, we default to using embedded rpaths. ++ if test "x$enable_darwin_at_rpath" != "xno"; then ++ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" ++ fi ++ ;; ++ *-darwin*) ++ # For these versions, we only use embedded rpaths on demand. ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" ++ fi ++ ;; ++esac + AC_SUBST(poststage1_ldflags) + + # GCC GRAPHITE dependency isl. +@@ -1931,7 +1945,41 @@ AC_ARG_ENABLE(host-shared, + x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;; + *) host_shared=no ;; + esac]) ++ ++# Check whether --enable-pie-tools was given. ++# Checked early because it can affect host make fragments. ++AC_ARG_ENABLE(pie-tools, ++[AS_HELP_STRING([--enable-pie-tools], ++ [build Position Independent Executables for the compilers and other tools])], ++[enable_pie_tools=$enableval ++ case $target in ++ aarch64-*-darwin1[[1-9]]*) ++ if test x$enable_pie_tools != xyes ; then ++ echo configure.ac: warning: aarch64-darwin must use PIE, pie-tools setting ignored. 1>&2 ++ enable_pie_tools=yes ++ host_shared=yes ++ fi ;; ++ *) ;; ++ esac], ++[case $target in ++ # PIE is the default for macOS 10.7+ so reflect that in the configure. ++ # However, we build 32b toolchains mdynamic-no-pic by default which is ++ # not compatible with PIE. ++ x86_64-*-darwin1[[1-9]]* | *-*-darwin2*) enable_pie_tools=yes ;; ++ *) enable_pie_tools=no ;; ++ esac]) ++ ++case $target in ++ *-*-darwin*) ++ if test x$enable_pie_tools = xyes && test x$host_shared != xyes ; then ++ echo configure.ac: warning: for Darwin PIE requires PIC code, switching host-shared on 1>&2 ++ host_shared=yes ++ fi ;; ++ *) ;; ++esac ++ + AC_SUBST(host_shared) ++AC_SUBST([enable_pie_tools]) + + # By default, C and C++ are the only stage 1 languages. + stage1_languages=,c, +diff --git a/contrib/compare-debug b/contrib/compare-debug +index cf80ae32695..678a897c931 100755 +--- a/contrib/compare-debug ++++ b/contrib/compare-debug +@@ -60,9 +60,19 @@ trap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 + case `uname -s` in + Darwin) + # The strip command on darwin does not remove all debug info. +- # Fortunately, we can use ld to do it instead. +- ld -S -r -no_uuid "$1" -o "$1.$suf1" +- ld -S -r -no_uuid "$2" -o "$2.$suf2" ++ # Fortunately, we can use ld to do it instead, but even ld on earlier ++ # system versions can be fussy about what it finds - make sure we use ++ # a ld that understands coalesced sections. ++ case `uname -r` in ++ 8*) ++ ld64 -S -r -no_uuid "$1" -o "$1.$suf1" ++ ld64 -S -r -no_uuid "$2" -o "$2.$suf2" ++ ;; ++ *) ++ ld -S -r -no_uuid "$1" -o "$1.$suf1" ++ ld -S -r -no_uuid "$2" -o "$2.$suf2" ++ ;; ++ esac + ;; + *) + cp "$1" "$1.$suf1" +diff --git a/fixincludes/configure b/fixincludes/configure +index 6e2d67b655b..b3bca666a4d 100755 +--- a/fixincludes/configure ++++ b/fixincludes/configure +@@ -2644,7 +2644,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + # _LT_DARWIN_LINKER_FEATURES + # -------------------------- +-# Checks for linker and compiler features on darwin ++# Checks for linker and compiler features on Darwin / macOS / iOS + + + # _LT_SYS_MODULE_PATH_AIX +diff --git a/gcc/Makefile.in b/gcc/Makefile.in +index 31ff95500c9..255a10c2ce8 100644 +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -270,11 +270,15 @@ COMPILER += $(CET_HOST_FLAGS) + NO_PIE_CFLAGS = @NO_PIE_CFLAGS@ + NO_PIE_FLAG = @NO_PIE_FLAG@ + +-# We don't want to compile the compilers with -fPIE, it make PCH fail. ++ifneq (@enable_pie_tools@,yes) ++# Build and link the compilers and tools without PIE. + COMPILER += $(NO_PIE_CFLAGS) +- +-# Link with -no-pie since we compile the compiler with -fno-PIE. + LINKER += $(NO_PIE_FLAG) ++else ++# FIXME these need to be configured. ++COMPILER += -fPIE ++LINKER += -pie ++endif + + # Like LINKER, but use a mutex for serializing front end links. + ifeq (@DO_LINK_MUTEX@,true) +@@ -407,6 +411,7 @@ ifeq ($(enable_plugin),yes) + endif + + enable_host_shared = @enable_host_shared@ ++enable_default_pie = @enable_default_pie@ + + enable_as_accelerator = @enable_as_accelerator@ + +@@ -1153,6 +1158,8 @@ LANG_MAKEFRAGS = @all_lang_makefrags@ + # Used by gcc/jit/Make-lang.in + LD_VERSION_SCRIPT_OPTION = @ld_version_script_option@ + LD_SONAME_OPTION = @ld_soname_option@ ++@ENABLE_DARWIN_AT_RPATH_TRUE@DARWIN_RPATH = @rpath ++@ENABLE_DARWIN_AT_RPATH_FALSE@DARWIN_RPATH = ${libdir} + + # Flags to pass to recursive makes. + # CC is set by configure. +@@ -1942,9 +1949,12 @@ cs-tconfig.h: Makefile + $(SHELL) $(srcdir)/mkconfig.sh tconfig.h + + cs-tm.h: Makefile +- TARGET_CPU_DEFAULT="$(target_cpu_default)" \ +- HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ +- $(SHELL) $(srcdir)/mkconfig.sh tm.h ++@ENABLE_DARWIN_AT_RPATH_FALSE@ TARGET_CPU_DEFAULT="$(target_cpu_default)" \ ++@ENABLE_DARWIN_AT_RPATH_FALSE@ HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ ++@ENABLE_DARWIN_AT_RPATH_FALSE@ $(SHELL) $(srcdir)/mkconfig.sh tm.h ++@ENABLE_DARWIN_AT_RPATH_TRUE@ TARGET_CPU_DEFAULT="$(target_cpu_default)" \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ HEADERS="$(tm_include_list)" DEFINES="$(tm_defines) DARWIN_AT_RPATH=1" \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ $(SHELL) $(srcdir)/mkconfig.sh tm.h + + cs-tm_p.h: Makefile + TARGET_CPU_DEFAULT="" \ +@@ -4116,6 +4126,9 @@ site.exp: ./config.status Makefile + echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./site.tmp; \ + else true; \ + fi ++ @if test "x@enable_darwin_at_rpath@" = "xyes" ; then \ ++ echo "set ENABLE_DARWIN_AT_RPATH 1" >> ./site.tmp; \ ++ fi + @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./site.tmp + @cat ./site.tmp > site.exp + @cat site.bak | sed \ +diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 +index 6be36df5190..126e09bbcd1 100644 +--- a/gcc/aclocal.m4 ++++ b/gcc/aclocal.m4 +@@ -12,6 +12,56 @@ + # PARTICULAR PURPOSE. + + m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) ++# AM_CONDITIONAL -*- Autoconf -*- ++ ++# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_CONDITIONAL(NAME, SHELL-CONDITION) ++# ------------------------------------- ++# Define a conditional. ++AC_DEFUN([AM_CONDITIONAL], ++[AC_PREREQ([2.52])dnl ++ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], ++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl ++AC_SUBST([$1_TRUE])dnl ++AC_SUBST([$1_FALSE])dnl ++_AM_SUBST_NOTMAKE([$1_TRUE])dnl ++_AM_SUBST_NOTMAKE([$1_FALSE])dnl ++m4_define([_AM_COND_VALUE_$1], [$2])dnl ++if $2; then ++ $1_TRUE= ++ $1_FALSE='#' ++else ++ $1_TRUE='#' ++ $1_FALSE= ++fi ++AC_CONFIG_COMMANDS_PRE( ++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then ++ AC_MSG_ERROR([[conditional "$1" was never defined. ++Usually this means the macro was only invoked conditionally.]]) ++fi])]) ++ ++# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# _AM_SUBST_NOTMAKE(VARIABLE) ++# --------------------------- ++# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. ++# This macro is traced by Automake. ++AC_DEFUN([_AM_SUBST_NOTMAKE]) ++ ++# AM_SUBST_NOTMAKE(VARIABLE) ++# -------------------------- ++# Public sister of _AM_SUBST_NOTMAKE. ++AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) ++ + m4_include([../libtool.m4]) + m4_include([../ltoptions.m4]) + m4_include([../ltsugar.m4]) +diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl +index aaf853e3a2a..b20218310f3 100644 +--- a/gcc/ada/Makefile.rtl ++++ b/gcc/ada/Makefile.rtl +@@ -2822,6 +2822,15 @@ ifeq ($(strip $(filter-out darwin%,$(target_os))),) + TOOLS_TARGET_PAIRS = indepsw.adb 8 * 1024 * 1024) ++ { ++ emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, sym)); ++ emit_insn (gen_add_losym (dest, tmp_reg, sym)); ++ /* FIXME: add the SI option if/when we support ilp32. */ ++ emit_insn (gen_adddi3 (dest, dest, off)); ++ return; ++ } ++ /* else small enough positive offset is OK. */ ++ } + emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm))); + emit_insn (gen_add_losym (dest, tmp_reg, imm)); + return; +@@ -4598,6 +4621,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, + return; + } + ++ case SYMBOL_MO_SMALL_GOT: + case SYMBOL_SMALL_GOT_4G: + emit_insn (gen_rtx_SET (dest, imm)); + return; +@@ -6659,6 +6683,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) + case SYMBOL_SMALL_TLSIE: + case SYMBOL_SMALL_GOT_28K: + case SYMBOL_SMALL_GOT_4G: ++ case SYMBOL_MO_SMALL_GOT: + case SYMBOL_TINY_GOT: + case SYMBOL_TINY_TLSIE: + if (const_offset != 0) +@@ -6672,6 +6697,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) + /* FALLTHRU */ + + case SYMBOL_SMALL_ABSOLUTE: ++ case SYMBOL_MO_SMALL_PCR: + case SYMBOL_TINY_ABSOLUTE: + case SYMBOL_TLSLE12: + case SYMBOL_TLSLE24: +@@ -7251,6 +7277,7 @@ aarch64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) + gcc_unreachable (); + } + ++#if !TARGET_MACHO + static bool + aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, + const_tree type, int *nregs) +@@ -7260,6 +7287,7 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, + &pcum->aapcs_vfp_rmode, + nregs, NULL, pcum->silent_p); + } ++#endif + + /* Given MODE and TYPE of a function argument, return the alignment in + bits. The idea is to suppress any stronger alignment requested by +@@ -7343,6 +7371,13 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + return; + + pcum->aapcs_arg_processed = true; ++ if (TARGET_MACHO) ++ { ++ /* Set suitable defaults for queries. */ ++ pcum->darwinpcs_arg_boundary ++ = aarch64_function_arg_alignment (mode, type, &abi_break); ++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; ++ } + + pure_scalable_type_info pst_info; + if (type && pst_info.analyze_registers (type)) +@@ -7399,13 +7434,29 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + /* No frontends can create types with variable-sized modes, so we + shouldn't be asked to pass or return them. */ + size = GET_MODE_SIZE (mode).to_constant (); ++ ++ if (TARGET_MACHO) ++ /* Since we can pack things on the stack, we need the unrounded size. */ ++ pcum->darwinpcs_stack_bytes = size; ++ + size = ROUND_UP (size, UNITS_PER_WORD); + + allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode); ++ bool is_ha = false; ++#if !TARGET_MACHO + allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v, + mode, + type, + &nregs); ++#else ++ /* We care if the value is a homogenous aggregate when laying out the stack, ++ so use this call directly. */ ++ allocate_nvrn ++ = aarch64_vfp_is_call_or_return_candidate (mode, type, ++ &pcum->aapcs_vfp_rmode, ++ &nregs, &is_ha, ++ pcum->silent_p); ++#endif + gcc_assert (!sve_p || !allocate_nvrn); + + /* allocate_ncrn may be false-positive, but allocate_nvrn is quite reliable. +@@ -7420,7 +7471,13 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + if (!pcum->silent_p && !TARGET_FLOAT) + aarch64_err_no_fpadvsimd (mode); + +- if (nvrn + nregs <= NUM_FP_ARG_REGS) ++ if (TARGET_MACHO ++ && !arg.named) ++ { ++ pcum->aapcs_nextnvrn = NUM_FP_ARG_REGS; ++ goto on_stack; ++ } ++ else if (nvrn + nregs <= NUM_FP_ARG_REGS) + { + pcum->aapcs_nextnvrn = nvrn + nregs; + if (!aarch64_composite_type_p (type, mode)) +@@ -7450,6 +7507,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + } + pcum->aapcs_reg = par; + } ++ pcum->darwinpcs_stack_bytes = 0; + return; + } + else +@@ -7466,10 +7524,18 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + /* C6 - C9. though the sign and zero extension semantics are + handled elsewhere. This is the case where the argument fits + entirely general registers. */ ++ + if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) + { + gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); + ++ if (TARGET_MACHO ++ && !arg.named) ++ { ++ pcum->aapcs_nextncrn = NUM_ARG_REGS; ++ goto on_stack; ++ } ++ + /* C.8 if the argument has an alignment of 16 then the NGRN is + rounded up to the next even number. */ + if (nregs == 2 +@@ -7479,7 +7545,9 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + alignment nregs should be > 2 and therefore it should be + passed by reference rather than value. */ + && (aarch64_function_arg_alignment (mode, type, &abi_break) +- == 16 * BITS_PER_UNIT)) ++ == 16 * BITS_PER_UNIT) ++ /* Darwin PCS deletes rule C.8. */ ++ && !TARGET_MACHO) + { + if (abi_break && warn_psabi && currently_expanding_gimple_stmt) + inform (input_location, "parameter passing for argument of type " +@@ -7525,8 +7593,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + } + pcum->aapcs_reg = par; + } +- + pcum->aapcs_nextncrn = ncrn + nregs; ++ pcum->darwinpcs_stack_bytes = 0; + return; + } + +@@ -7536,10 +7604,87 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) + /* The argument is passed on stack; record the needed number of words for + this argument and align the total size if necessary. */ + on_stack: +- pcum->aapcs_stack_words = size / UNITS_PER_WORD; + +- if (aarch64_function_arg_alignment (mode, type, &abi_break) +- == 16 * BITS_PER_UNIT) ++ unsigned int align = aarch64_function_arg_alignment (mode, type, &abi_break); ++ ++ if (TARGET_MACHO) ++ { ++ /* Darwin does not round up the allocation for smaller entities to 8 ++ bytes. It only requires the natural alignment for these. ++ ++ but we don't do this for: ++ * unnamed parms in variadic functions ++ * complex types ++ * unions ++ * aggregates (except for homogeneous ones which are handles as the ++ enclosed type). ++ each entry starts a new slot. ++ ++ 16 byte entities are naturally aligned on the stack. ++ There was no darwinpcs for GCC 9, so neither the implementation ++ change nor the warning should fire here (i.e. we do not need to check ++ if 16byte entities alter the stack size). */ ++ ++gcc_checking_assert (arg.named == pcum->named_p); ++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; ++ if (!pcum->named_p ++ || TREE_CODE (type) == COMPLEX_TYPE ++ || (TREE_CODE (type) == RECORD_TYPE ++ && !is_ha && !SCALAR_FLOAT_MODE_P (pcum->aapcs_vfp_rmode)) ++ || TREE_CODE (type) == UNION_TYPE) ++ { ++ pcum->aapcs_stack_words = size / UNITS_PER_WORD; ++ pcum->darwinpcs_sub_word_offset = 0; ++ pcum->darwinpcs_sub_word_pos = 0; ++ pcum->darwinpcs_arg_boundary = MAX (align, PARM_BOUNDARY); ++ if (!pcum->named_p) ++ pcum->darwinpcs_arg_padding = PARM_BOUNDARY; ++ return; ++ } ++ ++ /* Updated sub-word offset aligned for the new object. ++ We are looking for the case that the new object will fit after some ++ existing object(s) in the same stack slot. In that case, we do not ++ need to add any more stack space for it. */ ++ int new_off ++ = ROUND_UP (pcum->darwinpcs_sub_word_pos, align / BITS_PER_UNIT); ++ ++ if (new_off >= UNITS_PER_WORD) ++ { ++ /* That exceeds a stack slot, start a new one. */ ++ pcum->darwinpcs_sub_word_offset = 0; ++ pcum->darwinpcs_sub_word_pos = 0; ++ new_off = 0; ++ } ++ /* This is the end of the new object. */ ++ int new_pos = new_off + pcum->darwinpcs_stack_bytes; ++ ++ if (pcum->darwinpcs_sub_word_pos == 0) ++ /* New stack slot, just allocate one or more words, and note where ++ the next arg will start. */ ++ pcum->aapcs_stack_words = size / UNITS_PER_WORD; ++ else if (new_pos <= UNITS_PER_WORD) ++ /* Old stack slot, object starts at new_off and goes to new_pos, we do ++ not add any stack space. */ ++ pcum->darwinpcs_sub_word_offset = new_off; ++ pcum->darwinpcs_sub_word_pos = new_pos; ++ pcum->darwinpcs_arg_boundary = align; ++ if (pcum->last_named_p && new_pos > 0) ++ { ++ /* Round the last named arg to the start of the next stack slot. */ ++ if (new_pos <= 4) ++ pcum->darwinpcs_arg_padding = PARM_BOUNDARY; ++ else if (new_pos <= 6) ++ pcum->darwinpcs_arg_padding = 4 * BITS_PER_UNIT; ++ else if (pcum->darwinpcs_sub_word_pos <= 7) ++ pcum->darwinpcs_arg_padding = 2 * BITS_PER_UNIT; ++ } ++ return; ++ } ++ ++ /* size was already rounded up to PARM_BOUNDARY. */ ++ pcum->aapcs_stack_words = size / UNITS_PER_WORD; ++ if (align == 16 * BITS_PER_UNIT) + { + int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); + if (pcum->aapcs_stack_size != new_size) +@@ -7592,7 +7737,28 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, + pcum->aapcs_arg_processed = false; + pcum->aapcs_stack_words = 0; + pcum->aapcs_stack_size = 0; ++ pcum->darwinpcs_stack_bytes = 0; ++ pcum->darwinpcs_sub_word_offset = 0; ++ pcum->darwinpcs_sub_word_pos = 0; ++ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT; ++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; ++ /* If we have been invoked for incoming args, then n_named will have been ++ set to -1, but we should have a function decl - so pick up the named ++ count from that. If that fails, and we end up with -1, this effectively ++ corresponds to assuming that there is an arbitrary number of named ++ args. */ ++ pcum->darwinpcs_n_named = n_named; ++ if (n_named == (unsigned)-1 && fndecl) ++ { ++ tree fnt = TREE_TYPE (fndecl); ++ if (fnt && TYPE_ARG_TYPES (fnt)) ++ pcum->darwinpcs_n_named = list_length (TYPE_ARG_TYPES (fnt)); ++ } ++ pcum->darwinpcs_n_args_processed = 0; ++ pcum->named_p = pcum->darwinpcs_n_named != 0; ++ pcum->last_named_p = pcum->darwinpcs_n_named == 1; + pcum->silent_p = silent_p; ++ pcum->aapcs_vfp_rmode = VOIDmode; + + if (!silent_p + && !TARGET_FLOAT +@@ -7631,8 +7797,10 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v, + || pcum->pcs_variant == ARM_PCS_SVE) + { + aarch64_layout_arg (pcum_v, arg); +- gcc_assert ((pcum->aapcs_reg != NULL_RTX) +- != (pcum->aapcs_stack_words != 0)); ++ pcum->darwinpcs_n_args_processed++; ++ gcc_assert (TARGET_MACHO ++ || (pcum->aapcs_reg != NULL_RTX) ++ != (pcum->aapcs_stack_words != 0)); + pcum->aapcs_arg_processed = false; + pcum->aapcs_ncrn = pcum->aapcs_nextncrn; + pcum->aapcs_nvrn = pcum->aapcs_nextnvrn; +@@ -7640,6 +7808,12 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v, + pcum->aapcs_stack_size += pcum->aapcs_stack_words; + pcum->aapcs_stack_words = 0; + pcum->aapcs_reg = NULL_RTX; ++ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT; ++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; ++ pcum->named_p ++ = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; ++ pcum->last_named_p ++ = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named; + } + } + +@@ -7650,12 +7824,15 @@ aarch64_function_arg_regno_p (unsigned regno) + || (FP_REGNUM_P (regno) && regno < V0_REGNUM + NUM_FP_ARG_REGS)); + } + +-/* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least +- PARM_BOUNDARY bits of alignment, but will be given anything up +- to STACK_BOUNDARY bits if the type requires it. This makes sure +- that both before and after the layout of each argument, the Next +- Stacked Argument Address (NSAA) will have a minimum alignment of +- 8 bytes. */ ++/* Implement FUNCTION_ARG_BOUNDARY. ++ For AAPCS64, Every parameter gets at least PARM_BOUNDARY bits of ++ alignment, but will be given anything up to STACK_BOUNDARY bits ++ if the type requires it. This makes sure that both before and after ++ the layout of each argument, the Next Stacked Argument Address (NSAA) ++ will have a minimum alignment of 8 bytes. ++ ++ For darwinpcs, this is only called to lower va_arg entries which are ++ always aligned as for AAPCS64. */ + + static unsigned int + aarch64_function_arg_boundary (machine_mode mode, const_tree type) +@@ -7663,6 +7840,71 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type) + unsigned int abi_break; + unsigned int alignment = aarch64_function_arg_alignment (mode, type, + &abi_break); ++#if TARGET_MACHO ++ /* This can only work for unnamed args. */ ++ machine_mode comp_mode = VOIDmode; ++ int nregs; ++ bool is_ha; ++ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs, ++ &is_ha, /*silent*/true); ++ if (TREE_CODE (type) == COMPLEX_TYPE ++ || (TREE_CODE (type) == RECORD_TYPE ++ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode)) ++ || TREE_CODE (type) == UNION_TYPE) ++ return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); ++ return MIN (alignment, STACK_BOUNDARY); ++#else ++ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); ++ if (abi_break & warn_psabi) ++ { ++ abi_break = MIN (MAX (abi_break, PARM_BOUNDARY), STACK_BOUNDARY); ++ if (alignment != abi_break && !TARGET_MACHO) ++ inform (input_location, "parameter passing for argument of type " ++ "%qT changed in GCC 9.1", type); ++ } ++ ++ return alignment; ++#endif ++} ++ ++/* For Darwin, we want to use the arg boundary computed when laying out the ++ function arg, to cope with items packed on the stack and the different ++ rules applied to unnamed parms. */ ++ ++static unsigned int ++aarch64_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, ++ const_tree type ATTRIBUTE_UNUSED, ++ cumulative_args_t ca ATTRIBUTE_UNUSED) ++{ ++ unsigned int abi_break; ++ unsigned int alignment = aarch64_function_arg_alignment (mode, type, ++ &abi_break); ++#if TARGET_MACHO ++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); ++gcc_checking_assert (pcum->aapcs_arg_processed); ++ ++ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; ++gcc_checking_assert (named_p == pcum->named_p); ++ machine_mode comp_mode = VOIDmode; ++ int nregs; ++ bool is_ha; ++ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs, ++ &is_ha, /*silent*/true); ++ bool no_pack = (TREE_CODE (type) == COMPLEX_TYPE ++ || (TREE_CODE (type) == RECORD_TYPE ++ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode)) ++ || TREE_CODE (type) == UNION_TYPE); ++ ++ bool in_regs = (pcum->aapcs_reg != NULL_RTX); ++ ++ if ((named_p && !no_pack) || in_regs) ++ ; /* Leave the alignment as natural. */ ++ else ++ alignment = MAX (alignment, PARM_BOUNDARY); ++gcc_checking_assert (alignment == pcum->darwinpcs_arg_boundary); ++ return MIN (alignment, STACK_BOUNDARY); ++ ++#else + alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); + if (abi_break & warn_psabi) + { +@@ -7673,6 +7915,44 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type) + } + + return alignment; ++#endif ++} ++ ++/* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA for darwinpcs which allows ++ non-standard passing of byte-aligned items [D.2]. This is done by pulling ++ the values out of the cumulative args struct. */ ++ ++static unsigned int ++aarch64_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, ++ const_tree type ATTRIBUTE_UNUSED, ++ cumulative_args_t ca) ++{ ++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); ++gcc_checking_assert (pcum->aapcs_arg_processed); ++ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; ++gcc_checking_assert (named_p == pcum->named_p); ++ bool last_named_p = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named; ++gcc_checking_assert (last_named_p == pcum->last_named_p); ++ ++ unsigned boundary = BITS_PER_UNIT; ++ if (last_named_p && pcum->darwinpcs_sub_word_pos > 0) ++ { ++ /* Round the last named arg to the start of the next stack slot. */ ++ if (pcum->darwinpcs_sub_word_pos <= 4) ++ boundary = PARM_BOUNDARY; ++ else if (pcum->darwinpcs_sub_word_pos <= 6) ++ boundary = 4 * BITS_PER_UNIT; ++ else if (pcum->darwinpcs_sub_word_pos <= 7) ++ boundary = 2 * BITS_PER_UNIT; ++ } ++ else if (named_p) ++ /* Named args are naturally aligned, but with no rounding. */ ++ ; ++ else ++ /* un-named args are rounded to fill slots. */ ++ boundary = PARM_BOUNDARY; ++gcc_checking_assert (boundary == pcum->darwinpcs_arg_padding); ++ return boundary; + } + + /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ +@@ -10848,6 +11128,7 @@ aarch64_classify_address (struct aarch64_address_info *info, + /* load literal: pc-relative constant pool entry. Only supported + for SI mode or larger. */ + info->type = ADDRESS_SYMBOLIC; ++ info->offset = NULL_RTX; + + if (!load_store_pair_p + && GET_MODE_SIZE (mode).is_constant (&const_size) +@@ -10855,6 +11136,7 @@ aarch64_classify_address (struct aarch64_address_info *info, + { + poly_int64 offset; + rtx sym = strip_offset_and_salt (x, &offset); ++ + return ((LABEL_REF_P (sym) + || (SYMBOL_REF_P (sym) + && CONSTANT_POOL_ADDRESS_P (sym) +@@ -10872,10 +11154,13 @@ aarch64_classify_address (struct aarch64_address_info *info, + poly_int64 offset; + HOST_WIDE_INT const_offset; + rtx sym = strip_offset_and_salt (info->offset, &offset); ++ + if (SYMBOL_REF_P (sym) + && offset.is_constant (&const_offset) + && (aarch64_classify_symbol (sym, const_offset) +- == SYMBOL_SMALL_ABSOLUTE)) ++ == SYMBOL_SMALL_ABSOLUTE ++ || aarch64_classify_symbol (sym, const_offset) ++ == SYMBOL_MO_SMALL_PCR)) + { + /* The symbol and offset must be aligned to the access size. */ + unsigned int align; +@@ -10925,6 +11210,55 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) + if (!res) + return false; + ++ /* For ELF targets using GAS, we emit prfm unconditionally; GAS will alter ++ the instruction to pick the prfum form where possible (i.e. when the ++ offset is in the range -256..255) and fall back to prfm otherwise. ++ We can reject cases where the offset exceeds the range usable by both ++ insns [-256..32760], or for offsets > 255 when the value is not divisible ++ by 8. ++ For Mach-O (Darwin) where the assembler uses the LLVM back end, that does ++ not yet do the substitution, so we must reject all prfum cases. */ ++ if (addr.offset) ++ { ++ HOST_WIDE_INT offs = INTVAL (addr.offset); ++ if (offs < -256) /* Out of range for both prfum and prfm. */ ++ return false; ++ if (offs > 32760) /* Out of range for prfm. */ ++ return false; ++ if (offs & 0x07) /* We cannot use prfm. */ ++ { ++ if (offs > 255) /* Out of range for prfum. */ ++ return false; ++ if (TARGET_MACHO) ++ return false; ++ } ++ if (TARGET_MACHO && offs < 0) ++ return false; ++ } ++ ++ /* ... except writeback forms. */ ++ return addr.type != ADDRESS_REG_WB; ++} ++ ++/* Return true if the address X is valid for a PRFUM instruction. ++ STRICT_P is true if we should do strict checking with ++ aarch64_classify_address. */ ++ ++bool ++aarch64_address_valid_for_unscaled_prefetch_p (rtx x, bool strict_p) ++{ ++ struct aarch64_address_info addr; ++ ++ /* PRFUM accepts the same addresses as DImode, but constrained to a range ++ -256..255. */ ++ bool res = aarch64_classify_address (&addr, x, DImode, strict_p); ++ if (!res) ++ return false; ++ ++ if (addr.offset && ((INTVAL (addr.offset) > 255) ++ || (INTVAL (addr.offset) < -256))) ++ return false; ++ + /* ... except writeback forms. */ + return addr.type != ADDRESS_REG_WB; + } +@@ -11609,6 +11943,144 @@ sizetochar (int size) + } + } + ++static void ++output_macho_postfix_expr (FILE *file, rtx x, const char *postfix) ++{ ++ char buf[256]; ++ ++ restart: ++ switch (GET_CODE (x)) ++ { ++ case PC: ++ putc ('.', file); ++ break; ++ ++ case SYMBOL_REF: ++ if (SYMBOL_REF_DECL (x)) ++ assemble_external (SYMBOL_REF_DECL (x)); ++ assemble_name (file, XSTR (x, 0)); ++ fprintf (file, "@%s", postfix); ++ break; ++ ++ case LABEL_REF: ++ x = label_ref_label (x); ++ /* Fall through. */ ++ case CODE_LABEL: ++ ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); ++ assemble_name (file, buf); ++ fprintf (file, "@%s", postfix); ++ break; ++ ++ case CONST_INT: ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); ++ break; ++ ++ case CONST: ++ /* This used to output parentheses around the expression, ++ but that does not work on the 386 (either ATT or BSD assembler). */ ++ output_macho_postfix_expr (file, XEXP (x, 0), postfix); ++ break; ++ ++ case CONST_WIDE_INT: ++ /* We do not know the mode here so we have to use a round about ++ way to build a wide-int to get it printed properly. */ ++ { ++ wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0), ++ CONST_WIDE_INT_NUNITS (x), ++ CONST_WIDE_INT_NUNITS (x) ++ * HOST_BITS_PER_WIDE_INT, ++ false); ++ print_decs (w, file); ++ } ++ break; ++ ++ case CONST_DOUBLE: ++ if (CONST_DOUBLE_AS_INT_P (x)) ++ { ++ /* We can use %d if the number is one word and positive. */ ++ if (CONST_DOUBLE_HIGH (x)) ++ fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, ++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x), ++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); ++ else if (CONST_DOUBLE_LOW (x) < 0) ++ fprintf (file, HOST_WIDE_INT_PRINT_HEX, ++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); ++ else ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); ++ } ++ else ++ /* We can't handle floating point constants; ++ PRINT_OPERAND must handle them. */ ++ output_operand_lossage ("floating constant misused"); ++ break; ++ ++ case CONST_FIXED: ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x)); ++ break; ++ ++ case PLUS: ++ /* Some assemblers need integer constants to appear last (eg masm). */ ++ if (CONST_INT_P (XEXP (x, 0))) ++ { ++ output_macho_postfix_expr (file, XEXP (x, 1), postfix); ++ if (INTVAL (XEXP (x, 0)) >= 0) ++ fprintf (file, "+"); ++ output_addr_const (file, XEXP (x, 0)); ++ } ++ else ++ { ++ output_macho_postfix_expr (file, XEXP (x, 0), postfix); ++ if (!CONST_INT_P (XEXP (x, 1)) ++ || INTVAL (XEXP (x, 1)) >= 0) ++ fprintf (file, "+"); ++ output_addr_const (file, XEXP (x, 1)); ++ } ++ break; ++ ++ case MINUS: ++ /* Avoid outputting things like x-x or x+5-x, ++ since some assemblers can't handle that. */ ++ x = simplify_subtraction (x); ++ if (GET_CODE (x) != MINUS) ++ goto restart; ++ ++ output_macho_postfix_expr (file, XEXP (x, 0), postfix); ++ fprintf (file, "-"); ++ if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0) ++ || GET_CODE (XEXP (x, 1)) == PC ++ || GET_CODE (XEXP (x, 1)) == SYMBOL_REF) ++ output_addr_const (file, XEXP (x, 1)); ++ else ++ { ++ fputs (targetm.asm_out.open_paren, file); ++ output_addr_const (file, XEXP (x, 1)); ++ fputs (targetm.asm_out.close_paren, file); ++ } ++ break; ++ ++ case ZERO_EXTEND: ++ case SIGN_EXTEND: ++ case SUBREG: ++ case TRUNCATE: ++ output_addr_const (file, XEXP (x, 0)); ++ break; ++ ++ case UNSPEC: ++ if (XINT (x, 1) == UNSPEC_SALT_ADDR) ++ { ++ output_macho_postfix_expr (file, XVECEXP (x, 0, 0), postfix); ++ break; ++ } ++ /* FALLTHROUGH */ ++ default: ++ if (targetm.asm_out.output_addr_const_extra (file, x)) ++ break; ++ ++ output_operand_lossage ("invalid expression as operand"); ++ } ++ ++} ++ + /* Print operand X to file F in a target specific manner according to CODE. + The acceptable formatting commands given by CODE are: + 'c': An integer or symbol address without a preceding # +@@ -11677,6 +12149,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) + } + break; + ++ case 'K': ++ output_macho_postfix_expr (f, x, "PAGEOFF"); ++ break; ++ case 'O': ++ output_macho_postfix_expr (f, x, "GOTPAGEOFF"); ++ break; + case 'e': + { + x = unwrap_const_vec_duplicate (x); +@@ -12000,7 +12478,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) + case 'A': + if (GET_CODE (x) == HIGH) + x = XEXP (x, 0); +- ++#if !TARGET_MACHO + switch (aarch64_classify_symbolic_expression (x)) + { + case SYMBOL_SMALL_GOT_4G: +@@ -12031,9 +12509,29 @@ aarch64_print_operand (FILE *f, rtx x, int code) + break; + } + output_addr_const (asm_out_file, x); ++#endif ++#if TARGET_MACHO ++ // FIXME update classify symbolic expression to handle macho. ++ switch (aarch64_classify_symbolic_expression (x)) ++ { ++ case SYMBOL_MO_SMALL_PCR: ++ output_macho_postfix_expr (asm_out_file, x, "PAGE"); ++// asm_fprintf (asm_out_file, "@PAGE;mopcr"); ++ break; ++ case SYMBOL_MO_SMALL_GOT: ++ output_macho_postfix_expr (asm_out_file, x, "GOTPAGE"); ++// asm_fprintf (asm_out_file, "@GOTPAGE;mosg"); ++ break; ++ default: ++ output_macho_postfix_expr (asm_out_file, x, "BLEAH"); ++// asm_fprintf (asm_out_file, "@BLEAH"); ++ break; ++ } ++#endif + break; + + case 'L': ++#if !TARGET_MACHO + switch (aarch64_classify_symbolic_expression (x)) + { + case SYMBOL_SMALL_GOT_4G: +@@ -12071,10 +12569,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) + default: + break; + } ++#endif + output_addr_const (asm_out_file, x); + break; + + case 'G': ++#if !TARGET_MACHO + switch (aarch64_classify_symbolic_expression (x)) + { + case SYMBOL_TLSLE24: +@@ -12083,6 +12583,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) + default: + break; + } ++#endif + output_addr_const (asm_out_file, x); + break; + +@@ -12232,8 +12733,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, + break; + + case ADDRESS_LO_SUM: ++#if TARGET_MACHO ++ asm_fprintf (f, "[%s, #", reg_names [REGNO (addr.base)]); ++ output_macho_postfix_expr (f, addr.offset, "PAGEOFF"); ++// output_addr_const (f, addr.offset); ++#else + asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]); + output_addr_const (f, addr.offset); ++#endif + asm_fprintf (f, "]"); + return true; + +@@ -12703,6 +13210,8 @@ aarch64_asm_output_labelref (FILE* f, const char *name) + asm_fprintf (f, "%U%s", name); + } + ++#if !TARGET_MACHO ++ + static void + aarch64_elf_asm_constructor (rtx symbol, int priority) + { +@@ -12742,6 +13251,7 @@ aarch64_elf_asm_destructor (rtx symbol, int priority) + assemble_aligned_integer (POINTER_BYTES, symbol); + } + } ++#endif + + const char* + aarch64_output_casesi (rtx *operands) +@@ -15048,15 +15558,17 @@ aarch64_init_builtins () + { + aarch64_general_init_builtins (); + aarch64_sve::init_builtins (); +-#ifdef SUBTARGET_INIT_BUILTINS +- SUBTARGET_INIT_BUILTINS; +-#endif ++ aarch64_init_subtarget_builtins (); + } + + /* Implement TARGET_FOLD_BUILTIN. */ + static tree + aarch64_fold_builtin (tree fndecl, int nargs, tree *args, bool) + { ++#ifdef SUBTARGET_FOLD_BUILTIN ++ if (tree res = SUBTARGET_FOLD_BUILTIN (fndecl, nargs, args, false)) ++ return res; ++#endif + unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); + unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; + tree type = TREE_TYPE (TREE_TYPE (fndecl)); +@@ -18326,10 +18838,14 @@ initialize_aarch64_code_model (struct gcc_options *opts) + } + break; + case AARCH64_CMODEL_LARGE: +- if (opts->x_flag_pic) ++ if (TARGET_MACHO) ++ /* We need to implement fPIC here (arm64_32 also accepts the large ++ model). */ ++ ; ++ else if (opts->x_flag_pic) + sorry ("code model %qs with %<-f%s%>", "large", + opts->x_flag_pic > 1 ? "PIC" : "pic"); +- if (opts->x_aarch64_abi == AARCH64_ABI_ILP32) ++ else if (opts->x_aarch64_abi == AARCH64_ABI_ILP32) + sorry ("code model %qs not supported in ilp32 mode", "large"); + break; + case AARCH64_CMODEL_TINY_PIC: +@@ -19252,7 +19768,9 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) + case AARCH64_CMODEL_SMALL_SPIC: + case AARCH64_CMODEL_SMALL_PIC: + case AARCH64_CMODEL_SMALL: +- return SYMBOL_SMALL_ABSOLUTE; ++ return TARGET_MACHO ++ ? SYMBOL_MO_SMALL_PCR ++ : SYMBOL_SMALL_ABSOLUTE; + + default: + gcc_unreachable (); +@@ -19288,10 +19806,22 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) + + return SYMBOL_TINY_ABSOLUTE; + +- + case AARCH64_CMODEL_SMALL_SPIC: + case AARCH64_CMODEL_SMALL_PIC: + case AARCH64_CMODEL_SMALL: ++#if TARGET_MACHO ++ if (TARGET_MACHO) ++ { ++ /* Constant pool addresses are always TU-local and PC- ++ relative. We indirect common, external and weak ++ symbols (but weak only if not hidden). */ ++ if (!CONSTANT_POOL_ADDRESS_P (x) ++ && (MACHO_SYMBOL_MUST_INDIRECT_P (x) ++ || !aarch64_symbol_binds_local_p (x))) ++ return SYMBOL_MO_SMALL_GOT; ++ } ++ else ++#endif + if ((flag_pic || SYMBOL_REF_WEAK (x)) + && !aarch64_symbol_binds_local_p (x)) + return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC +@@ -19303,7 +19833,8 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) + || offset_within_block_p (x, offset))) + return SYMBOL_FORCE_TO_MEM; + +- return SYMBOL_SMALL_ABSOLUTE; ++ return TARGET_MACHO ? SYMBOL_MO_SMALL_PCR ++ : SYMBOL_SMALL_ABSOLUTE; + + case AARCH64_CMODEL_LARGE: + /* This is alright even in PIC code as the constant +@@ -19433,7 +19964,10 @@ static GTY(()) tree va_list_type; + void *__vr_top; + int __gr_offs; + int __vr_offs; +- }; */ ++ }; ++ ++ darwinpcs uses 'char *' for the va_list (in common with other platform ++ ports). */ + + static tree + aarch64_build_builtin_va_list (void) +@@ -19441,6 +19975,13 @@ aarch64_build_builtin_va_list (void) + tree va_list_name; + tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; + ++ /* darwinpcs uses a simple char * for this. */ ++ if (TARGET_MACHO) ++ { ++ va_list_type = build_pointer_type (char_type_node); ++ return va_list_type; ++ } ++ + /* Create the type. */ + va_list_type = lang_hooks.types.make_type (RECORD_TYPE); + /* Give it the required name. */ +@@ -19512,6 +20053,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) + int vr_save_area_size = cfun->va_list_fpr_size; + int vr_offset; + ++ /* darwinpcs uses the default, char * va_list impl. */ ++ if (TARGET_MACHO) ++ { ++ std_expand_builtin_va_start (valist, nextarg); ++ return; ++ } ++ + cum = &crtl->args.info; + if (cfun->va_list_gpr_size) + gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD, +@@ -19602,6 +20150,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, + HOST_WIDE_INT size, rsize, adjust, align; + tree t, u, cond1, cond2; + ++ if (TARGET_MACHO) ++ return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); ++ + indirect_p = pass_va_arg_by_reference (type); + if (indirect_p) + type = build_pointer_type (type); +@@ -19786,8 +20337,18 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, + field_ptr_t = double_ptr_type_node; + break; + case E_TFmode: +- field_t = long_double_type_node; +- field_ptr_t = long_double_ptr_type_node; ++ if (TARGET_MACHO) ++ { ++ /* Darwin has __float128, and long double is the same as ++ double. */ ++ field_t = float128_type_node; ++ field_ptr_t = aarch64_float128_ptr_type_node; ++ } ++ else ++ { ++ field_t = long_double_type_node; ++ field_ptr_t = long_double_ptr_type_node; ++ } + break; + case E_HFmode: + field_t = aarch64_fp16_type_node; +@@ -19858,6 +20419,9 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, + int gr_saved = cfun->va_list_gpr_size; + int vr_saved = cfun->va_list_fpr_size; + ++ if (TARGET_MACHO) ++ return default_setup_incoming_varargs (cum_v, arg, pretend_size, no_rtl); ++ + /* The caller has advanced CUM up to, but not beyond, the last named + argument. Advance a local copy of CUM past the last "real" named + argument, to find out how many registers are left over. */ +@@ -20685,6 +21249,12 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool) + static const char * + aarch64_mangle_type (const_tree type) + { ++ /* The darwinpcs ABI documents say that "__va_list" has to be ++ mangled as char *. */ ++ if (TARGET_MACHO ++ && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) ++ return "Pc"; ++ + /* The AArch64 ABI documents say that "__va_list" has to be + mangled as if it is in the "std" namespace. */ + if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) +@@ -20699,6 +21269,10 @@ aarch64_mangle_type (const_tree type) + return "Dh"; + } + ++ /* TFmode is __float128 for Darwin. */ ++ if (TARGET_MACHO && TYPE_MODE (type) == TFmode) ++ return "g"; ++ + /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for + builtin types. */ + if (TYPE_NAME (type) != NULL) +@@ -21389,7 +21963,8 @@ aarch64_mov_operand_p (rtx x, machine_mode mode) + + /* GOT accesses are valid moves. */ + if (SYMBOL_REF_P (x) +- && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G) ++ && (aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G ++ || aarch64_classify_symbolic_expression (x) == SYMBOL_MO_SMALL_GOT)) + return true; + + if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x)) +@@ -22549,7 +23124,9 @@ aarch64_declare_function_name (FILE *stream, const char* name, + aarch64_asm_output_variant_pcs (stream, fndecl, name); + + /* Don't forget the type directive for ELF. */ ++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE + ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function"); ++#endif + ASM_OUTPUT_LABEL (stream, name); + + cfun->machine->label_is_assembled = true; +@@ -22584,12 +23161,17 @@ aarch64_print_patchable_function_entry (FILE *file, + /* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */ + + void +-aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target) ++aarch64_asm_output_alias (FILE *stream, const tree decl, ++ const tree target ATTRIBUTE_UNUSED) + { + const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); ++#ifdef ASM_OUTPUT_DEF + const char *value = IDENTIFIER_POINTER (target); ++#endif + aarch64_asm_output_variant_pcs (stream, decl, name); ++#ifdef ASM_OUTPUT_DEF + ASM_OUTPUT_DEF (stream, name, value); ++#endif + } + + /* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined +@@ -23213,6 +23795,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, + } + + gcc_assert (CONST_INT_P (info.u.mov.value)); ++ unsigned HOST_WIDE_INT value = UINTVAL (info.u.mov.value); ++ ++ /* We have signed chars which can result in a sign-extended 8bit value ++ which is then emitted as an unsigned hex value, and the LLVM back end ++ assembler rejects that as being too big. */ ++ if (TARGET_MACHO && (known_eq (GET_MODE_BITSIZE (info.elt_mode), 8))) ++ { ++ unsigned HOST_WIDE_INT mask = (1U << GET_MODE_BITSIZE (info.elt_mode))-1; ++ value &= mask; ++ } + + if (which == AARCH64_CHECK_MOV) + { +@@ -23221,16 +23813,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, + ? "msl" : "lsl"); + if (lane_count == 1) + snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, +- mnemonic, UINTVAL (info.u.mov.value)); ++ mnemonic, value); + else if (info.u.mov.shift) + snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " + HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count, +- element_char, UINTVAL (info.u.mov.value), shift_op, ++ element_char, value, shift_op, + info.u.mov.shift); + else + snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " + HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count, +- element_char, UINTVAL (info.u.mov.value)); ++ element_char, value); + } + else + { +@@ -23239,12 +23831,12 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, + if (info.u.mov.shift) + snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" + HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count, +- element_char, UINTVAL (info.u.mov.value), "lsl", ++ element_char, value, "lsl", + info.u.mov.shift); + else + snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" + HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count, +- element_char, UINTVAL (info.u.mov.value)); ++ element_char, value); + } + return templ; + } +@@ -26355,12 +26947,12 @@ aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode) + } + + /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE +- if MODE is HFmode, and punt to the generic implementation otherwise. */ ++ if MODE is HFmode, or TFmode on Mach-O, and punt to the generic implementation otherwise. */ + + static bool + aarch64_scalar_mode_supported_p (scalar_mode mode) + { +- return (mode == HFmode ++ return (mode == HFmode || (mode == TFmode && TARGET_MACHO) + ? true + : default_scalar_mode_supported_p (mode)); + } +@@ -27118,19 +27710,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE *out_file) + continue; + + const char *name = indirect_symbol_names[regnum]; +- switch_to_section (get_named_section (decl, NULL, 0)); ++ /* If the target uses a unique section for this switch to it. */ ++ if (DECL_SECTION_NAME (decl)) ++ switch_to_section (get_named_section (decl, NULL, 0)); ++ else ++ switch_to_section (text_section); + ASM_OUTPUT_ALIGN (out_file, 2); +- targetm.asm_out.globalize_label (out_file, name); ++ if (!TARGET_MACHO) ++ targetm.asm_out.globalize_label (out_file, name); ++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE ++ ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); ++#endif ++ if (TARGET_MACHO) ++ { ++#ifdef ASM_WEAKEN_DECL ++ if (DECL_WEAK (decl)) ++ ASM_WEAKEN_DECL (out_file, decl, name, 0); ++ else ++#endif ++ targetm.asm_out.globalize_decl_name (out_file, decl); ++ } + /* Only emits if the compiler is configured for an assembler that can + handle visibility directives. */ + targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); +- ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); + ASM_OUTPUT_LABEL (out_file, name); + aarch64_sls_emit_function_stub (out_file, regnum); + /* Use the most conservative target to ensure it can always be used by any + function in the translation unit. */ + asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n"); ++#ifdef ASM_DECLARE_FUNCTION_SIZE + ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl); ++#endif + } + } + +@@ -27323,6 +27933,15 @@ aarch64_run_selftests (void) + #undef TARGET_ASM_ALIGNED_SI_OP + #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" + ++#if TARGET_MACHO ++#undef TARGET_ASM_UNALIGNED_HI_OP ++#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" ++#undef TARGET_ASM_UNALIGNED_SI_OP ++#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" ++#undef TARGET_ASM_UNALIGNED_DI_OP ++#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t" ++#endif ++ + #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK + #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ + hook_bool_const_tree_hwi_hwi_const_tree_true +@@ -27409,6 +28028,12 @@ aarch64_run_selftests (void) + #undef TARGET_FUNCTION_ARG_BOUNDARY + #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary + ++#undef TARGET_FUNCTION_ARG_BOUNDARY_CA ++#define TARGET_FUNCTION_ARG_BOUNDARY_CA aarch64_function_arg_boundary_ca ++ ++#undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA ++#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA aarch64_function_arg_round_boundary_ca ++ + #undef TARGET_FUNCTION_ARG_PADDING + #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding + +@@ -27736,7 +28361,7 @@ aarch64_libgcc_floating_mode_supported_p + + /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors. */ + #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS +-#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 ++#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS AARCH64_CUSTOM_FUNCTION_TEST + + #undef TARGET_HARD_REGNO_NREGS + #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs +diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h +index 359b6e8561f..db5fe441b36 100644 +--- a/gcc/config/aarch64/aarch64.h ++++ b/gcc/config/aarch64/aarch64.h +@@ -58,6 +58,10 @@ + #define TARGET_SIMD (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SIMD) + #define TARGET_FLOAT (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_FP) + ++/* If this is non-zero then generated code of the object format, ABI and ++ assembler syntax used by Darwin (Mach-O) platforms. */ ++#define TARGET_MACHO 0 ++ + #define UNITS_PER_WORD 8 + + #define UNITS_PER_VREG 16 +@@ -135,6 +139,12 @@ + /* Heap alignment (same as BIGGEST_ALIGNMENT and STACK_BOUNDARY). */ + #define MALLOC_ABI_ALIGNMENT 128 + ++/* We will and with this value to test if a custom function descriptor needs ++ a static chain. The function boundary must the adjusted so that the bit ++ this represents is no longer part of the address. 0 Disables the custom ++ function descriptors. */ ++#define AARCH64_CUSTOM_FUNCTION_TEST 4 ++ + /* Defined by the ABI */ + #define WCHAR_TYPE "unsigned int" + #define WCHAR_TYPE_SIZE 32 +@@ -1025,6 +1035,24 @@ typedef struct + aapcs_reg == NULL_RTX. */ + int aapcs_stack_size; /* The total size (in words, per 8 byte) of the + stack arg area so far. */ ++ ++ /* In the darwinpcs, items smaller than one word are packed onto the stack ++ naturally aligned. Unnamed parameters passed in a variadic call are, ++ however, aligned the same way as the AAPCS64. This means that we need to ++ pad the last named arg to the next parm boundary (and hence notice when ++ we are processing that arg). */ ++ int darwinpcs_stack_bytes; /* If the argument is passed on the stack, this ++ the byte-size. */ ++ int darwinpcs_sub_word_offset;/* This is the offset of this arg within a word ++ when placing smaller items for darwinpcs. */ ++ int darwinpcs_sub_word_pos; /* The next byte available within the word for ++ darwinpcs. */ ++ unsigned darwinpcs_arg_boundary; /* The computed argument boundary. */ ++ unsigned darwinpcs_arg_padding; /* The computed argument padding. */ ++ unsigned darwinpcs_n_named; /* Number of named arguments. */ ++ unsigned darwinpcs_n_args_processed; /* Processed so far. */ ++ bool named_p; /* Is this arg named? */ ++ bool last_named_p; /* Is this the last named arg? */ + bool silent_p; /* True if we should act silently, rather than + raise an error for invalid calls. */ + } CUMULATIVE_ARGS; +@@ -1309,8 +1337,13 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); + #define ASM_CPU_SPEC \ + MCPU_TO_MARCH_SPEC + ++#ifndef SUBTARGET_EXTRA_SPECS ++#define SUBTARGET_EXTRA_SPECS ++#endif ++ + #define EXTRA_SPECS \ +- { "asm_cpu_spec", ASM_CPU_SPEC } ++ { "asm_cpu_spec", ASM_CPU_SPEC }, \ ++ SUBTARGET_EXTRA_SPECS + + #define ASM_OUTPUT_POOL_EPILOGUE aarch64_asm_output_pool_epilogue + +@@ -1324,6 +1357,10 @@ extern GTY(()) tree aarch64_fp16_ptr_type_node; + extern GTY(()) tree aarch64_bf16_type_node; + extern GTY(()) tree aarch64_bf16_ptr_type_node; + ++/* A pointer to the user-visible __float128 (on Mach-O). Defined in ++ aarch64-builtins.c. */ ++extern GTY(()) tree aarch64_float128_ptr_type_node; ++ + /* The generic unwind code in libgcc does not initialize the frame pointer. + So in order to unwind a function using a frame pointer, the very first + function that is unwound must save the frame pointer. That way the frame +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index 34b8059b45b..c356d3048b5 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -303,6 +303,7 @@ + UNSPEC_TAG_SPACE ; Translate address to MTE tag address space. + UNSPEC_LD1RO + UNSPEC_SALT_ADDR ++ UNSPEC_MACHOPIC_OFFSET + ]) + + (define_c_enum "unspecv" [ +@@ -849,6 +850,37 @@ + [(set_attr "type" "load_4")] + ) + ++(define_insn "prefetch_unscaled" ++ [(prefetch (match_operand:DI 0 "aarch64_unscaled_prefetch_operand" "Du") ++ (match_operand:QI 1 "const_int_operand" "") ++ (match_operand:QI 2 "const_int_operand" ""))] ++ "" ++ { ++ const char * pftype[2][4] = ++ { ++ {"prfum\\tPLDL1STRM, %0", ++ "prfum\\tPLDL3KEEP, %0", ++ "prfum\\tPLDL2KEEP, %0", ++ "prfum\\tPLDL1KEEP, %0"}, ++ {"prfum\\tPSTL1STRM, %0", ++ "prfum\\tPSTL3KEEP, %0", ++ "prfum\\tPSTL2KEEP, %0", ++ "prfum\\tPSTL1KEEP, %0"}, ++ }; ++ ++ int locality = INTVAL (operands[2]); ++ ++ gcc_assert (IN_RANGE (locality, 0, 3)); ++ ++ /* PRFUM accepts the same addresses as a 64-bit LDR so wrap ++ the address into a DImode MEM so that aarch64_print_operand knows ++ how to print it. */ ++ operands[0] = gen_rtx_MEM (DImode, operands[0]); ++ return pftype[INTVAL(operands[1])][locality]; ++ } ++ [(set_attr "type" "load_4")] ++) ++ + (define_insn "trap" + [(trap_if (const_int 1) (const_int 8))] + "" +@@ -1286,7 +1318,7 @@ + ldr\\t%s0, %1 + str\\t%w1, %0 + str\\t%s1, %0 +- adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1] ++ * return TARGET_MACHO ? \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %O1]\" : \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]\"; + adr\\t%x0, %c1 + adrp\\t%x0, %A1 + fmov\\t%s0, %w1 +@@ -1325,7 +1357,7 @@ + ldr\\t%d0, %1 + str\\t%x1, %0 + str\\t%d1, %0 +- * return TARGET_ILP32 ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\"; ++ * return TARGET_ILP32 ? (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\") : (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\"); + adr\\t%x0, %c1 + adrp\\t%x0, %A1 + fmov\\t%d0, %x1 +@@ -6857,7 +6889,10 @@ + (lo_sum:P (match_operand:P 1 "register_operand" "r") + (match_operand 2 "aarch64_valid_symref" "S")))] + "" +- "add\\t%0, %1, :lo12:%c2" ++ { return TARGET_MACHO ++ ? "add\\t%0, %1, %K2;momd" ++ : "add\\t%0, %1, :lo12:%c2"; ++ } + [(set_attr "type" "alu_imm")] + ) + +diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt +index 92220b26ee2..15ec719ca2d 100644 +--- a/gcc/config/aarch64/aarch64.opt ++++ b/gcc/config/aarch64/aarch64.opt +@@ -152,6 +152,13 @@ Enum(aarch64_abi) String(ilp32) Value(AARCH64_ABI_ILP32) + EnumValue + Enum(aarch64_abi) String(lp64) Value(AARCH64_ABI_LP64) + ++EnumValue ++Enum(aarch64_abi) String(darwinpcs) Value(AARCH64_ABI_LP64) ++ ++m64 ++Target RejectNegative Alias(mabi=, darwinpcs) ++On Darwin for compatibility with other platform variants. ++ + mpc-relative-literal-loads + Target Save Var(pcrelative_literal_loads) Init(2) Save + PC relative literal loads. +diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md +index ee7587cca16..cb73a2daae8 100644 +--- a/gcc/config/aarch64/constraints.md ++++ b/gcc/config/aarch64/constraints.md +@@ -158,7 +158,9 @@ + A constraint that matches a small GOT access." + (and (match_code "const,symbol_ref") + (match_test "aarch64_classify_symbolic_expression (op) +- == SYMBOL_SMALL_GOT_4G"))) ++ == SYMBOL_SMALL_GOT_4G ++ || aarch64_classify_symbolic_expression (op) ++ == SYMBOL_MO_SMALL_GOT"))) + + (define_constraint "Uss" + "@internal +@@ -490,6 +492,11 @@ + An address valid for a prefetch instruction." + (match_test "aarch64_address_valid_for_prefetch_p (op, true)")) + ++(define_address_constraint "Du" ++ "@internal ++ An address valid for a prefetch instruction with an unscaled offset." ++ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, true)")) ++ + (define_constraint "vgb" + "@internal + A constraint that matches an immediate offset valid for SVE LD1B +diff --git a/gcc/config/aarch64/darwin.h b/gcc/config/aarch64/darwin.h +new file mode 100644 +index 00000000000..2a855c11efa +--- /dev/null ++++ b/gcc/config/aarch64/darwin.h +@@ -0,0 +1,280 @@ ++/* Target definitions for Arm64/Aarch64 running on macOS/iOS. ++ ++Copyright The GNU Toolchain Authors. ++Contributed by Iain Sandoe. ++ ++This file is part of GCC. ++ ++GCC is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 3, or (at your option) ++any later version. ++ ++GCC is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GCC; see the file COPYING3. If not see ++. */ ++ ++/* Enable Mach-O bits in generic Aarch64 code. */ ++#undef TARGET_MACHO ++#define TARGET_MACHO 1 ++ ++#undef DARWIN_ARM64 ++#define DARWIN_ARM64 1 ++ ++/* FIXME FIXME FIXME - these are mostly guesses right now. */ ++ ++/* FIXME: this is only used in generic code in darwin.c. */ ++#undef TARGET_64BIT ++#define TARGET_64BIT 1 ++ ++#undef PTRDIFF_TYPE ++#define PTRDIFF_TYPE "long int" ++ ++/* NOTE that arm64_32 is a valid thing and corresponds to darwinpcs ++ and TARGET_ILP32, but we are not implementing that for now. */ ++#define TARGET_OS_CPP_BUILTINS() \ ++ do { \ ++ builtin_define ("__LITTLE_ENDIAN__"); \ ++ builtin_define ("__arm64"); \ ++ builtin_define ("__arm64__"); \ ++ darwin_cpp_builtins (pfile); \ ++ } while (0) ++ ++/* In Darwin's arm64 ABI, chars are signed, for consistency with other Darwin ++ architectures. */ ++ ++#undef DEFAULT_SIGNED_CHAR ++#define DEFAULT_SIGNED_CHAR 1 ++ ++#undef LONG_DOUBLE_TYPE_SIZE ++#define LONG_DOUBLE_TYPE_SIZE 64 ++ ++/* Disable custom function descriptors on Darwin, it breaks ABI. */ ++#undef AARCH64_CUSTOM_FUNCTION_TEST ++#define AARCH64_CUSTOM_FUNCTION_TEST 0 ++ ++/* Non-PIE executables are forbidden by the aarch64-darwin security model; ++ remove the option from link-lines since they just produce a warning from ++ ld64 and are then ignored anyway. */ ++#undef DARWIN_NOPIE_SPEC ++#define DARWIN_NOPIE_SPEC \ ++" %insn); +diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md +index c308015ac2c..cd88f93ca2d 100644 +--- a/gcc/config/aarch64/predicates.md ++++ b/gcc/config/aarch64/predicates.md +@@ -261,9 +261,24 @@ + (define_predicate "aarch64_prefetch_operand" + (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) + ++(define_predicate "aarch64_unscaled_prefetch_operand" ++ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, false)")) ++ + (define_predicate "aarch64_valid_symref" + (match_code "const, symbol_ref, label_ref") + { ++ if (TARGET_MACHO) ++ { ++ rtx x = op; ++ rtx offset; ++ split_const (x, &x, &offset); ++ if (GET_CODE (x) == CONST) ++ x = XEXP (x, 0); ++ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SALT_ADDR) ++ x = XVECEXP (x, 0, 0); ++ if (SYMBOL_REF_P (x) && INTVAL (offset) < 0) ++ return false; ++ } + return (aarch64_classify_symbolic_expression (op) + != SYMBOL_FORCE_TO_MEM); + }) +diff --git a/gcc/config/aarch64/t-aarch64-darwin b/gcc/config/aarch64/t-aarch64-darwin +new file mode 100644 +index 00000000000..a8bfcffad78 +--- /dev/null ++++ b/gcc/config/aarch64/t-aarch64-darwin +@@ -0,0 +1,25 @@ ++# Machine description for AArch64 architecture. ++# Copyright (C) 2020 Free Software Foundation, Inc. ++# ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++LIB1ASMSRC = aarch64/lib1funcs.asm ++LIB1ASMFUNCS = _aarch64_sync_cache_range ++ ++# FIXME - figure out what multilib provisions we should make for ++# a) arm64e ++# b) arm64_32 +diff --git a/gcc/config/darwin-driver.cc b/gcc/config/darwin-driver.cc +index 00287f3d5ec..6df85f57bb4 100644 +--- a/gcc/config/darwin-driver.cc ++++ b/gcc/config/darwin-driver.cc +@@ -268,14 +268,21 @@ darwin_driver_init (unsigned int *decoded_options_count, + bool seenX86_64 = false; + bool seenPPC = false; + bool seenPPC64 = false; ++#if !DARWIN_ARM64 ++ bool seenArm64 = false; + bool seenM32 = false; + bool seenM64 = false; + bool appendM32 = false; + bool appendM64 = false; ++#endif + const char *vers_string = NULL; + bool seen_version_min = false; + bool seen_sysroot_p = false; + bool noexport_p = true; ++#ifdef RPATH_SETS_NODEFAULT ++ bool seen_rpath_p = false; ++ bool seen_nodefaultrpaths_p = false; ++#endif + + for (i = 1; i < *decoded_options_count; i++) + { +@@ -296,6 +303,12 @@ darwin_driver_init (unsigned int *decoded_options_count, + seenPPC = true; + else if (!strcmp ((*decoded_options)[i].arg, "ppc64")) + seenPPC64 = true; ++ else if (!strcmp ((*decoded_options)[i].arg, "arm64")) ++#if !DARWIN_ARM64 ++ seenArm64 = true; ++#else ++ ; /* We accept the option, but don't need to act on it. */ ++#endif + else + error ("this compiler does not support %qs", + (*decoded_options)[i].arg); +@@ -309,7 +322,7 @@ darwin_driver_init (unsigned int *decoded_options_count, + --i; + --*decoded_options_count; + break; +- ++#if !DARWIN_ARM64 + case OPT_m32: + seenM32 = true; + break; +@@ -317,6 +330,7 @@ darwin_driver_init (unsigned int *decoded_options_count, + case OPT_m64: + seenM64 = true; + break; ++#endif + + case OPT_mmacosx_version_min_: + seen_version_min = true; +@@ -349,8 +363,16 @@ darwin_driver_init (unsigned int *decoded_options_count, + gcc_checking_assert ((*decoded_options)[i].arg); + if (startswith ((*decoded_options)[i].arg, "-exported_symbol")) + noexport_p = false; ++#ifdef RPATH_SETS_NODEFAULT ++ else if (strncmp ((*decoded_options)[i].arg, "-rpath", 6) == 0) ++ seen_rpath_p = true; ++#endif + break; + ++#ifdef RPATH_SETS_NODEFAULT ++ case OPT_nodefaultrpaths: ++ seen_nodefaultrpaths_p = true; ++#endif + default: + break; + } +@@ -366,6 +388,9 @@ darwin_driver_init (unsigned int *decoded_options_count, + if (seenPPC || seenPPC64) + warning (0, "this compiler does not support PowerPC" + " (%<-arch%> option ignored)"); ++ else if (seenArm64) ++ warning (0, "this compiler does not support Arm64" ++ " (%<-arch%> option ignored)"); + if (seenX86) + { + if (seenX86_64 || seenM64) +@@ -389,6 +414,9 @@ darwin_driver_init (unsigned int *decoded_options_count, + if (seenX86 || seenX86_64) + warning (0, "this compiler does not support x86" + " (%<-arch%> option ignored)"); ++ else if (seenArm64) ++ warning (0, "this compiler does not support Arm64" ++ " (%<-arch%> option ignored)"); + if (seenPPC) + { + if (seenPPC64 || seenM64) +@@ -408,12 +436,20 @@ darwin_driver_init (unsigned int *decoded_options_count, + if (! seenM64) /* Add -m64 if the User didn't. */ + appendM64 = true; + } ++#elif DARWIN_ARM64 ++ if (seenPPC || seenPPC64) ++ warning (0, "this compiler does not support PowerPC" ++ " (%<-arch%> option ignored)"); ++ if (seenX86 || seenX86_64) ++ warning (0, "this compiler does not support x86" ++ " (%<-arch%> option ignored)"); + #endif + + /* If there is nothing else on the command line, do not add sysroot etc. */ + if (*decoded_options_count <= 1) + return; + ++#if !DARWIN_ARM64 + if (appendM32 || appendM64) + { + ++*decoded_options_count; +@@ -423,6 +459,7 @@ darwin_driver_init (unsigned int *decoded_options_count, + generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER, + &(*decoded_options)[*decoded_options_count - 1]); + } ++#endif + + if (!seen_sysroot_p) + { +@@ -490,4 +527,16 @@ darwin_driver_init (unsigned int *decoded_options_count, + generate_option (OPT_nodefaultexport, NULL, 1, CL_DRIVER, + &(*decoded_options)[*decoded_options_count - 1]); + } ++ ++#ifdef RPATH_SETS_NODEFAULT ++ if (seen_rpath_p && !seen_nodefaultrpaths_p) ++ { ++ ++*decoded_options_count; ++ *decoded_options = XRESIZEVEC (struct cl_decoded_option, ++ *decoded_options, ++ *decoded_options_count); ++ generate_option (OPT_nodefaultrpaths, NULL, 1, CL_DRIVER, ++ &(*decoded_options)[*decoded_options_count - 1]); ++ } ++#endif + } +diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc +index f065a13d73d..7cd684c6abe 100644 +--- a/gcc/config/darwin.cc ++++ b/gcc/config/darwin.cc +@@ -118,7 +118,7 @@ static bool ld_init_term_start_labels = false; + section * darwin_sections[NUM_DARWIN_SECTIONS]; + + /* While we transition to using in-tests instead of ifdef'd code. */ +-#if !HAVE_lo_sum ++#if !HAVE_lo_sum || DARWIN_ARM64 + #define gen_macho_high(m,a,b) (a) + #define gen_macho_low(m,a,b,c) (a) + #endif +@@ -1052,6 +1052,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg) + return pic_ref; + } + ++#if !DARWIN_ARM64 + /* Callbacks to output the stub or non-lazy pointers. + Each works on the item in *SLOT,if it has been used. + DATA is the FILE* for assembly output. +@@ -1207,6 +1208,7 @@ machopic_finish (FILE *out_file) + machopic_indirections->traverse_noresize + (out_file); + } ++#endif + + int + machopic_operand_p (rtx op) +@@ -1936,6 +1938,8 @@ darwin_label_is_anonymous_local_objc_name (const char *name) + } + else if (startswith ((const char *)p, "ClassMethods")) + return false; ++ else if (startswith ((const char *)p, "ClassProtocols")) ++ return false; + else if (startswith ((const char *)p, "Instance")) + { + if (p[8] == 'I' || p[8] == 'M') +@@ -2238,6 +2242,8 @@ darwin_emit_except_table_label (FILE *file) + rtx + darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis)) + { ++ if (DARWIN_ARM64) ++ return orig; + if (DARWIN_PPC == 0 && TARGET_64BIT) + return orig; + +@@ -3058,7 +3064,12 @@ darwin_file_end (void) + fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags); + } + ++#if !DARWIN_ARM64 + machopic_finish (asm_out_file); ++#else ++ gcc_checking_assert (!machopic_indirections); ++#endif ++ + if (flag_apple_kext) + { + /* These sections are only used for kernel code. */ +diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h +index 51e257dc698..13ba6e61474 100644 +--- a/gcc/config/darwin.h ++++ b/gcc/config/darwin.h +@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + + #define DARWIN_X86 0 + #define DARWIN_PPC 0 ++#define DARWIN_ARM64 0 + + #define OBJECT_FORMAT_MACHO 1 + +@@ -296,6 +297,31 @@ extern GTY(()) int darwin_ms_struct; + #define DARWIN_CC1_SPEC \ + "% 10.11 mmacosx-version-min= -lgcc_s.1.1) \ ++ %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) " ++#endif ++ ++/* We might elect to add a path even when this compiler does not use embedded ++ run paths, so that we can use libraries from an alternate compiler that is ++ using embedded runpaths. */ ++#if DARWIN_DO_EXTRA_RPATH ++# define DARWIN_EXTRA_RPATH \ ++"%{!r:%{!nostdlib:%{!nodefaultrpaths:\ ++ %:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ ++ %:version-compare(>= 10.5 mmacosx-version-min= " DARWIN_ADD_RPATH ") \ ++ }}}" ++#else ++# define DARWIN_EXTRA_RPATH "" ++#endif ++ + #define SUBSUBTARGET_OVERRIDE_OPTIONS \ + do { \ + darwin_override_options (); \ +@@ -387,7 +413,9 @@ extern GTY(()) int darwin_ms_struct; + DARWIN_NOPIE_SPEC \ + DARWIN_RDYNAMIC \ + DARWIN_NOCOMPACT_UNWIND \ +- "}}}}}}} %= 10.6, the unwinder *still* comes from libSystem and +- we find the emutls impl from lemutls_w. In either case, the builtins etc. +- are linked from -lgcc. +- +- When we have specified shared-libgcc or any case that might require +- exceptions, we pull the libgcc content (including emulated tls) from +- -lgcc_s.1 in GCC and the unwinder from /usr/lib/libgcc_s.1 for < 10.6 and +- libSystem for >= 10.6 respectively. +- Otherwise, we just link the emutls/builtins from convenience libs. +- +- If we need exceptions, prior to 10.3.9, then we have to link the static +- eh lib, since there's no shared version on the system. +- +- In all cases, libgcc_s.1 will be installed with the compiler, or any app +- built using it, so we can link the builtins and emutls shared on all. +- + We have to work around that DYLD_XXXX are disabled in macOS 10.11+ which + means that any bootstrap trying to use a shared libgcc with a bumped SO- + name will fail. This means that we do not accept shared libgcc for these +- versions. ++ versions, unless we have embedded run paths enabled, in which case the ++ compiler will add the appropriate path to find the library. ++ ++ For -static-libgcc: < 10.6, use the unwinder in libgcc_eh (and find ++ the emultls impl. there too). + + For -static-libgcc: >= 10.6, the unwinder *still* comes from libSystem and + we find the emutls impl from lemutls_w. In either case, the builtins etc. + are linked from -lgcc. +-> ++ + Otherwise, we just link the shared version of gcc_s.1.1 and pick up + exceptions: + * Prior to 10.3.9, then we have to link the static eh lib, since there +@@ -502,6 +515,10 @@ extern GTY(()) int darwin_ms_struct; + + In all cases, libgcc_s.1.1 will be installed with the compiler, or any app + built using it, so we can link the builtins and emutls shared on all. ++ ++ On most Darwin systems (other than Arm64) we will also install a legacy ++ support libgcc_s.1.dylib to support executables linked with libgcc_ext by ++ earlier GCC versions. + */ + #undef REAL_LIBGCC_SPEC + #define REAL_LIBGCC_SPEC \ +@@ -509,8 +526,7 @@ extern GTY(()) int darwin_ms_struct; + %:version-compare(!> 10.6 mmacosx-version-min= -lgcc_eh) \ + %:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w); \ + shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ +- %:version-compare(!> 10.11 mmacosx-version-min= -lgcc_s.1.1) \ +- %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) \ ++ " DARWIN_SHARED_LIBGCC " \ + %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh) \ + %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \ + %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5); \ +@@ -545,7 +561,8 @@ extern GTY(()) int darwin_ms_struct; + { "darwin_crt2", DARWIN_CRT2_SPEC }, \ + { "darwin_crt3", DARWIN_CRT3_SPEC }, \ + { "darwin_dylib1", DARWIN_DYLIB1_SPEC }, \ +- { "darwin_bundle1", DARWIN_BUNDLE1_SPEC }, ++ { "darwin_bundle1", DARWIN_BUNDLE1_SPEC }, \ ++ { "darwin_rpaths", DARWIN_RPATH_SPEC }, + + #define DARWIN_CRT1_SPEC \ + "%:version-compare(!> 10.5 mmacosx-version-min= -lcrt1.o) \ +@@ -571,6 +588,17 @@ extern GTY(()) int darwin_ms_struct; + "%{!static:%:version-compare(< 10.6 mmacosx-version-min= -lbundle1.o) \ + %{fgnu-tm: -lcrttms.o}}" + ++#if DARWIN_AT_RPATH ++/* A default rpath, that picks up dependent libraries installed in the same ++ director as one being loaded. */ ++#define DARWIN_RPATH_SPEC \ ++ "%:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ ++ %:version-compare(>= 10.5 mmacosx-version-min= @loader_path) \ ++ %P " ++#else ++#define DARWIN_RPATH_SPEC "" ++#endif ++ + #ifdef HAVE_AS_MMACOSX_VERSION_MIN_OPTION + /* Emit macosx version (but only major). */ + #define ASM_MMACOSX_VERSION_MIN_SPEC \ +diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt +index cc7d14c2e4d..b1cb8464d57 100644 +--- a/gcc/config/darwin.opt ++++ b/gcc/config/darwin.opt +@@ -237,6 +237,10 @@ nodefaultexport + Driver RejectNegative + Do not add a default symbol exports to modules or dynamic libraries. + ++nodefaultrpaths ++Driver RejectNegative ++Do not add default run paths (for the compiler library directories) to executables, modules or dynamic libraries. ++ + nofixprebinding + Driver RejectNegative + (Obsolete after 10.3.9) Set MH_NOPREFIXBINDING, in an executable. +diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h +index a55f6b2b874..36a32867281 100644 +--- a/gcc/config/i386/darwin.h ++++ b/gcc/config/i386/darwin.h +@@ -308,3 +308,10 @@ along with GCC; see the file COPYING3. If not see + #define CLEAR_INSN_CACHE(beg, end) \ + extern void sys_icache_invalidate(void *start, size_t len); \ + sys_icache_invalidate ((beg), (size_t)((end)-(beg))) ++ ++/* Disable custom function descriptors for Darwin when we have off-stack ++ trampolines. */ ++#undef X86_CUSTOM_FUNCTION_TEST ++#define X86_CUSTOM_FUNCTION_TEST \ ++ (!flag_off_stack_trampolines && !flag_trampolines) ? 1 : 0 ++ +diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc +index 9dd9fa68722..5cd4b5c0592 100644 +--- a/gcc/config/i386/i386.cc ++++ b/gcc/config/i386/i386.cc +@@ -24698,7 +24698,7 @@ ix86_libgcc_floating_mode_supported_p + #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok + + #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS +-#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 ++#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST + + #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID + #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 363082ba47b..5f56d7abf65 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -746,6 +746,12 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); + /* Minimum allocation boundary for the code of a function. */ + #define FUNCTION_BOUNDARY 8 + ++/* We will and with this value to test if a custom function descriptor needs ++ a static chain. The function boundary must the adjusted so that the bit ++ this represents is no longer part of the address. 0 Disables the custom ++ function descriptors. */ ++#define X86_CUSTOM_FUNCTION_TEST 1 ++ + /* C++ stores the virtual bit in the lowest bit of function pointers. */ + #define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_pfn + +diff --git a/gcc/configure b/gcc/configure +index 5ce0557719a..dbc127c59cb 100755 +--- a/gcc/configure ++++ b/gcc/configure +@@ -634,6 +634,7 @@ LIBOBJS + CET_HOST_FLAGS + NO_PIE_FLAG + NO_PIE_CFLAGS ++enable_pie_tools + enable_default_pie + PICFLAG + enable_host_shared +@@ -740,6 +741,8 @@ ORIGINAL_PLUGIN_LD_FOR_TARGET + gcc_cv_ld + ORIGINAL_AS_FOR_TARGET + gcc_cv_as ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_fast_install + objdir + OTOOL64 +@@ -1000,6 +1003,8 @@ enable_static + with_pic + enable_fast_install + enable_libtool_lock ++enable_darwin_at_rpath ++with_darwin_extra_rpath + enable_ld + enable_gold + with_plugin_ld +@@ -1030,6 +1035,7 @@ with_linker_hash_style + with_diagnostics_color + with_diagnostics_urls + enable_default_pie ++enable_pie_tools + enable_cet + enable_s390_excess_float_precision + ' +@@ -1733,6 +1739,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-ld[=ARG] build ld [ARG={default,yes,no}] + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-gnu-indirect-function +@@ -1790,6 +1798,8 @@ Optional Features: + --disable-libquadmath-support + disable libquadmath support for Fortran + --enable-default-pie enable Position Independent Executable as default ++ --enable-pie-tools build Position Independent Executables for the ++ compilers and other tools + --enable-cet enable Intel CET in host libraries [default=auto] + --enable-s390-excess-float-precision + on s390 targets, evaluate float with double +@@ -1850,6 +1860,9 @@ Optional Packages: + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] ++ --with-darwin-extra-rpath=[ARG] ++ Specify a runpath directory, additional to those ++ provided by the compiler + --with-plugin-ld=[ARG] specify the plugin linker + --with-glibc-version=M.N + assume GCC used with glibc version M.N or later +@@ -3766,15 +3779,24 @@ if test x${gcc_gxx_libcxx_include_dir} != x; then + $as_echo "#define ENABLE_STDLIB_OPTION 1" >>confdefs.h + + else +- $as_echo "#define ENABLE_STDLIB_OPTION 0" >>confdefs.h ++ case $target in ++ *-darwin1[1-9]* | *-darwin2*) ++ # Default this on for Darwin versions which default to libcxx. ++ $as_echo "#define ENABLE_STDLIB_OPTION 1" >>confdefs.h + ++ ;; ++ *) ++ $as_echo "#define ENABLE_STDLIB_OPTION 0" >>confdefs.h ++ ++ ;; ++ esac + fi +-# ??? This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO. ++ + if test x${gcc_gxx_libcxx_include_dir} = x; then ++ libcxx_incdir='include/c++/v1' + if test x${enable_version_specific_runtime_libs} = xyes; then +- gcc_gxx_libcxx_include_dir='${libsubdir}/libc++_include/c++/v1' ++ gcc_gxx_libcxx_include_dir='${libsubdir}/$libcxx_incdir' + else +- libcxx_incdir='libc++_include/c++/$(version)/v1' + if test x$host != x$target; then + libcxx_incdir="$target_alias/$libcxx_incdir" + fi +@@ -17867,6 +17889,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -17884,10 +17947,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -19673,7 +19745,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 19676 "configure" ++#line 19748 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -19779,7 +19851,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 19782 "configure" ++#line 19854 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -20655,6 +20727,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -20672,12 +20785,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -23028,6 +23154,35 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++DARWIN_DO_EXTRA_RPATH=0 ++ ++# Check whether --with-darwin-extra-rpath was given. ++if test "${with_darwin_extra_rpath+set}" = set; then : ++ withval=$with_darwin_extra_rpath; if test x"$withval" != x; then ++ DARWIN_ADD_RPATH="$withval" ++ DARWIN_DO_EXTRA_RPATH=1 ++ fi ++fi ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DARWIN_DO_EXTRA_RPATH $DARWIN_DO_EXTRA_RPATH ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define DARWIN_ADD_RPATH "$DARWIN_ADD_RPATH" ++_ACEOF ++ ++ + # Identify the assembler which will work hand-in-glove with the newly + # built GCC, so that we can examine its features. This is the assembler + # which will be driven by the driver program. +@@ -32429,6 +32584,22 @@ $as_echo "#define ENABLE_DEFAULT_PIE 1" >>confdefs.h + fi + + ++# Check whether --enable-pie-tools was given; this is passed automatically ++# from the top level where it has already been validated. ++# Check whether --enable-pie-tools was given. ++if test "${enable_pie_tools+set}" = set; then : ++ enableval=$enable_pie_tools; enable_pie_tools=$enableval ++else ++ enable_pie_tools=no ++fi ++ ++if test x$enable_pie_tools = xyes ; then ++ ++$as_echo "#define ENABLE_PIE_TOOLS 1" >>confdefs.h ++ ++fi ++ ++ + # Check if -fno-PIE works. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-PIE option" >&5 + $as_echo_n "checking for -fno-PIE option... " >&6; } +@@ -32966,6 +33137,10 @@ LTLIBOBJS=$ac_ltlibobjs + + + ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/gcc/configure.ac b/gcc/configure.ac +index 23bee7010a3..2d9159989e4 100644 +--- a/gcc/configure.ac ++++ b/gcc/configure.ac +@@ -249,14 +249,22 @@ if test x${gcc_gxx_libcxx_include_dir} != x; then + AC_DEFINE(ENABLE_STDLIB_OPTION, 1, + [Define if the -stdlib= option should be enabled.]) + else +- AC_DEFINE(ENABLE_STDLIB_OPTION, 0) ++ case $target in ++ *-darwin1[[1-9]]* | *-darwin2*) ++ # Default this on for Darwin versions which default to libcxx. ++ AC_DEFINE(ENABLE_STDLIB_OPTION, 1) ++ ;; ++ *) ++ AC_DEFINE(ENABLE_STDLIB_OPTION, 0) ++ ;; ++ esac + fi +-# ??? This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO. ++ + if test x${gcc_gxx_libcxx_include_dir} = x; then ++ libcxx_incdir='include/c++/v1' + if test x${enable_version_specific_runtime_libs} = xyes; then +- gcc_gxx_libcxx_include_dir='${libsubdir}/libc++_include/c++/v1' ++ gcc_gxx_libcxx_include_dir='${libsubdir}/$libcxx_incdir' + else +- libcxx_incdir='libc++_include/c++/$(version)/v1' + if test x$host != x$target; then + libcxx_incdir="$target_alias/$libcxx_incdir" + fi +@@ -2559,6 +2567,21 @@ AC_PROG_LIBTOOL + AC_SUBST(objdir) + AC_SUBST(enable_fast_install) + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++DARWIN_DO_EXTRA_RPATH=0 ++AC_ARG_WITH(darwin-extra-rpath, ++[AS_HELP_STRING( ++ [[--with-darwin-extra-rpath=[ARG]]], ++ [Specify a runpath directory, additional to those provided by the compiler])], ++[if test x"$withval" != x; then ++ DARWIN_ADD_RPATH="$withval" ++ DARWIN_DO_EXTRA_RPATH=1 ++ fi]) ++AC_DEFINE_UNQUOTED(DARWIN_DO_EXTRA_RPATH, $DARWIN_DO_EXTRA_RPATH, ++ [Should add an extra runpath directory]) ++AC_DEFINE_UNQUOTED(DARWIN_ADD_RPATH, "$DARWIN_ADD_RPATH", ++ [Specify a runpath directory, additional to those provided by the compiler]) ++ + # Identify the assembler which will work hand-in-glove with the newly + # built GCC, so that we can examine its features. This is the assembler + # which will be driven by the driver program. +@@ -7646,6 +7669,19 @@ if test x$enable_default_pie = xyes ; then + fi + AC_SUBST([enable_default_pie]) + ++# Check whether --enable-pie-tools was given; this is passed automatically ++# from the top level where it has already been validated. ++AC_ARG_ENABLE(pie-tools, ++[AS_HELP_STRING([--enable-pie-tools], ++ [build Position Independent Executables for the compilers and other tools])], ++[enable_pie_tools=$enableval], ++[enable_pie_tools=no]) ++if test x$enable_pie_tools = xyes ; then ++ AC_DEFINE(ENABLE_PIE_TOOLS, 1, ++ [Define if you build Position Independent Executables for the compilers and other tools.]) ++fi ++AC_SUBST([enable_pie_tools]) ++ + # Check if -fno-PIE works. + AC_CACHE_CHECK([for -fno-PIE option], + [gcc_cv_c_no_fpie], +diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc +index d7e9980ff1e..ff2a1f6665f 100644 +--- a/gcc/cp/decl2.cc ++++ b/gcc/cp/decl2.cc +@@ -3653,9 +3653,8 @@ get_tls_init_fn (tree var) + if (!flag_extern_tls_init && DECL_EXTERNAL (var)) + return NULL_TREE; + +- /* If the variable is internal, or if we can't generate aliases, +- call the local init function directly. */ +- if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES) ++ /* If the variable is internal call the local init function directly. */ ++ if (!TREE_PUBLIC (var)) + return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var)); + + tree sname = mangle_tls_init_fn (var); +@@ -4801,22 +4800,24 @@ handle_tls_init (void) + finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR, + boolean_true_node, + tf_warning_or_error)); ++ auto_vec direct_calls; + for (; vars; vars = TREE_CHAIN (vars)) + { + tree var = TREE_VALUE (vars); + tree init = TREE_PURPOSE (vars); + one_static_initialization_or_destruction (var, init, true); + +- /* Output init aliases even with -fno-extern-tls-init. */ +- if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var)) ++ /* Output inits even with -fno-extern-tls-init. ++ We save the list here and output either an alias or a stub function ++ below. */ ++ if (TREE_PUBLIC (var)) + { +- tree single_init_fn = get_tls_init_fn (var); ++ tree single_init_fn = get_tls_init_fn (var); + if (single_init_fn == NULL_TREE) + continue; +- cgraph_node *alias +- = cgraph_node::get_create (fn)->create_same_body_alias +- (single_init_fn, fn); +- gcc_assert (alias != NULL); ++ if (single_init_fn == fn) ++ continue; ++ direct_calls.safe_push (single_init_fn); + } + } + +@@ -4824,6 +4825,30 @@ handle_tls_init (void) + finish_if_stmt (if_stmt); + finish_function_body (body); + expand_or_defer_fn (finish_function (/*inline_p=*/false)); ++ ++ /* For each TLS var that we have an init function, we either emit an alias ++ between that and the tls_init, or a stub function that just calls the ++ tls_init. */ ++ while (!direct_calls.is_empty()) ++ { ++ tree single_init_fn = direct_calls.pop (); ++ if (TARGET_SUPPORTS_ALIASES) ++ { ++ cgraph_node *alias ++ = cgraph_node::get_create (fn)->create_same_body_alias ++ (single_init_fn, fn); ++ gcc_assert (alias != NULL); ++ } ++ else ++ { ++ start_preparsed_function (single_init_fn, NULL_TREE, SF_PRE_PARSED); ++ tree body = begin_function_body (); ++ tree r = build_call_expr (fn, 0); ++ finish_expr_stmt (r); ++ finish_function_body (body); ++ expand_or_defer_fn (finish_function (/*inline_p=*/false)); ++ } ++ } + } + + /* We're at the end of compilation, so generate any mangling aliases that +diff --git a/gcc/cp/g++spec.cc b/gcc/cp/g++spec.cc +index 8174d652776..2e1e06e6ac9 100644 +--- a/gcc/cp/g++spec.cc ++++ b/gcc/cp/g++spec.cc +@@ -222,7 +222,12 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, + + case OPT_static_libstdc__: + library = library >= 0 ? 2 : library; ++#ifdef HAVE_LD_STATIC_DYNAMIC ++ /* Remove -static-libstdc++ from the command only if target supports ++ LD_STATIC_DYNAMIC. When not supported, it is left in so that a ++ back-end target can use outfile substitution. */ + args[i] |= SKIPOPT; ++#endif + break; + + case OPT_stdlib_: +diff --git a/gcc/cumulative-args.h b/gcc/cumulative-args.h +new file mode 100644 +index 00000000000..b60928e37f9 +--- /dev/null ++++ b/gcc/cumulative-args.h +@@ -0,0 +1,20 @@ ++#ifndef GCC_CUMULATIVE_ARGS_H ++#define GCC_CUMULATIVE_ARGS_H ++ ++#if CHECKING_P ++ ++struct cumulative_args_t { void *magic; void *p; }; ++ ++#else /* !CHECKING_P */ ++ ++/* When using a GCC build compiler, we could use ++ __attribute__((transparent_union)) to get cumulative_args_t function ++ arguments passed like scalars where the ABI would mandate a less ++ efficient way of argument passing otherwise. However, that would come ++ at the cost of less type-safe !CHECKING_P compilation. */ ++ ++union cumulative_args_t { void *p; }; ++ ++#endif /* !CHECKING_P */ ++ ++#endif /* GCC_CUMULATIVE_ARGS_H */ +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index ff6c338bedb..55c8ba8969f 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -670,6 +670,7 @@ Objective-C and Objective-C++ Dialects}. + @gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol + -ffixed-@var{reg} -fexceptions @gol + -fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables @gol ++-foff-stack-trampolines @gol + -fasynchronous-unwind-tables @gol + -fno-gnu-unique @gol + -finhibit-size-directive -fcommon -fno-ident @gol +@@ -680,6 +681,7 @@ Objective-C and Objective-C++ Dialects}. + -fverbose-asm -fpack-struct[=@var{n}] @gol + -fleading-underscore -ftls-model=@var{model} @gol + -fstack-reuse=@var{reuse_level} @gol ++-fstack-use-cumulative-args @gol + -ftrampolines -ftrapv -fwrapv @gol + -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} @gol + -fstrict-volatile-bitfields -fsync-libcalls} +@@ -17071,6 +17073,17 @@ the behavior of older compilers in which temporaries' stack space is + not reused, the aggressive stack reuse can lead to runtime errors. This + option is used to control the temporary stack reuse optimization. + ++@item -fstack-use-cumulative-args ++@opindex fstack_use_cumulative_args ++This option instructs the compiler to use the ++@code{cumulative_args_t}-based stack layout target hooks, ++@code{TARGET_FUNCTION_ARG_BOUNDARY_CA} and ++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA}. If a given target does ++not define these hooks, the default behaviour is to fallback to using ++the standard non-@code{_CA} variants instead. Certain targets (such as ++AArch64 Darwin) require using the more advanced @code{_CA}-based ++hooks: For these targets this option should be enabled by default. ++ + @item -ftrapv + @opindex ftrapv + This option generates traps for signed overflow on addition, subtraction, +@@ -17129,6 +17142,19 @@ instructions. It does not allow exceptions to be thrown from + arbitrary signal handlers such as @code{SIGALRM}. This enables + @option{-fexceptions}. + ++@item -foff-stack-trampolines ++@opindex foff-stack-trampolines ++Certain platforms (such as the Apple M1) do not permit an executable ++stack. Generate calls to @code{__builtin_nested_func_ptr_created} and ++@code{__builtin_nested_func_ptr_deleted} in order to allocate and ++deallocate trampoline space on the executable heap. Please note that ++these functions are implemented in libgcc, and will not be compiled in ++unless you provide @option{--enable-off-stack-trampolines} when ++building gcc. @emph{PLEASE NOTE}: The trampolines are @emph{not} ++guaranteed to be correctly deallocated if you @code{setjmp}, ++instantiate nested functions, and then @code{longjmp} back to a state ++prior to having allocated those nested functions. ++ + @item -fdelete-dead-exceptions + @opindex fdelete-dead-exceptions + Consider that instructions that may throw exceptions but don't otherwise +diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi +index c5006afc00d..366360612e3 100644 +--- a/gcc/doc/tm.texi ++++ b/gcc/doc/tm.texi +@@ -4322,6 +4322,16 @@ with the specified mode and type. The default hook returns + @code{PARM_BOUNDARY} for all arguments. + @end deftypefn + ++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca}) ++This is the @code{cumulative_args_t}-based version of ++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more ++fine-grained control over argument alignment, e.g. depending on whether ++it is a named argument or not, or any other criteria that you choose to ++place in the @var{ca} structure. ++ ++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}. ++@end deftypefn ++ + @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type}) + Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}, + which is the default value for this hook. You can define this hook to +@@ -4329,6 +4339,16 @@ return a different value if an argument size must be rounded to a larger + value. + @end deftypefn + ++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca}) ++This is the @code{cumulative_args_t}-based version of ++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more ++fine-grained control over argument size rounding, e.g. depending on whether ++it is a named argument or not, or any other criteria that you choose to ++place in the @var{ca} structure. ++ ++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. ++@end deftypefn ++ + @defmac FUNCTION_ARG_REGNO_P (@var{regno}) + A C expression that is nonzero if @var{regno} is the number of a hard + register in which function arguments are sometimes passed. This does +diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in +index f869ddd5e5b..2c9f0f0bf14 100644 +--- a/gcc/doc/tm.texi.in ++++ b/gcc/doc/tm.texi.in +@@ -3330,8 +3330,12 @@ required. + + @hook TARGET_FUNCTION_ARG_BOUNDARY + ++@hook TARGET_FUNCTION_ARG_BOUNDARY_CA ++ + @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY + ++@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA ++ + @defmac FUNCTION_ARG_REGNO_P (@var{regno}) + A C expression that is nonzero if @var{regno} is the number of a hard + register in which function arguments are sometimes passed. This does +diff --git a/gcc/function.cc b/gcc/function.cc +index ad0096a43ef..e5044a60741 100644 +--- a/gcc/function.cc ++++ b/gcc/function.cc +@@ -2445,7 +2445,10 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, + else if (DECL_CHAIN (parm)) + data->arg.named = 1; /* Not the last non-variadic parm. */ + else if (targetm.calls.strict_argument_naming (all->args_so_far)) +- data->arg.named = 1; /* Only variadic ones are unnamed. */ ++ { ++ data->arg.named = 1; /* Only variadic ones are unnamed. */ ++ data->arg.last_named = 1; ++ } + else + data->arg.named = 0; /* Treat as variadic. */ + +@@ -2502,6 +2505,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all, + + function_arg_info last_named_arg = data->arg; + last_named_arg.named = true; ++ last_named_arg.last_named = true; + targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg, + &varargs_pretend_bytes, no_rtl); + +@@ -2610,7 +2614,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, + + locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs, + all->reg_parm_stack_space, +- entry_parm ? data->partial : 0, current_function_decl, ++ entry_parm ? data->partial : 0, ++ all->args_so_far, ++ current_function_decl, + &all->stack_args_size, &data->locate); + + /* Update parm_stack_boundary if this parameter is passed in the +@@ -3924,7 +3930,8 @@ gimplify_parameters (gimple_seq *cleanup) + if (data.arg.pass_by_reference) + { + tree type = TREE_TYPE (data.arg.type); +- function_arg_info orig_arg (type, data.arg.named); ++ function_arg_info orig_arg (type, data.arg.named, ++ data.arg.last_named); + if (reference_callee_copied (&all.args_so_far_v, orig_arg)) + { + tree local, t; +@@ -4027,6 +4034,7 @@ gimplify_parameters (gimple_seq *cleanup) + void + locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, + int reg_parm_stack_space, int partial, ++ cumulative_args_t ca, + tree fndecl ATTRIBUTE_UNUSED, + struct args_size *initial_offset_ptr, + struct locate_and_pad_arg_data *locate) +@@ -4064,9 +4072,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, + ? arg_size_in_bytes (type) + : size_int (GET_MODE_SIZE (passed_mode))); + where_pad = targetm.calls.function_arg_padding (passed_mode, type); +- boundary = targetm.calls.function_arg_boundary (passed_mode, type); +- round_boundary = targetm.calls.function_arg_round_boundary (passed_mode, +- type); ++ ++ if (flag_stack_use_cumulative_args) ++ { ++ boundary = targetm.calls.function_arg_boundary_ca (passed_mode, ++ type, ++ ca); ++ round_boundary = targetm.calls.function_arg_round_boundary_ca ++ (passed_mode, type, ca); ++ } ++ else ++ { ++ boundary = targetm.calls.function_arg_boundary (passed_mode, ++ type); ++ round_boundary = targetm.calls.function_arg_round_boundary ++ (passed_mode, type); ++ } ++ + locate->where_pad = where_pad; + + /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */ +diff --git a/gcc/function.h b/gcc/function.h +index 098613766be..009a9dc1c44 100644 +--- a/gcc/function.h ++++ b/gcc/function.h +@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see + #ifndef GCC_FUNCTION_H + #define GCC_FUNCTION_H + ++#include "cumulative-args.h" + + /* Stack of pending (incomplete) sequences saved by `start_sequence'. + Each element describes one pending sequence. +@@ -661,6 +662,7 @@ extern int aggregate_value_p (const_tree, const_tree); + extern bool use_register_for_decl (const_tree); + extern gimple_seq gimplify_parameters (gimple_seq *); + extern void locate_and_pad_parm (machine_mode, tree, int, int, int, ++ cumulative_args_t, + tree, struct args_size *, + struct locate_and_pad_arg_data *); + extern void generate_setjmp_warnings (void); +diff --git a/gcc/gcc.cc b/gcc/gcc.cc +index bb07cc244e3..a16c1e4372b 100644 +--- a/gcc/gcc.cc ++++ b/gcc/gcc.cc +@@ -572,6 +572,7 @@ or with constant text in a single argument. + %l process LINK_SPEC as a spec. + %L process LIB_SPEC as a spec. + %M Output multilib_os_dir. ++ %P Output a RUNPATH_OPTION for each directory in startfile_prefixes. + %G process LIBGCC_SPEC as a spec. + %R Output the concatenation of target_system_root and + target_sysroot_suffix. +@@ -1191,6 +1192,10 @@ proper position among the other output files. */ + # define SYSROOT_HEADERS_SUFFIX_SPEC "" + #endif + ++#ifndef RUNPATH_OPTION ++# define RUNPATH_OPTION "-rpath" ++#endif ++ + static const char *asm_debug = ASM_DEBUG_SPEC; + static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC; + static const char *cpp_spec = CPP_SPEC; +@@ -5895,6 +5900,7 @@ struct spec_path_info { + size_t append_len; + bool omit_relative; + bool separate_options; ++ bool realpaths; + }; + + static void * +@@ -5904,6 +5910,16 @@ spec_path (char *path, void *data) + size_t len = 0; + char save = 0; + ++ /* The path must exist; we want to resolve it to the realpath so that this ++ can be embedded as a runpath. */ ++ if (info->realpaths) ++ path = lrealpath (path); ++ ++ /* However, if we failed to resolve it - perhaps because there was a bogus ++ -B option on the command line, then punt on this entry. */ ++ if (!path) ++ return NULL; ++ + if (info->omit_relative && !IS_ABSOLUTE_PATH (path)) + return NULL; + +@@ -6135,6 +6151,22 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) + info.omit_relative = false; + #endif + info.separate_options = false; ++ info.realpaths = false; ++ ++ for_each_path (&startfile_prefixes, true, 0, spec_path, &info); ++ } ++ break; ++ ++ case 'P': ++ { ++ struct spec_path_info info; ++ ++ info.option = RUNPATH_OPTION; ++ info.append_len = 0; ++ info.omit_relative = false; ++ info.separate_options = true; ++ /* We want to embed the actual paths that have the libraries. */ ++ info.realpaths = true; + + for_each_path (&startfile_prefixes, true, 0, spec_path, &info); + } +@@ -6461,6 +6493,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) + info.append_len = strlen (info.append); + info.omit_relative = false; + info.separate_options = true; ++ info.realpaths = false; + + for_each_path (&include_prefixes, false, info.append_len, + spec_path, &info); +diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h +index 79e296d4a66..a9caa0467ba 100644 +--- a/gcc/ginclude/stddef.h ++++ b/gcc/ginclude/stddef.h +@@ -427,9 +427,8 @@ typedef struct { + /* _Float128 is defined as a basic type, so max_align_t must be + sufficiently aligned for it. This code must work in C++, so we + use __float128 here; that is only available on some +- architectures, but only on i386 is extra alignment needed for +- __float128. */ +-#ifdef __i386__ ++ architectures. */ ++#if defined(__i386__) || (__APPLE__ && __aarch64__) + __float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128)))); + #endif + } max_align_t; +diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in +index 6e10abfd0ac..5a39342068d 100644 +--- a/gcc/jit/Make-lang.in ++++ b/gcc/jit/Make-lang.in +@@ -43,6 +43,7 @@ + LIBGCCJIT_VERSION_NUM = 0 + LIBGCCJIT_MINOR_NUM = 0 + LIBGCCJIT_RELEASE_NUM = 1 ++COMMA := , + + ifneq (,$(findstring mingw,$(target))) + LIBGCCJIT_FILENAME = libgccjit-$(LIBGCCJIT_VERSION_NUM).dll +@@ -59,22 +60,18 @@ LIBGCCJIT_AGE = 1 + LIBGCCJIT_BASENAME = libgccjit + + LIBGCCJIT_SONAME = \ +- ${libdir}/$(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib ++ $(DARWIN_RPATH)/$(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib + LIBGCCJIT_FILENAME = $(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib + LIBGCCJIT_LINKER_NAME = $(LIBGCCJIT_BASENAME).dylib + +-# Conditionalize the use of the LD_VERSION_SCRIPT_OPTION and +-# LD_SONAME_OPTION depending if configure found them, using $(if) +-# We have to define a COMMA here, otherwise the commas in the "true" +-# result are treated as separators by the $(if). +-COMMA := , +-LIBGCCJIT_VERSION_SCRIPT_OPTION = \ +- $(if $(LD_VERSION_SCRIPT_OPTION),\ +- -Wl$(COMMA)$(LD_VERSION_SCRIPT_OPTION)$(COMMA)$(srcdir)/jit/libgccjit.map) ++# TODO: translate the libgccjit.map into a form usable by Darwin's linker and ++# then check for linker support for -exported_symbols_list=. Omitting this ++# means that all symbols in the libgccjit library will be visible. ++LIBGCCJIT_VERSION_SCRIPT_OPTION = + +-LIBGCCJIT_SONAME_OPTION = \ +- $(if $(LD_SONAME_OPTION), \ +- -Wl$(COMMA)$(LD_SONAME_OPTION)$(COMMA)$(LIBGCCJIT_SONAME)) ++# This is a work-around fix for cross-compilation where the target linker ++# is ld and the host is ld64. ++LIBGCCJIT_SONAME_OPTION = -Wl,-install_name,$(LIBGCCJIT_SONAME) + + LIBGCCJIT_SONAME_SYMLINK = $(LIBGCCJIT_FILENAME) + LIBGCCJIT_LINKER_NAME_SYMLINK = $(LIBGCCJIT_LINKER_NAME) +@@ -98,7 +95,6 @@ LIBGCCJIT_SONAME_SYMLINK = $(LIBGCCJIT_SONAME) + # LD_SONAME_OPTION depending if configure found them, using $(if) + # We have to define a COMMA here, otherwise the commas in the "true" + # result are treated as separators by the $(if). +-COMMA := , + LIBGCCJIT_VERSION_SCRIPT_OPTION = \ + $(if $(LD_VERSION_SCRIPT_OPTION),\ + -Wl$(COMMA)$(LD_VERSION_SCRIPT_OPTION)$(COMMA)$(srcdir)/jit/libgccjit.map) +diff --git a/gcc/objc/objc-next-runtime-abi-02.cc b/gcc/objc/objc-next-runtime-abi-02.cc +index e50ca6e89f5..9ea63b189c7 100644 +--- a/gcc/objc/objc-next-runtime-abi-02.cc ++++ b/gcc/objc/objc-next-runtime-abi-02.cc +@@ -1033,6 +1033,7 @@ next_runtime_abi_02_protocol_decl (tree p) + else + decl = start_var_decl (objc_v2_protocol_template, buf); + OBJCMETA (decl, objc_meta, meta_protocol); ++ DECL_PRESERVE_P (decl) = 1; + return decl; + } + +@@ -2115,8 +2116,8 @@ build_v2_classrefs_table (void) + expr = convert (objc_class_type, build_fold_addr_expr (expr)); + } + /* The runtime wants this, even if it appears unused, so we must force the +- output. +- DECL_PRESERVE_P (decl) = 1; */ ++ output. */ ++ DECL_PRESERVE_P (decl) = 1; + finish_var_decl (decl, expr); + } + } +@@ -2318,6 +2319,7 @@ build_v2_protocol_list_address_table (void) + expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl)); + OBJCMETA (decl, objc_meta, meta_label_protocollist); + finish_var_decl (decl, expr); ++ DECL_PRESERVE_P (decl) = 1; + } + + /* TODO: delete the vec. */ +diff --git a/gcc/target.def b/gcc/target.def +index d85adf36a39..5eb1fdce24e 100644 +--- a/gcc/target.def ++++ b/gcc/target.def +@@ -4967,6 +4967,18 @@ with the specified mode and type. The default hook returns\n\ + unsigned int, (machine_mode mode, const_tree type), + default_function_arg_boundary) + ++DEFHOOK ++(function_arg_boundary_ca, ++ "This is the @code{cumulative_args_t}-based version of\n\ ++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more\n\ ++fine-grained control over argument alignment, e.g. depending on whether\n\ ++it is a named argument or not, or any other criteria that you choose to\n\ ++place in the @var{ca} structure.\n\ ++\n\ ++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.", ++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca), ++ default_function_arg_boundary_ca) ++ + DEFHOOK + (function_arg_round_boundary, + "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\ +@@ -4976,6 +4988,18 @@ value.", + unsigned int, (machine_mode mode, const_tree type), + default_function_arg_round_boundary) + ++DEFHOOK ++(function_arg_round_boundary_ca, ++ "This is the @code{cumulative_args_t}-based version of\n\ ++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more\n\ ++fine-grained control over argument size rounding, e.g. depending on whether\n\ ++it is a named argument or not, or any other criteria that you choose to\n\ ++place in the @var{ca} structure.\n\ ++\n\ ++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.", ++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca), ++ default_function_arg_round_boundary_ca) ++ + /* Return the diagnostic message string if function without a prototype + is not allowed for this 'val' argument; NULL otherwise. */ + DEFHOOK +diff --git a/gcc/target.h b/gcc/target.h +index d6fa6931499..40c3da87656 100644 +--- a/gcc/target.h ++++ b/gcc/target.h +@@ -51,22 +51,7 @@ + #include "insn-codes.h" + #include "tm.h" + #include "hard-reg-set.h" +- +-#if CHECKING_P +- +-struct cumulative_args_t { void *magic; void *p; }; +- +-#else /* !CHECKING_P */ +- +-/* When using a GCC build compiler, we could use +- __attribute__((transparent_union)) to get cumulative_args_t function +- arguments passed like scalars where the ABI would mandate a less +- efficient way of argument passing otherwise. However, that would come +- at the cost of less type-safe !CHECKING_P compilation. */ +- +-union cumulative_args_t { void *p; }; +- +-#endif /* !CHECKING_P */ ++#include "cumulative-args.h" + + /* Types of memory operation understood by the "by_pieces" infrastructure. + Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and +diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc +index 399d6f874dc..9d554adcb45 100644 +--- a/gcc/targhooks.cc ++++ b/gcc/targhooks.cc +@@ -850,6 +850,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, + return PARM_BOUNDARY; + } + ++unsigned int ++default_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, ++ const_tree type ATTRIBUTE_UNUSED, ++ cumulative_args_t ca ATTRIBUTE_UNUSED) ++{ ++ return default_function_arg_boundary (mode, type); ++} ++ + unsigned int + default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED) +@@ -857,6 +865,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, + return PARM_BOUNDARY; + } + ++unsigned int ++default_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, ++ const_tree type ATTRIBUTE_UNUSED, ++ cumulative_args_t ca ATTRIBUTE_UNUSED) ++{ ++ return default_function_arg_round_boundary (mode, type); ++} ++ + void + hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) + { +diff --git a/gcc/targhooks.h b/gcc/targhooks.h +index ecce55ebe79..ba110ade58b 100644 +--- a/gcc/targhooks.h ++++ b/gcc/targhooks.h +@@ -154,6 +154,12 @@ extern unsigned int default_function_arg_boundary (machine_mode, + const_tree); + extern unsigned int default_function_arg_round_boundary (machine_mode, + const_tree); ++extern unsigned int default_function_arg_boundary_ca (machine_mode, ++ const_tree, ++ cumulative_args_t ca); ++extern unsigned int default_function_arg_round_boundary_ca (machine_mode, ++ const_tree, ++ cumulative_args_t ca); + extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); + extern rtx default_function_value (const_tree, const_tree, bool); + extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET); +diff --git a/gcc/testsuite/g++.dg/abi/aarch64_guard1.C b/gcc/testsuite/g++.dg/abi/aarch64_guard1.C +index e2669a89fbf..52be32decc6 100644 +--- a/gcc/testsuite/g++.dg/abi/aarch64_guard1.C ++++ b/gcc/testsuite/g++.dg/abi/aarch64_guard1.C +@@ -12,5 +12,6 @@ int *foo () + return &x; + } + +-// { dg-final { scan-assembler _ZGVZ3foovE1x,8,8 } } ++// { dg-final { scan-assembler _ZGVZ3foovE1x,8,8 { target { ! *-*-darwin* } } } } ++// { dg-final { scan-assembler __DATA,__bss,__ZGVZ3foovE1x,8,3 { target *-*-darwin* } } } + // { dg-final { scan-tree-dump "& 1" "original" } } +diff --git a/gcc/testsuite/g++.dg/abi/arm_va_list.C b/gcc/testsuite/g++.dg/abi/arm_va_list.C +index 4f6f3a46da4..ff9fd8bcf0d 100644 +--- a/gcc/testsuite/g++.dg/abi/arm_va_list.C ++++ b/gcc/testsuite/g++.dg/abi/arm_va_list.C +@@ -8,8 +8,10 @@ + // #include + typedef __builtin_va_list va_list; + +-// { dg-final { scan-assembler "\n_Z1fPSt9__va_list:" } } ++// { dg-final { scan-assembler "\n_Z1fPSt9__va_list:" { target { ! *-*-darwin* } } } } ++// { dg-final { scan-assembler "\n__Z1fPPc:" { target *-*-darwin* } } } + void f(va_list*) {} + +-// { dg-final { scan-assembler "\n_Z1gSt9__va_listS_:" } } ++// { dg-final { scan-assembler "\n_Z1gSt9__va_listS_:" { target { ! *-*-darwin* } } } } ++// { dg-final { scan-assembler "\n__Z1gPcS_:" { target *-*-darwin* } } } + void g(va_list, va_list) {} +diff --git a/gcc/testsuite/g++.dg/cpp0x/pr106435-b.cc b/gcc/testsuite/g++.dg/cpp0x/pr106435-b.cc +new file mode 100644 +index 00000000000..4f581694177 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/pr106435-b.cc +@@ -0,0 +1,17 @@ ++// PR c++/106435 ++#include "pr106435.h" ++ ++//#include ++ ++Foo::Foo() { ++ ++num_calls; ++// std::cout << "Foo::Foo(this=" << this << ")\n"; ++} ++ ++int Foo::func() { ++// std::cout << "Foo::func(this=" << this << ")\n"; ++ return num_calls; ++} ++ ++thread_local Foo Bar::foo; ++thread_local Foo Bar::baz; +diff --git a/gcc/testsuite/g++.dg/cpp0x/pr106435.C b/gcc/testsuite/g++.dg/cpp0x/pr106435.C +new file mode 100644 +index 00000000000..d600976f9f9 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/pr106435.C +@@ -0,0 +1,20 @@ ++// PR c++/106435 ++// { dg-do run { target c++11 } } ++// { dg-additional-sources "pr106435-b.cc" } ++ ++#include "pr106435.h" ++ ++int num_calls = 0; ++ ++extern "C" __attribute__((__noreturn__)) void abort(); ++ ++thread_local Foo Bar::bat; ++ ++int main() { ++ int v = Bar::foo.func(); ++ if (v != 2) ++ abort(); ++ v = Bar::bat.func(); ++ if (v != 3) ++ abort(); ++} +diff --git a/gcc/testsuite/g++.dg/cpp0x/pr106435.h b/gcc/testsuite/g++.dg/cpp0x/pr106435.h +new file mode 100644 +index 00000000000..240de1ee9a9 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/pr106435.h +@@ -0,0 +1,14 @@ ++// PR c++/106435 ++#pragma once ++ ++extern int num_calls; ++struct Foo { ++ Foo(); ++ int func(); ++}; ++ ++struct Bar { ++ thread_local static Foo foo; ++ thread_local static Foo baz; ++ thread_local static Foo bat; ++}; +diff --git a/gcc/testsuite/g++.dg/ext/arm-bf16/bf16-mangle-aarch64-1.C b/gcc/testsuite/g++.dg/ext/arm-bf16/bf16-mangle-aarch64-1.C +index 5426a1814b8..a017ce8ce5f 100644 +--- a/gcc/testsuite/g++.dg/ext/arm-bf16/bf16-mangle-aarch64-1.C ++++ b/gcc/testsuite/g++.dg/ext/arm-bf16/bf16-mangle-aarch64-1.C +@@ -2,12 +2,12 @@ + + /* Test mangling */ + +-/* { dg-final { scan-assembler "\t.global\t_Z1fPu6__bf16" } } */ ++/* { dg-final { scan-assembler {\t.globa?l[ \t]_?_Z1fPu6__bf16} } } */ + void f (__bf16 *x) { } + +-/* { dg-final { scan-assembler "\t.global\t_Z1gPu6__bf16S_" } } */ ++/* { dg-final { scan-assembler {\t.globa?l[ \t]_?_Z1gPu6__bf16S_} } } */ + void g (__bf16 *x, __bf16 *y) { } + +-/* { dg-final { scan-assembler "\t.global\t_ZN1SIu6__bf16u6__bf16E1iE" } } */ ++/* { dg-final { scan-assembler {\t.globa?l[ \t]_?_ZN1SIu6__bf16u6__bf16E1iE} } } */ + template struct S { static int i; }; + template <> int S<__bf16, __bf16>::i = 3; +diff --git a/gcc/testsuite/g++.dg/torture/darwin-cfstring-3.C b/gcc/testsuite/g++.dg/torture/darwin-cfstring-3.C +index ee4b385b17f..eabb3b517a4 100644 +--- a/gcc/testsuite/g++.dg/torture/darwin-cfstring-3.C ++++ b/gcc/testsuite/g++.dg/torture/darwin-cfstring-3.C +@@ -26,5 +26,5 @@ void foo(void) { + + /* { dg-final { scan-assembler "\\.long\[ \\t\]+___CFConstantStringClassReference\n\[ \\t\]*\\.long\[ \\t\]+1992\n\[ \\t\]*\\.long\[ \\t\]+\[lL\]C.*\n\[ \\t\]*\\.long\[ \\t\]+4\n" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler "\\.long\[ \\t\]+___CFConstantStringClassReference\n\[ \\t\]*\\.long\[ \\t\]+1992\n\[ \\t\]*\\.long\[ \\t\]+\[lL\]C.*\n\[ \\t\]*\\.long\[ \\t\]+10\n" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t4\n" { target { *-*-darwin* && { lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t10\n" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t4\n} { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t10\n} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/g++.target/aarch64/no_unique_address_1.C b/gcc/testsuite/g++.target/aarch64/no_unique_address_1.C +index 5fc68ea5d6d..5faf915fa54 100644 +--- a/gcc/testsuite/g++.target/aarch64/no_unique_address_1.C ++++ b/gcc/testsuite/g++.target/aarch64/no_unique_address_1.C +@@ -1,5 +1,5 @@ + /* { dg-options "-std=c++11 -O -foptimize-sibling-calls -fpeephole2" } */ +-/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */ ++/* { dg-final { check-function-bodies "**" "" "" { target { lp64 && { ! aarch64*-*-darwin* } } } } } */ + + struct X { }; + struct Y { int : 0; }; +diff --git a/gcc/testsuite/g++.target/aarch64/no_unique_address_2.C b/gcc/testsuite/g++.target/aarch64/no_unique_address_2.C +index f0717133ccd..322ec127c79 100644 +--- a/gcc/testsuite/g++.target/aarch64/no_unique_address_2.C ++++ b/gcc/testsuite/g++.target/aarch64/no_unique_address_2.C +@@ -1,5 +1,5 @@ + /* { dg-options "-std=c++17 -O -foptimize-sibling-calls -fpeephole2" } */ +-/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */ ++/* { dg-final { check-function-bodies "**" "" "" { target { lp64 && { ! aarch64*-*-darwin* } } } } } */ + + struct X { }; + struct Y { int : 0; }; +diff --git a/gcc/testsuite/g++.target/aarch64/sve/aarch64-sve.exp b/gcc/testsuite/g++.target/aarch64/sve/aarch64-sve.exp +index 03a6537a53e..d4c2052dc59 100644 +--- a/gcc/testsuite/g++.target/aarch64/sve/aarch64-sve.exp ++++ b/gcc/testsuite/g++.target/aarch64/sve/aarch64-sve.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } then { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib g++-dg.exp + +diff --git a/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp b/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp +index 38140413a97..559e1f37c68 100644 +--- a/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp ++++ b/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp +@@ -24,6 +24,11 @@ if { ![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib g++-dg.exp + +diff --git a/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle.exp b/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle.exp +index d1887eb8087..c9fee945c52 100644 +--- a/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle.exp ++++ b/gcc/testsuite/g++.target/aarch64/sve/acle/aarch64-sve-acle.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib g++-dg.exp + +diff --git a/gcc/testsuite/g++.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp b/gcc/testsuite/g++.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp +index 78e8ecae729..e22ef5f0876 100644 +--- a/gcc/testsuite/g++.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp ++++ b/gcc/testsuite/g++.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp +@@ -24,6 +24,11 @@ if { ![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib g++-dg.exp + +diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c +index 0f350f4ac16..d1e70b3a3e5 100644 +--- a/gcc/testsuite/gcc.dg/builtin-apply2.c ++++ b/gcc/testsuite/gcc.dg/builtin-apply2.c +@@ -1,7 +1,7 @@ + /* { dg-do run } */ + /* { dg-require-effective-target untyped_assembly } */ + /* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "avr-*-* nds32*-*-* amdgcn-*-*" } } */ +-/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "csky*-*-* riscv*-*-* or1k*-*-* msp430-*-* pru-*-* loongarch*-*-*" } } */ ++/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "csky*-*-* riscv*-*-* or1k*-*-* msp430-*-* pru-*-* loongarch*-*-* aarch64-apple-darwin*" } } */ + /* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } } */ + + /* PR target/12503 */ +diff --git a/gcc/testsuite/gcc.dg/cwsc1.c b/gcc/testsuite/gcc.dg/cwsc1.c +index e793e26116a..7d8b472bdf6 100644 +--- a/gcc/testsuite/gcc.dg/cwsc1.c ++++ b/gcc/testsuite/gcc.dg/cwsc1.c +@@ -6,7 +6,11 @@ + #elif defined(__i386__) + # define CHAIN "%ecx" + #elif defined(__aarch64__) +-# define CHAIN "x18" ++# if defined(__APPLE__) ++# define CHAIN "x16" ++# else ++# define CHAIN "x18" ++# endif + #elif defined(__alpha__) + # define CHAIN "$1" + #elif defined(__arm__) +diff --git a/gcc/testsuite/gcc.dg/darwin-segaddr.c b/gcc/testsuite/gcc.dg/darwin-segaddr.c +index 526db77bd9c..fcc324b3031 100644 +--- a/gcc/testsuite/gcc.dg/darwin-segaddr.c ++++ b/gcc/testsuite/gcc.dg/darwin-segaddr.c +@@ -1,7 +1,8 @@ + /* Check that -segaddr gets through and works. */ + /* { dg-do run { target *-*-darwin* } } */ + /* { dg-options "-O0 -segaddr __TEST 0x200000 -fno-pie" { target { *-*-darwin* && { ! lp64 } } } } */ +-/* { dg-options "-O0 -segaddr __TEST 0x110000000 -fno-pie" { target { *-*-darwin* && lp64 } } } */ ++/* { dg-options "-O0 -segaddr __TEST 0x110000000 -fno-pie" { target { *-*-darwin[1456789]* && lp64 } } } */ ++/* { dg-options "-O0 -segaddr __TEST 0x110000000 " { target { *-*-darwin2* && lp64 } } } */ + + extern void abort (); + +diff --git a/gcc/testsuite/gcc.dg/pr26427.c b/gcc/testsuite/gcc.dg/pr26427.c +index add13ca209e..2c09f28195d 100644 +--- a/gcc/testsuite/gcc.dg/pr26427.c ++++ b/gcc/testsuite/gcc.dg/pr26427.c +@@ -1,4 +1,4 @@ +-/* { dg-warning "this target does not support" "" {target *86*-*-darwin* } 0 } */ ++/* { dg-warning "this target does not support" "" {target *86*-*-darwin* aarch64-*-darwin* } 0 } */ + /* { dg-do run { target { *-*-darwin* } } } */ + /* { dg-options { -fsection-anchors -O } } */ + /* PR target/26427 */ +diff --git a/gcc/testsuite/gcc.dg/pubtypes-2.c b/gcc/testsuite/gcc.dg/pubtypes-2.c +index 116e3489bc0..b3d1231ad44 100644 +--- a/gcc/testsuite/gcc.dg/pubtypes-2.c ++++ b/gcc/testsuite/gcc.dg/pubtypes-2.c +@@ -2,7 +2,8 @@ + /* { dg-options "-O0 -gdwarf-2 -dA" } */ + /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */ + /* { dg-final { scan-assembler "__debug_pubtypes" } } */ +-/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} { target { ! aarch64-*-darwin* } } } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x163+[ \t]+[#;]+[ \t]+Pub Info Length} { target aarch64-*-darwin* } } } */ + /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + +diff --git a/gcc/testsuite/gcc.dg/pubtypes-3.c b/gcc/testsuite/gcc.dg/pubtypes-3.c +index 3fb3468fb00..950a9ba72fc 100644 +--- a/gcc/testsuite/gcc.dg/pubtypes-3.c ++++ b/gcc/testsuite/gcc.dg/pubtypes-3.c +@@ -2,7 +2,8 @@ + /* { dg-options "-O0 -gdwarf-2 -dA" } */ + /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */ + /* { dg-final { scan-assembler "__debug_pubtypes" } } */ +-/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} { target { ! aarch64-*-darwin* } } } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x163+[ \t]+[#;]+[ \t]+Pub Info Length} { target aarch64-*-darwin* } } } */ + /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + /* { dg-final { scan-assembler-not "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +diff --git a/gcc/testsuite/gcc.dg/pubtypes-4.c b/gcc/testsuite/gcc.dg/pubtypes-4.c +index 83fba8dfabc..7250771587b 100644 +--- a/gcc/testsuite/gcc.dg/pubtypes-4.c ++++ b/gcc/testsuite/gcc.dg/pubtypes-4.c +@@ -2,7 +2,8 @@ + /* { dg-options "-O0 -gdwarf-2 -dA" } */ + /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */ + /* { dg-final { scan-assembler "__debug_pubtypes" } } */ +-/* { dg-final { scan-assembler {long+[ \t]+0x184+[ \t]+[#;]+[ \t]+Pub Info Length} } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x184+[ \t]+[#;]+[ \t]+Pub Info Length} { target { ! aarch64-*-darwin* } } } } */ ++/* { dg-final { scan-assembler {long+[ \t]+0x19a+[ \t]+[#;]+[ \t]+Pub Info Length} { target aarch64-*-darwin* } } } */ + /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ + /* { dg-final { scan-assembler "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */ +diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/big-endian-cse-1.c b/gcc/testsuite/gcc.dg/rtl/aarch64/big-endian-cse-1.c +index 1559a489f25..aa2da0cbca5 100644 +--- a/gcc/testsuite/gcc.dg/rtl/aarch64/big-endian-cse-1.c ++++ b/gcc/testsuite/gcc.dg/rtl/aarch64/big-endian-cse-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile { target aarch64*-*-* } } */ ++/* { dg-skip-if "Darwin platforms do not support big-endian arm64" *-*-darwin* } */ + /* { dg-require-effective-target lp64 } */ + /* { dg-options "-O3 -mbig-endian" } */ + +diff --git a/gcc/testsuite/gcc.dg/tls/pr78796.c b/gcc/testsuite/gcc.dg/tls/pr78796.c +index 038e5366e41..31e03dd419c 100644 +--- a/gcc/testsuite/gcc.dg/tls/pr78796.c ++++ b/gcc/testsuite/gcc.dg/tls/pr78796.c +@@ -1,7 +1,7 @@ + /* PR target/78796 */ + /* { dg-do run } */ + /* { dg-options "-O2" } */ +-/* { dg-additional-options "-mcmodel=large" { target aarch64-*-* } } */ ++/* { dg-additional-options "-mcmodel=large" { target { { aarch64-*-* } && { ! aarch64-*-darwin* } } } } */ + /* { dg-require-effective-target tls_runtime } */ + /* { dg-add-options tls } */ + +diff --git a/gcc/testsuite/gcc.dg/torture/darwin-cfstring-3.c b/gcc/testsuite/gcc.dg/torture/darwin-cfstring-3.c +index ee4b385b17f..eabb3b517a4 100644 +--- a/gcc/testsuite/gcc.dg/torture/darwin-cfstring-3.c ++++ b/gcc/testsuite/gcc.dg/torture/darwin-cfstring-3.c +@@ -26,5 +26,5 @@ void foo(void) { + + /* { dg-final { scan-assembler "\\.long\[ \\t\]+___CFConstantStringClassReference\n\[ \\t\]*\\.long\[ \\t\]+1992\n\[ \\t\]*\\.long\[ \\t\]+\[lL\]C.*\n\[ \\t\]*\\.long\[ \\t\]+4\n" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler "\\.long\[ \\t\]+___CFConstantStringClassReference\n\[ \\t\]*\\.long\[ \\t\]+1992\n\[ \\t\]*\\.long\[ \\t\]+\[lL\]C.*\n\[ \\t\]*\\.long\[ \\t\]+10\n" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t4\n" { target { *-*-darwin* && { lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t10\n" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t4\n} { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t10\n} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +index 552ca1433f4..16643ceb198 100644 +--- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c ++++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +@@ -9,7 +9,7 @@ + /* arm_hf_eabi: Variadic funcs use Base AAPCS. Normal funcs use VFP variant. + avr: Variadic funcs don't pass arguments in registers, while normal funcs + do. */ +-/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { csky*-*-* avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* loongarch*-*-* } } } */ ++/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { csky*-*-* avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* loongarch*-*-* aarch64-apple-darwin* } } } */ + /* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* } { v850*-*-* } } */ + /* { dg-require-effective-target untyped_assembly } */ + +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c +index 0224997f18a..3684cffdc64 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-2.c +@@ -25,9 +25,9 @@ f1 (int i, ...) + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -46,9 +46,9 @@ f2 (int i, ...) + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -62,10 +62,10 @@ f3 (int i, ...) + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 1 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[1-9\]\[0-9\]* GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -81,9 +81,9 @@ f4 (int i, ...) + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -100,9 +100,9 @@ f5 (int i, ...) + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -121,9 +121,9 @@ f6 (int i, ...) + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 3 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -139,9 +139,9 @@ f7 (int i, ...) + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -159,9 +159,9 @@ f8 (int i, ...) + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f8: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -177,9 +177,9 @@ f9 (int i, ...) + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f9: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -197,9 +197,9 @@ f10 (int i, ...) + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f10: va_list escapes 1, needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -218,9 +218,9 @@ f11 (int i, ...) + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 3 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f11: va_list escapes 0, needs to save (3|12|24) GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -239,9 +239,9 @@ f12 (int i, ...) + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and 3 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f12: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -260,9 +260,9 @@ f13 (int i, ...) + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 24 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and 3 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save 0 GPR units and 48 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f13: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -281,9 +281,9 @@ f14 (int i, ...) + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[148\] GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 24 GPR units and 3" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 1 GPR units and 2 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f14: va_list escapes 0, needs to save \[1-9]\[0-9\]* GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + inline void __attribute__((always_inline)) +@@ -305,11 +305,11 @@ f15 (int i, ...) + /* { dg-final { scan-tree-dump "f15: va_list escapes 0, needs to save \[148\] GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f15: va_list escapes 0, needs to save \[148\] GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f15: va_list escapes 0, needs to save 1 GPR units and 2 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + + /* We may be able to improve upon this after fixing PR66010/PR66013. */ + /* { dg-final { scan-tree-dump "f15: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" { target alpha*-*-linux* } } } */ + + /* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump-not "f15: va_list escapes 0, needs to save 0 GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c +index 1a637d6efe4..77cdf384df4 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-4.c +@@ -27,9 +27,9 @@ f1 (int i, ...) + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -45,9 +45,9 @@ f2 (int i, ...) + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save 0 GPR units and all FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes \[01\], needs to save all GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + /* Here va_arg can be executed at most as many times as va_start. +@@ -69,9 +69,9 @@ f3 (int i, ...) + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units and 0 FPR units" "stdarg" { target { powerpc*-*-linux* && ilp32 } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ + + void +@@ -91,7 +91,7 @@ f4 (int i, ...) + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and \[1-9\]\[0-9\]* FPR units" "stdarg" { target { powerpc*-*-linux* && { powerpc_fprs && ilp32 } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 8 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and 1 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 0 GPR units and 16 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target ia64-*-* aarch64-apple-darwin* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save \[148\] GPR units" "stdarg" { target { powerpc*-*-* && lp64 } } } } */ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c +index c8ad4fe320d..b0484f2f053 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/stdarg-5.c +@@ -25,7 +25,8 @@ f1 (int i, ...) + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f1: va_list escapes 0, needs to save all GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + void + f2 (int i, ...) +@@ -39,7 +40,8 @@ f2 (int i, ...) + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and all FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f2: va_list escapes 0, needs to save all GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + /* Here va_arg can be executed at most as many times as va_start. */ + void +@@ -58,7 +60,8 @@ f3 (int i, ...) + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 0 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 1 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f3: va_list escapes 0, needs to save 8 GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + void + f4 (int i, ...) +@@ -77,7 +80,8 @@ f4 (int i, ...) + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 16 GPR units and 16 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f4: va_list escapes 0, needs to save 24 GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + void + f5 (int i, ...) +@@ -92,7 +96,8 @@ f5 (int i, ...) + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 32 GPR units and 1" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save (4|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units and 0 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f5: va_list escapes 0, needs to save 16 GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + void + f6 (int i, ...) +@@ -107,7 +112,8 @@ f6 (int i, ...) + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 32 GPR units and 3" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save (3|2) GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 8 GPR units and 32 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f6: va_list escapes 0, needs to save 24 GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ + + void + f7 (int i, ...) +@@ -122,4 +128,5 @@ f7 (int i, ...) + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 || llp64 } } } } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 32 GPR units and 2" "stdarg" { target alpha*-*-linux* } } } */ + /* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 2 GPR units and 0 FPR units" "stdarg" { target s390*-*-linux* } } } */ +-/* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target aarch64*-*-* } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 0 GPR units and 64 FPR units" "stdarg" { target { { aarch64*-*-* } && { ! aarch64-apple-darwin* } } } } } */ ++/* { dg-final { scan-tree-dump "f7: va_list escapes 0, needs to save 32 GPR units" "stdarg" { target aarch64-apple-darwin* } } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp +index 3e652c483c7..34907929bda 100644 +--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp ++++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/aapcs64.exp +@@ -25,6 +25,11 @@ if { ![istarget aarch64*-*-*] } then { + return + } + ++if { [istarget *-*-darwin*] } then { ++ # darwinpcs and mach-o will need different test mechanisms. ++ return ++} ++ + torture-init + set-torture-options $C_TORTURE_OPTIONS + set additional_flags "-W -Wall -Wno-abi" +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_dup.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_dup.c +index c42c7acbbe9..76917a6ff5b 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_dup.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_dup.c +@@ -1,4 +1,5 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-options "-O2" } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_get.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_get.c +index 2193753ffbb..d29b222b032 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_get.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_get.c +@@ -1,4 +1,5 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_reinterpret.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_reinterpret.c +index f5adf40c648..4e3a3d94416 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_reinterpret.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bf16_reinterpret.c +@@ -1,4 +1,5 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-compile.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-compile.c +index 47af7c494d9..a2f415f67b7 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-compile.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-compile.c +@@ -1,4 +1,5 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-nosimd.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-nosimd.c +index a914680937d..c6b2ef3e444 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-nosimd.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvt-nosimd.c +@@ -2,7 +2,7 @@ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + /* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-additional-options "-save-temps -march=armv8.2-a+bf16+nosimd" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvtnq2-untied.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvtnq2-untied.c +index 4b730e39d4e..fd2abadb457 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvtnq2-untied.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfcvtnq2-untied.c +@@ -1,8 +1,9 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + + #include +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-1.c +index ad51507731b..e57053d2193 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-1.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-1.c +@@ -1,8 +1,9 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + + #include +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-2.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-2.c +index ae0a953f7b4..9f5669a8974 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfdot-2.c +@@ -3,7 +3,7 @@ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-mbig-endian --save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + + #include +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmlalbt-compile.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmlalbt-compile.c +index 9810e4ba374..315cabd464b 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmlalbt-compile.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmlalbt-compile.c +@@ -1,8 +1,9 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ ++/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" { target { ! aarch64*-*-darwin* } } } } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmmla-compile.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmmla-compile.c +index 0aaa69f0037..ddc391b1332 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmmla-compile.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/bfmmla-compile.c +@@ -1,8 +1,9 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target aarch64_asm_bf16_ok } */ + /* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */ + /* { dg-add-options arm_v8_2a_bf16_neon } */ + /* { dg-additional-options "-save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ ++/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" { target { ! aarch64*-*-darwin* } } } } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-1.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-1.c +index ac4f821e771..978eac29815 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-1.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-1.c +@@ -1,8 +1,9 @@ + /* { dg-do assemble { target { aarch64*-*-* } } } */ ++/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw } */ + /* { dg-require-effective-target arm_v8_2a_i8mm_ok } */ + /* { dg-add-options arm_v8_2a_i8mm } */ + /* { dg-additional-options "-save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + + #include +diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-2.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-2.c +index 61c7c51f5ec..f84ed68e2f7 100644 +--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vdot-3-2.c +@@ -3,7 +3,7 @@ + /* { dg-require-effective-target arm_v8_2a_i8mm_ok } */ + /* { dg-add-options arm_v8_2a_i8mm } */ + /* { dg-additional-options "-mbig-endian -save-temps" } */ +-/* { dg-final { check-function-bodies "**" "" {-O[^0]} } } */ ++/* { dg-final { check-function-bodies "**" "" {-O[^0]} { target { ! aarch64*-*-darwin* } } } } */ + /* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */ + + #include +diff --git a/gcc/testsuite/gcc.target/aarch64/arm_align_max_pwr.c b/gcc/testsuite/gcc.target/aarch64/arm_align_max_pwr.c +index ffa4d229922..38b9ef01eb7 100644 +--- a/gcc/testsuite/gcc.target/aarch64/arm_align_max_pwr.c ++++ b/gcc/testsuite/gcc.target/aarch64/arm_align_max_pwr.c +@@ -19,5 +19,7 @@ dummy () + return result; + } + +-/* { dg-final { scan-assembler-times "zero\t4" 2 } } */ +-/* { dg-final { scan-assembler "zero\t268435452" } } */ ++/* { dg-final { scan-assembler-times "zero\t4" 2 { target { ! *-*-darwin* } } } } */ ++/* { dg-final { scan-assembler "zero\t268435452" { target { ! *-*-darwin*} } } } */ ++/* { dg-final { scan-assembler-times ".zerofill __DATA,__bss,_y,4,28" 1 { target { *-*-darwin* } } } } */ ++/* { dg-final { scan-assembler-times ".zerofill __DATA,__bss,_x,4,28" 1 { target { *-*-darwin* } } } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-2.c b/gcc/testsuite/gcc.target/aarch64/auto-init-2.c +index 375befd325b..3a0387a5952 100644 +--- a/gcc/testsuite/gcc.target/aarch64/auto-init-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/auto-init-2.c +@@ -12,11 +12,11 @@ enum E { + N3 + }; + +-extern void bar (char, short, int, enum E, long, long long, int *, bool); ++extern void bar (unsigned char, short, int, enum E, long, long long, int *, bool); + + void foo() + { +- char temp1; ++ unsigned char temp1; + short temp2; + int temp3; + enum E temp4; +diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-3.c b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c +index 7008f76b294..85a4e4daeb6 100644 +--- a/gcc/testsuite/gcc.target/aarch64/auto-init-3.c ++++ b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c +@@ -2,13 +2,19 @@ + /* { dg-do compile } */ + /* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */ + +-long double result; ++#ifdef __APPLE__ ++# define TYPE _Float128 ++#else ++# define TYPE long double ++#endif + +-long double foo() ++TYPE result; ++ ++TYPE foo() + { + float temp1; + double temp2; +- long double temp3; ++ TYPE temp3; + + result = temp1 + temp2 + temp3; + return result; +diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-4.c b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c +index 10197045b4c..0c6840ba224 100644 +--- a/gcc/testsuite/gcc.target/aarch64/auto-init-4.c ++++ b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c +@@ -2,13 +2,19 @@ + /* { dg-do compile } */ + /* { dg-options "-O -ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */ + +-long double result; ++#ifdef __APPLE__ ++# define TYPE _Float128 ++#else ++# define TYPE long double ++#endif + +-long double foo() ++TYPE result; ++ ++TYPE foo() + { + float temp1; + double temp2; +- long double temp3; ++ TYPE temp3; + + result = temp1 + temp2 + temp3; + return result; +diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-5.c b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c +index ac69ac3df82..0dda3c201d3 100644 +--- a/gcc/testsuite/gcc.target/aarch64/auto-init-5.c ++++ b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c +@@ -2,14 +2,19 @@ + /* { dg-do compile } */ + /* { dg-options "-ftrivial-auto-var-init=zero" } */ + ++#ifdef __APPLE__ ++# define TYPE _Float128 ++#else ++# define TYPE long double ++#endif + +-_Complex long double result; ++_Complex TYPE result; + +-_Complex long double foo() ++_Complex TYPE foo() + { + _Complex float temp1; + _Complex double temp2; +- _Complex long double temp3; ++ _Complex TYPE temp3; + + result = temp1 + temp2 + temp3; + return result; +diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-6.c b/gcc/testsuite/gcc.target/aarch64/auto-init-6.c +index 0456c66f496..23323115a11 100644 +--- a/gcc/testsuite/gcc.target/aarch64/auto-init-6.c ++++ b/gcc/testsuite/gcc.target/aarch64/auto-init-6.c +@@ -2,14 +2,19 @@ + /* { dg-do compile } */ + /* { dg-options "-ftrivial-auto-var-init=pattern" } */ + ++#ifdef __APPLE__ ++# define TYPE _Float128 ++#else ++# define TYPE long double ++#endif + +-_Complex long double result; ++_Complex TYPE result; + +-_Complex long double foo() ++_Complex TYPE foo() + { + _Complex float temp1; + _Complex double temp2; +- _Complex long double temp3; ++ _Complex TYPE temp3; + + result = temp1 + temp2 + temp3; + return result; +diff --git a/gcc/testsuite/gcc.target/aarch64/c-output-template-2.c b/gcc/testsuite/gcc.target/aarch64/c-output-template-2.c +index ced96d04542..86e4f5fa82c 100644 +--- a/gcc/testsuite/gcc.target/aarch64/c-output-template-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/c-output-template-2.c +@@ -6,4 +6,4 @@ test (void) + __asm__ ("@ %c0" : : "S" (test)); + } + +-/* { dg-final { scan-assembler "@ test" } } */ ++/* { dg-final { scan-assembler "@ _?test" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/c-output-template-3.c b/gcc/testsuite/gcc.target/aarch64/c-output-template-3.c +index 8bde4cbeb0c..4531a381518 100644 +--- a/gcc/testsuite/gcc.target/aarch64/c-output-template-3.c ++++ b/gcc/testsuite/gcc.target/aarch64/c-output-template-3.c +@@ -7,4 +7,4 @@ test (void) + __asm__ ("@ %c0" : : "S" (&test + 4)); + } + +-/* { dg-final { scan-assembler "@ test\\+4" } } */ ++/* { dg-final { scan-assembler "@ _?test\\+4" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/c-output-template-4.c b/gcc/testsuite/gcc.target/aarch64/c-output-template-4.c +index c5a93915af1..800d52bfab8 100644 +--- a/gcc/testsuite/gcc.target/aarch64/c-output-template-4.c ++++ b/gcc/testsuite/gcc.target/aarch64/c-output-template-4.c +@@ -7,4 +7,4 @@ test (void) + __asm__ ("@ %c0" : : "S" (&test + 4)); + } + +-/* { dg-final { scan-assembler "@ test\\+4" } } */ ++/* { dg-final { scan-assembler "@ _?test\\+4" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/cpymem-size.c b/gcc/testsuite/gcc.target/aarch64/cpymem-size.c +index 4a6f2495d22..b8ef4745c6d 100644 +--- a/gcc/testsuite/gcc.target/aarch64/cpymem-size.c ++++ b/gcc/testsuite/gcc.target/aarch64/cpymem-size.c +@@ -6,7 +6,7 @@ + /* + ** cpy_127: + ** mov (w|x)2, 127 +-** b memcpy ++** b _?memcpy + */ + void + cpy_127 (char *out, char *in) +@@ -17,7 +17,7 @@ cpy_127 (char *out, char *in) + /* + ** cpy_128: + ** mov (w|x)2, 128 +-** b memcpy ++** b _?memcpy + */ + void + cpy_128 (char *out, char *in) +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/aarch64-darwin.exp b/gcc/testsuite/gcc.target/aarch64/darwin/aarch64-darwin.exp +new file mode 100644 +index 00000000000..b0b7f49aede +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/aarch64-darwin.exp +@@ -0,0 +1,46 @@ ++# Specific tests for the darwinpcs and codegen. ++# Copyright (C) GNU Toolchain Authors ++# Contributed by Iain Sandoe ++# ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . */ ++ ++# GCC testsuite that uses the `dg.exp' driver. ++ ++# Exit immediately if this isn't aarch64-darwin. ++ ++if { ![istarget aarch64*-*-darwin*] } then { ++ return ++} ++ ++# Load support procs. ++load_lib gcc-dg.exp ++ ++# If a testcase doesn't have special options, use these. ++global DEFAULT_CFLAGS ++if ![info exists DEFAULT_CFLAGS] then { ++ set DEFAULT_CFLAGS " -ansi -pedantic-errors" ++} ++ ++# Initialize `dg'. ++dg-init ++ ++# Main loop. ++dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ ++ "" $DEFAULT_CFLAGS ++ ++# All done. ++dg-finish +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/complex-in-regs.c b/gcc/testsuite/gcc.target/aarch64/darwin/complex-in-regs.c +new file mode 100644 +index 00000000000..974f02ca2ec +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/complex-in-regs.c +@@ -0,0 +1,103 @@ ++/* { dg-do compile } */ ++/* we need this for complex and gnu initializers. */ ++/* { dg-options "-std=gnu99 " } */ ++/* We use the sections anchors to make the code easier to match. */ ++/* { dg-additional-options " -O -fsection-anchors -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++ ++__attribute__((__noinline__)) ++_Complex char ++cc_regs_fun (_Complex char r0, _Complex char r1, ++ _Complex char r2, _Complex char r3, ++ _Complex char r4, _Complex char r5, ++ _Complex char r6, _Complex char r7); ++ ++/* ++**call_cc_regs_fun: ++** ... ++** ldrh w7, \[x0\] ++** ldrh w6, \[x0, 2\] ++** ldrh w5, \[x0, 4\] ++** ldrh w4, \[x0, 6\] ++** ldrh w3, \[x0, 8\] ++** ldrh w2, \[x0, 10\] ++** ldrh w1, \[x0, 12\] ++** ldrh w0, \[x0, 14]\ ++** bl _cc_regs_fun ++** ... ++*/ ++ ++_Complex char ++call_cc_regs_fun (void) ++{ ++ return cc_regs_fun ((_Complex char) (1 + 1i), (_Complex char) (2 + 2i), ++ (_Complex char) (3 + 3i), (_Complex char) (4 + 4i), ++ (_Complex char) (5 + 5i), (_Complex char) (6 + 6i), ++ (_Complex char) (7 + 7i), (_Complex char) (8 + 8i)); ++} ++ ++ ++__attribute__((__noinline__)) ++_Complex short ++cs_regs_fun (_Complex short r0, _Complex short r1, ++ _Complex short r2, _Complex short r3, ++ _Complex short r4, _Complex short r5, ++ _Complex short r6, _Complex short r7); ++ ++/* ++**call_cs_regs_fun: ++** ... ++** ldr w7, \[x0, 16\] ++** ldr w6, \[x0, 20\] ++** ldr w5, \[x0, 24\] ++** ldr w4, \[x0, 28\] ++** ldr w3, \[x0, 32\] ++** ldr w2, \[x0, 36\] ++** ldr w1, \[x0, 40\] ++** ldr w0, \[x0, 44\] ++** bl _cs_regs_fun ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Complex short ++call_cs_regs_fun (void) ++{ ++ return cs_regs_fun ((_Complex short) (1 + 1i), (_Complex short) (2 + 2i), ++ (_Complex short) (3 + 3i), (_Complex short) (4 + 4i), ++ (_Complex short) (5 + 5i), (_Complex short) (6 + 6i), ++ (_Complex short) (7 + 7i), (_Complex short) (8 + 8i)); ++} ++ ++__attribute__((__noinline__)) ++_Complex int ++ci_regs_fun (_Complex int r0, _Complex int r1, ++ _Complex int r2, _Complex int r3, ++ _Complex int r4, _Complex int r5, ++ _Complex int r6, _Complex int r7); ++ ++/* ++**call_ci_regs_fun: ++** ... ++** ldr x7, \[x0, 48\] ++** ldr x6, \[x0, 56\] ++** ldr x5, \[x0, 64\] ++** ldr x4, \[x0, 72\] ++** ldr x3, \[x0, 80\] ++** ldr x2, \[x0, 88\] ++** ldr x1, \[x0, 96\] ++** ldr x0, \[x0, 104\] ++** bl _ci_regs_fun ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Complex int ++call_ci_regs_fun (void) ++{ ++ return ci_regs_fun ((_Complex int) (1 + 1i), (_Complex int) (2 + 2i), ++ (_Complex int) (3 + 3i), (_Complex int) (4 + 4i), ++ (_Complex int) (5 + 5i), (_Complex int) (6 + 6i), ++ (_Complex int) (7 + 7i), (_Complex int) (8 + 8i)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d1.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d1.c +new file mode 100644 +index 00000000000..e2dd574fac7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d1.c +@@ -0,0 +1,54 @@ ++/* { dg-do compile } */ ++/* we need this for the empty struct. */ ++/* { dg-options "-std=gnu99 " } */ ++/* { dg-additional-options "-O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* Make sure we do no consume any registers in passing zero-sized entities */ ++ ++typedef struct es {} Empty; ++ ++__attribute__((__noinline__)) void ++use_no_regs (int a, Empty b, int c, Empty d, Empty e, int f); ++ ++/* ++**call_use_no_regs: ++** ... ++** mov w2, 3 ++** mov w1, 2 ++** mov w0, 1 ++** bl _use_no_regs ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++call_use_no_regs (void) ++{ ++ Empty e; ++ use_no_regs (1, e, 2, e, e, 3); ++} ++ ++/* Make sure we consume no stack in passing zero-sized entities. */ ++ ++/* ++**call_use_no_stack: ++** ... ++** mov w[0-9]+, 108 ++** strb w[0-9]+, \[sp, 1\] ++** mov w[0-9]+, 106 ++** strb w[0-9]+, \[sp\] ++** ... ++** bl _use_no_stack ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++use_no_stack (int a, int b, int c, int d, int e, int f, int g, int h, ++ Empty i, char j, Empty k, char l); ++ ++void ++call_use_no_stack (void) ++{ ++ Empty e; ++ use_no_stack (0, 1, 2, 3, 4, 5, 6, 7, e, 'j', e, 'l'); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-00.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-00.c +new file mode 100644 +index 00000000000..bd76856308b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-00.c +@@ -0,0 +1,126 @@ ++/* { dg-do compile } */ ++/* { dg-additional-options " -O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* In each case we consume the parm registers with 8 ints, forcing ++ the test values to be spilled to the stack. */ ++ ++/* The important thing here is that the chars are assigned to the stack ++ * with no padding - so that they occupy bytes 0-8. */ ++ ++/* ++**call_char_packing: ++** ... ++** mov w[0-9]+, 113 ++** strb w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 112 ++** strb w[0-9]+, \[sp, 7\] ++** mov w[0-9]+, 111 ++** strb w[0-9]+, \[sp, 6\] ++** mov w[0-9]+, 110 ++** strb w[0-9]+, \[sp, 5\] ++** mov w[0-9]+, 109 ++** strb w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 108 ++** strb w[0-9]+, \[sp, 3\] ++** mov w[0-9]+, 107 ++** strb w[0-9]+, \[sp, 2\] ++** mov w[0-9]+, 106 ++** strb w[0-9]+, \[sp, 1\] ++** mov w[0-9]+, 105 ++** strb w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _char_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++char_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ char i, char j, char k, char l, ++ char m, char n, char o, char p, ++ char q); ++ ++void call_char_packing (void) ++{ ++ char_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'); ++} ++ ++/* Here we should occupy the first 7 short words on the stack. */ ++ ++/* ++**call_short_packing: ++** ... ++** mov w[0-9]+, 12 ++** strh w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 11 ++** strh w[0-9]+, \[sp, 6\] ++** mov w[0-9]+, 10 ++** strh w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 9 ++** strh w[0-9]+, \[sp, 2\] ++** mov w[0-9]+, 8 ++** strh w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _short_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++short_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ short i, short j, short k, short l, ++ short m); ++ ++void call_short_packing (void) ++{ ++ short_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12); ++} ++ ++/* Here we should occupy the first 3 ints on the stack. */ ++ ++/* ++**call_int_packing: ++** ... ++** mov w[0-9]+, 10 ++** str w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 9 ++** str w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 8 ++** str w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _int_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++int_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ int i, int j, int k); ++ ++void call_int_packing (void) ++{ ++ int_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10); ++} ++ +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-01.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-01.c +new file mode 100644 +index 00000000000..d21fd551b4a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-01.c +@@ -0,0 +1,115 @@ ++/* { dg-do compile } */ ++/* { dg-additional-options " -O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* In each case we consume the parm registers with 8 ints, forcing ++ the test values to be spilled to the stack. */ ++ ++/* char short char short - everything on 2byte boundaries */ ++ ++/* ++**call_c_s_packing: ++** ... ++** mov w[0-9]+, 109 ++** strb w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 9 ++** strh w[0-9]+, \[sp, 6\] ++** mov w[0-9]+, 107 ++** strb w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 8 ++** strh w[0-9]+, \[sp, 2\] ++** mov w[0-9]+, 105 ++** strb w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _c_s_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++c_s_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ char i, short j, char k, short l, ++ char m); ++ ++void call_c_s_packing (void) ++{ ++ c_s_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 'i', 8 , 'k', 9, 'm'); ++} ++ ++/* ++**call_s_c_packing: ++** ... ++** mov w[0-9]+, 109 ++** strb w[0-9]+, \[sp, 7\] ++** mov w[0-9]+, 108 ++** strb w[0-9]+, \[sp, 6\] ++** mov w[0-9]+, 9 ++** strh w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 106 ++** strb w[0-9]+, \[sp, 2\] ++** mov w[0-9]+, 8 ++** strh w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _s_c_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++s_c_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ short i, char j, short k, char l, ++ char m); ++ ++void call_s_c_packing (void) ++{ ++ s_c_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 'j' , 9, 'l', 'm'); ++} ++ ++/* 0, 2, 4, 0 */ ++ ++/* ++**call_csi_packing: ++** ... ++** mov w[0-9]+, 108 ++** strb w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 9 ++** str w[0-9]+, \[sp, 4\] ++** mov w[0-9]+, 8 ++** strh w[0-9]+, \[sp, 2\] ++** mov w[0-9]+, 105 ++** strb w[0-9]+, \[sp\] ++** mov w7, 7 ++** mov w6, 6 ++** mov w5, 5 ++** mov w4, 4 ++** mov w3, 3 ++** mov w2, 2 ++** mov w1, 1 ++** mov w0, 0 ++** bl _csi_packing ++** ... ++*/ ++ ++__attribute__((__noinline__)) void ++csi_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ char i, short j, int k, char l); ++ ++void call_csi_packing (void) ++{ ++ csi_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ 'i', 8 , 9, 'l'); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-02.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-02.c +new file mode 100644 +index 00000000000..55e5acdaf41 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-02.c +@@ -0,0 +1,75 @@ ++/* { dg-do compile } */ ++/* we need this for complex literals. */ ++/* { dg-options "-std=gnu99 " } */ ++/* { dg-additional-options "-O -fsection-anchors -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++ ++__attribute__((__noinline__)) void ++c_cc_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ _Complex char i, _Complex char j); ++ ++/* We check that these values are not packed on the stack. ++**call_c_cc_packing: ++** ... ++** ldrh w[0-9]+, \[x[0-9]+\] ++** strh w[0-9]+, \[sp, 8\] ++** ldrh w[0-9]+, \[x[0-9]+, 2\] ++** strh w[0-9]+, \[sp\] ++** ... ++** bl _c_cc_packing ++** ... ++*/ ++ ++void ++call_c_cc_packing (void) ++{ ++ c_cc_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ (_Complex char) (1 + 1i),(_Complex char) (2 + 2i)); ++} ++ ++ ++__attribute__((__noinline__)) void ++c_cs_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ _Complex short i, _Complex short j); ++ ++/* ++**call_c_cs_packing: ++** ... ++** ldr w[0-9]+, \[x[0-9]+, 4\] ++** str w[0-9]+, \[sp, 8\] ++** ldr w[0-9]+, \[x[0-9]+, 8\] ++** str w[0-9]+, \[sp\] ++** ... ++** bl _c_cs_packing ++** ... ++*/ ++ ++void ++call_c_cs_packing (void) ++{ ++ c_cs_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ (_Complex short) (1 + 1i),(_Complex short) (2 + 2i)); ++} ++ ++void c_ci_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ _Complex int i, _Complex int j); ++ ++/* ++**call_c_ci_packing: ++** ... ++** ldr x[0-9]+, \[x[0-9]+, 12\] ++** str x[0-9]+, \[sp, 8\] ++** ldr x[0-9]+, \[x[0-9]+, 20\] ++** str x[0-9]+, \[sp\] ++** ... ++** bl _c_ci_packing ++** ... ++*/ ++ ++void ++call_c_ci_packing (void) ++{ ++ c_ci_packing (0, 1, 2, 3, 4, 5, 6, 7, ++ (_Complex int) (1 + 1i),(_Complex int) (2 + 2i)); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-03.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-03.c +new file mode 100644 +index 00000000000..b0d2593dfd7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-03.c +@@ -0,0 +1,67 @@ ++/* { dg-do compile } */ ++ ++/* { dg-additional-options "-O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++typedef union u { char a; short b; } U; ++typedef struct sf { float a; float b; float c;} SF; ++ ++__attribute__((__noinline__)) void ++u_packing (int a, int b, int c, int d, int e, int f, int g, int h, ++ U i, U j); ++ ++/* We check that these values are not packed on the stack. ++**call_u_packing: ++** ... ++** strh w[0-9]+, \[sp, 8\] ++** strh w[0-9]+, \[sp\] ++** ... ++** bl _u_packing ++** ... ++*/ ++ ++void ++call_u_packing (void) ++{ ++ U x = { 'a' }; ++ u_packing (0, 1, 2, 3, 4, 5, 6, 7, x, x); ++} ++ ++/* But a homogeneous float aggregate is treated as if it were the contained ++ floats. */ ++ ++__attribute__((__noinline__)) void ++sf_packing (float a, float b, float c, float d, ++ float e, float f, float g, float h, ++ SF i, SF j); ++ ++/* So the stores to sp+12 and 20 pack the floats onto the stack. ++**call_sf_packing: ++** ... ++** fmov s1, 1.0e\+0 ++** str s1, \[sp, 48\] ++** fmov s2, 2.0e\+0 ++** str s2, \[sp, 52\] ++** mov w[0-9]+, 1077936128 ++** ldr x[0-9]+, \[sp, 48\] ++** str x[0-9]+, \[sp, 12\] ++** str w[0-9]+, \[sp, 20\] ++** str x[0-9]+, \[sp\] ++** str w[0-9]+, \[sp, 8\] ++** fmov s7, 7.0e\+0 ++** fmov s6, 6.0e\+0 ++** fmov s5, 5.0e\+0 ++** fmov s4, 4.0e\+0 ++** fmov s3, 3.0e\+0 ++** movi v0.2s, #0 ++** bl _sf_packing ++** ... ++*/ ++ ++void ++call_sf_packing (void) ++{ ++ SF A = {1.0F, 2.0F, 3.0F}; ++ sf_packing (0.0F, 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F, ++ A, A); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-04.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-04.c +new file mode 100644 +index 00000000000..33c60c69b78 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d2-04.c +@@ -0,0 +1,66 @@ ++/* { dg-do compile } */ ++ ++/* { dg-additional-options "-O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++typedef short v2hi __attribute__ ((vector_size (4))); ++typedef int v4si __attribute__ ((vector_size (16))); ++ ++v4si t; ++int al = __alignof__ (t); ++ ++__attribute__((__noinline__)) void ++v2hi_packing (v2hi a, v2hi b, v2hi c, v2hi d, v2hi e, v2hi f, v2hi g, v2hi h, ++ v2hi i, v2hi j); ++ ++/* We check that v2hi is packed on the stack. ++**call_v2hi_packing: ++** ... ++** mov w[0-9]+, 1 ++** movk w[0-9]+, 0x2, lsl 16 ++** str w[0-9]+, \[sp, 4\] ++** str w[0-9]+, \[sp\] ++** mov w7, w[0-9]+ ++** mov w6, w[0-9]+ ++** mov w5, w[0-9]+ ++** mov w4, w[0-9]+ ++** mov w3, w[0-9]+ ++** mov w2, w[0-9]+ ++** mov w1, w[0-9]+ ++** bl _v2hi_packing ++** ... ++*/ ++ ++void ++call_v2hi_packing (void) ++{ ++ v2hi x = {1,2}; ++ v2hi_packing (x, x, x, x, x, x, x, x, x, x); ++} ++ ++ ++__attribute__((__noinline__)) void ++v4si_packing (int r0, int r1, int r2, int r3, int r4, int r5, int r6, int r7, ++ v4si a, v4si b, v4si c, v4si d, v4si e, v4si f, v4si g, v4si h, ++ int stack, v4si i, v4si j); ++ ++/* Test that we align a 16b vector on the stack. ++**call_v4si_packing: ++** ... ++** adrp x0, lC0@PAGE ++** ldr q[0-9]+, \[x[0-9]+, #lC0@PAGEOFF\] ++** str q[0-9]+, \[sp, 32\] ++** str q[0-9]+, \[sp, 16\] ++** mov w[0-9]+, 42 ++** str w[0-9]+, \[sp\] ++** ... ++** bl _v4si_packing ++** ... ++*/ ++ ++void ++call_v4si_packing (void) ++{ ++ v4si x = {3,1,2,4}; ++ v4si_packing (0, 1, 2, 3, 4, 5, 6, 7, x, x, x, x, x, x, x, x, 42, x, x); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d3.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d3.c +new file mode 100644 +index 00000000000..21c6b696b7c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d3.c +@@ -0,0 +1,40 @@ ++/* { dg-do compile } */ ++/* { dg-additional-options "-O " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* This will fail, because of issue #74 ++**foo: ++** cmp w0, w1 ++** cset w0, eq ++** ret ++*/ ++ ++__attribute__((__noinline__)) ++int ++foo (char a, unsigned char b) ++{ ++ return a == b ? 1 : 0; ++} ++ ++__attribute__((__noinline__)) ++int ++bar (short a, unsigned short b) ++{ ++ return a == b ? 1 : 0; ++} ++ ++void pop (char *, unsigned char *, short *, unsigned short *); ++ ++int main () ++{ ++ char a; ++ unsigned char b; ++ short c; ++ unsigned short d; ++ int result; ++ pop (&a, &b, &c, &d); ++ ++ result = foo (a, b); ++ result += bar (c, d); ++ return result; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d4.c b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d4.c +new file mode 100644 +index 00000000000..2aab48260f4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/darwinpcs-d4.c +@@ -0,0 +1,62 @@ ++/* { dg-do compile } */ ++/* we need this for __int128. */ ++/* { dg-options "-std=gnu99 " } */ ++/* { dg-additional-options "-O -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* we should use x0, x1 and x2 - not skip x1. ++**foo: ++** eor x0, x0, x1 ++** orr x0, x0, x2 ++** cmp x0, 0 ++** cset w0, eq ++** ret ++*/ ++ ++__attribute__((__noinline__)) ++int ++foo (unsigned long long x,unsigned __int128 y) ++{ ++ return x == y ? 1 : 0; ++} ++ ++/* we should use x0, x1 and x2. ++**bar: ++** eor x2, x2, x0 ++** orr x2, x2, x1 ++** cmp x2, 0 ++** cset w0, eq ++** ret ++*/ ++ ++__attribute__((__noinline__)) ++int ++bar (unsigned __int128 y, unsigned long long x) ++{ ++ return x == y ? 1 : 0; ++} ++ ++int fooo (unsigned long long x, unsigned __int128 y); ++int baro (unsigned __int128 y, unsigned long long x); ++ ++/* we should use x0, x1 and x2 in both calls. ++**main: ++** ... ++** mov x1, 25 ++** mov x2, 0 ++** mov x0, 10 ++** bl _fooo ++** mov x2, 10 ++** mov x0, 25 ++** mov x1, 0 ++** bl _baro ++** ... ++*/ ++ ++int main () ++{ ++ unsigned long long x = 10; ++ unsigned __int128 y = 25; ++ int r = fooo (x, y); ++ r += baro (y, x); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/float128-00.c b/gcc/testsuite/gcc.target/aarch64/darwin/float128-00.c +new file mode 100644 +index 00000000000..29aec80fbaa +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/float128-00.c +@@ -0,0 +1,38 @@ ++ ++/* we need this for _Float128. */ ++/* { dg-options "-std=gnu99 " } */ ++/* We use the sections anchors to make the code easier to match. */ ++/* { dg-additional-options " -O2 -fsection-anchors " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* we should just pass q0 and q1 through ++**foo: ++** ... ++** bl ___addtf3 ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++foo (_Float128 a, _Float128 b) ++{ ++ return a + b; ++} ++ ++ ++/* we should just load q0 and q1 ++**call_foo: ++** ... ++** ldr q1, \[x[0-9]+\] ++** ... ++** ldr q0, \[x[0-9]+\] ++** b _foo ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++call_foo (void) ++{ ++ return foo (1.0, 2.0); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/homogeneous-aggr.c b/gcc/testsuite/gcc.target/aarch64/darwin/homogeneous-aggr.c +new file mode 100644 +index 00000000000..bee97557a4d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/homogeneous-aggr.c +@@ -0,0 +1,25 @@ ++/* { dg-do compile } */ ++/* { dg-additional-options "-O " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++typedef struct sf { float a; float b; float c;} SF; ++ ++__attribute__((__noinline__)) void ++hmg_f (SF a); ++ ++/* we should use registers for each item ++**call_hmg_f: ++** ... ++** fmov s0, 1.0e\+0 ++** fmov s1, 2.0e\+0 ++** fmov s2, 3.0e\+0 ++** bl _hmg_f ++** ... ++*/ ++ ++void ++call_hmg_f (void) ++{ ++ SF A = { 1.0F, 2.0F, 3.0F }; ++ hmg_f (A); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/k+r-00.c b/gcc/testsuite/gcc.target/aarch64/darwin/k+r-00.c +new file mode 100644 +index 00000000000..443fb968811 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/k+r-00.c +@@ -0,0 +1,28 @@ ++/* { dg-do compile } */ ++ ++/* { dg-options "-std=gnu99 " } */ ++/* { dg-additional-options "-O2 -fsection-anchors" } */ ++ ++ ++/* What we care about here is that we get int loads from sp, sp+4 and sp+8. ++ * This code will change when we implement darwinpcs d.3 - since the ++ * promotions will no longer be needed (although they are harmless). ++**test_k_r00: ++** ldrsb w[0-9]+, \[sp, 4\] ++** ldr x[0-9]+, \[sp, 8\] ++** ... ++** ldrsb w[0-9]+, \[sp\] ++** ... ++*/ ++ ++const char * ++test_k_r00 (r0, r1, r2, r3, r4, r5, r6, r7, a, b, c) ++ char r0, r1, r2, r3, r4, r5, r6, r7; ++ char a; ++ char b; ++ const char *c; ++{ ++ if (a > 10 && b < 100) ++ return c; ++ return (char *)0; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/tu-accesses-0.c b/gcc/testsuite/gcc.target/aarch64/darwin/tu-accesses-0.c +new file mode 100644 +index 00000000000..ba5cc493bc9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/tu-accesses-0.c +@@ -0,0 +1,82 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O -fcommon -mno-pc-relative-literal-loads" } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++/* This checks that we perform the correct accesses for file-scope vars ++ including GOT indirections. */ ++ ++double gd = 1.0; ++ ++__attribute__((__weak__)) ++double wd = 2.0; ++ ++__attribute__((__visibility__("hidden"))) ++double hd = 3.0; ++ ++__attribute__((__weak__, __visibility__("hidden"))) ++double whd = 4.0; ++ ++extern double ed; ++ ++double cd; ++ ++static double sd = 5.0; ++ ++struct { ++ double a; ++ double b; ++} two_dbls = { 1.0, 42.0 }; ++ ++double arr[3] = { 6.0, 7.0, 8.0 }; ++ ++/* ++**test: ++** adrp x[0-9]+, _gd@PAGE ++** ldr d[0-9]+, \[x[0-9]+, #_gd@PAGEOFF\] ++** adrp x[0-9]+, lC0@PAGE ++** ldr d[0-9]+, \[x[0-9]+, #lC0@PAGEOFF\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _wd@GOTPAGE ++** ldr x[0-9]+, \[x[0-9]+, _wd@GOTPAGEOFF\] ++** ldr d[0-9]+, \[x[0-9]+\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _hd@PAGE ++** ldr d[0-9]+, \[x[0-9]+, #_hd@PAGEOFF\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _whd@PAGE ++** ldr d[0-9]+, \[x[0-9]+, #_whd@PAGEOFF\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _ed@GOTPAGE ++** ldr x[0-9]+, \[x[0-9]+, _ed@GOTPAGEOFF\] ++** ldr d[0-9]+, \[x[0-9]+\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _cd@GOTPAGE ++** ldr x[0-9]+, \[x[0-9]+, _cd@GOTPAGEOFF\] ++** ldr d[0-9]+, \[x[0-9]+\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** fmov d[0-9]+, 5.0e\+0 ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _two_dbls@PAGE\+8 ++** ldr d[0-9]+, \[x[0-9]+, #_two_dbls@PAGEOFF\+8\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** adrp x[0-9]+, _arr@PAGE\+16 ++** ldr d[0-9]+, \[x[0-9]+, #_arr@PAGEOFF\+16\] ++** fadd d[0-9]+, d[0-9]+, d[0-9]+ ++** ret ++*/ ++ ++double test (void) ++{ ++ double x = 123456123456123456.0; ++ x += gd; ++ x += wd; ++ x += hd; ++ x += whd; ++ x += ed; ++ x += cd; ++ x += sd; ++ x += two_dbls.b; ++ x += arr[2]; ++ ++ return x; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/variadic-00.c b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-00.c +new file mode 100644 +index 00000000000..6420fca11d5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-00.c +@@ -0,0 +1,91 @@ ++/* { dg-do compile } */ ++ ++/* We use the sections anchors to make the code easier to match. */ ++/* { dg-additional-options " -O -fsection-anchors -fno-schedule-insns -fno-schedule-insns2 " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++#include ++ ++/* What we care about here is that the load of w0 is from the incoming [SP] ++**fooi: ++** sub sp, sp, #16 ++** add x[0-9]+, sp, 24 ++** str x[0-9]+, \[sp, 8\] ++** ldr w0, \[sp, 16\] ++** ... ++*/ ++ ++__attribute__((__noinline__)) int ++fooi (int a, ...) ++{ ++ int x; ++ va_list ap; ++ va_start(ap, a); ++ x = va_arg(ap, int); ++ va_end(ap); ++ return x; ++} ++ ++__attribute__((__noinline__)) int ++fooo (char a, ...); ++ ++/* ++**call_foo: ++** ... ++** mov w[0-9]+, 42 ++** str w[0-9]+, \[sp\] ++** mov w0, 1 ++** bl _fooo ++** ... ++*/ ++ ++__attribute__((__noinline__)) int ++call_foo (void) ++{ ++ int y = fooo (1, 42); ++ return y; ++} ++ ++/* What we care about here is that the load of w0 is from the incoming [SP+8] ++**bari: ++** sub sp, sp, #16 ++** add x[0-9]+, sp, 32 ++** str x[0-9]+, \[sp, 8\] ++** ldr w0, \[sp, 24\] ++** ... ++*/ ++ ++__attribute__((__noinline__)) int ++bari (int a, int b, int c, int d, int e, int f, int g, int h, ++ int i, ...) ++{ ++ int x; ++ va_list ap; ++ va_start(ap, i); ++ x = va_arg(ap, int); ++ va_end(ap); ++ return x; ++} ++ ++/* ++**call_bar: ++** ... ++** mov w[0-9]+, 42 ++** str w[0-9]+, \[sp, 8\] ++** mov w[0-9]+, 9 ++** str w[0-9]+, \[sp\] ++** ... ++ bl _baro ++** ... ++*/ ++ ++__attribute__((__noinline__)) int ++baro (int a, int b, int c, int d, int e, int f, int g, int h, ++ int i, ...); ++ ++__attribute__((__noinline__)) int ++call_bar (void) ++{ ++ int y = baro (1, 2, 3, 4, 5, 6, 7, 8, 9, 42); ++ return y; ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/variadic-01.c b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-01.c +new file mode 100644 +index 00000000000..c055aeae580 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-01.c +@@ -0,0 +1,102 @@ ++/* { dg-do compile } */ ++ ++/* we need this for _Float128. */ ++/* { dg-options "-std=gnu99 " } */ ++/* We use the sections anchors to make the code easier to match. */ ++/* { dg-additional-options " -O2 -fsection-anchors " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++#include ++ ++/* What we care about here is that q0 and q1 are loaded from incoming sp and ++ sp+16. ++**foo: ++** ... ++** ldr q1, \[sp, 32\] ++** ldr q0, \[sp, 48\] ++** ... ++** bl ___addtf3 ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++foo (int n, ...) ++{ ++ _Float128 a, b; ++ va_list ap; ++ ++ va_start(ap, n); ++ a = va_arg(ap, _Float128); ++ b = va_arg(ap, _Float128); ++ va_end(ap); ++ return a + b; ++} ++ ++/* ++**call_foo: ++** ... ++** str q[0-9]+, \[sp, 16\] ++** ... ++** mov w0, 2 ++** str q[0-9]+, \[sp\] ++** bl _foo ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++call_foo (void) ++{ ++ return foo (2, (_Float128)1.0, (_Float128)2.0); ++} ++ ++/* What we care about here is that q0 and q1 are loaded from incoming sp and ++ sp+32 (with the int at sp+16). ++**bar: ++** ... ++** ldr w[0-9]+, \[x[0-9]+, 16\] ++** ldr q0, \[x[0-9]+\] ++** ... ++** ldr q1, \[x[0-9]+, 32\] ++** bl ___addtf3 ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++bar (int n, ...) ++{ ++ _Float128 a, b; ++ va_list ap; ++ ++ va_start(ap, n); ++ a = va_arg(ap, _Float128); ++ n = va_arg(ap, int); ++ if (n != 42) ++ __builtin_abort (); ++ b = va_arg(ap, _Float128); ++ va_end(ap); ++ return a + b; ++} ++ ++/* ++**call_bar: ++** ... ++** str q[0-9]+, \[sp, 32\] ++** ... ++** mov w[0-9]+, 42 ++** str w[0-9]+, \[sp, 16\] ++** mov w0, 2 ++** str q[0-9]+, \[sp\] ++** bl _bar ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++_Float128 ++call_bar (void) ++{ ++ return bar (2, (_Float128)1.0, ++ 42, (_Float128)2.0); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/darwin/variadic-02.c b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-02.c +new file mode 100644 +index 00000000000..9d796bfc07f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/darwin/variadic-02.c +@@ -0,0 +1,104 @@ ++/* { dg-do compile } */ ++ ++/* we need this for __int128. */ ++/* { dg-options "-std=gnu99 " } */ ++/* We use the sections anchors to make the code easier to match. */ ++/* { dg-additional-options " -O2 -fsection-anchors " } */ ++/* { dg-final { check-function-bodies "**" "" "" { target *-*-darwin* } } } */ ++ ++#include ++ ++/* What we care about here is that we load the values from incoming sp and ++ sp + 16. ++**foo: ++** sub sp, sp, #16 ++** ... ++** ldp x[0-9]+, x[0-9]+, \[sp, 16\] ++** ... ++** ldr x[0-9]+, \[sp, 32\] ++** ldr x[0-9]+, \[sp, 40\] ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++__int128 ++foo (int n, ...) ++{ ++ __int128 a, b; ++ va_list ap; ++ ++ va_start(ap, n); ++ a = va_arg(ap, __int128); ++ b = va_arg(ap, __int128); ++ va_end(ap); ++ return a + b; ++} ++ ++/* ++**call_foo: ++** ... ++** stp x[0-9]+, x[0-9]+, \[sp\] ++** mov w0, 2 ++** stp x[0-9]+, x[0-9]+, \[sp, 16\] ++** bl _foo ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++__int128 ++call_foo (void) ++{ ++ return foo (2, (__int128)1, (__int128)2); ++} ++ ++ ++/* sp = one int128, sp+16 = int sp + 32 = other int128 ++**bar: ++** ... ++** sub sp, sp, #16 ++** ... ++** ldp x[0-9]+, x[0-9]+, \[sp, 16\] ++** ... ++** ldr x[0-9]+, \[sp, 48\] ++** ldr x[0-9]+, \[sp, 56\] ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++__int128 ++bar (int n, ...) ++{ ++ __int128 a, b; ++ va_list ap; ++ ++ va_start(ap, n); ++ a = va_arg(ap, __int128); ++ n = va_arg(ap, int); ++ b = va_arg(ap, __int128); ++ va_end(ap); ++ return a + b; ++} ++ ++__attribute__((__noinline__)) ++__int128 ++baro (int n, ...); ++ ++/* ++**call_bar: ++** ... ++** mov w[0-9]+, 42 ++** ... ++** mov w0, 2 ++** stp x[0-9]+, x[0-9]+, \[sp\] ++** str w[0-9]+, \[sp, 16\] ++** stp x[0-9]+, x[0-9]+, \[sp, 32\] ++** bl _baro ++** ... ++*/ ++ ++__attribute__((__noinline__)) ++__int128 ++call_bar (void) ++{ ++ return baro (2, (__int128)1, 42, (__int128)2); ++} +diff --git a/gcc/testsuite/gcc.target/aarch64/dbl_mov_immediate_1.c b/gcc/testsuite/gcc.target/aarch64/dbl_mov_immediate_1.c +index ba6a230457b..cc30dd546f4 100644 +--- a/gcc/testsuite/gcc.target/aarch64/dbl_mov_immediate_1.c ++++ b/gcc/testsuite/gcc.target/aarch64/dbl_mov_immediate_1.c +@@ -41,8 +41,10 @@ double d4(void) + + /* { dg-final { scan-assembler-times "movi\td\[0-9\]+, #?0" 1 } } */ + +-/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, \.LC\[0-9\]" 2 } } */ +-/* { dg-final { scan-assembler-times "ldr\td\[0-9\]+, \\\[x\[0-9\], #:lo12:\.LC\[0-9\]\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, \.LC\[0-9\]" 2 { target { ! *-*-darwin* } } } } */ ++/* { dg-final { scan-assembler-times "ldr\td\[0-9\]+, \\\[x\[0-9\], #:lo12:\.LC\[0-9\]\\\]" 2 { target { ! *-*-darwin* } } } } */ ++/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, lC\[0-9\]@PAGE" 2 { target *-*-darwin* } } } */ ++/* { dg-final { scan-assembler-times "ldr\td\[0-9\]+, \\\[x\[0-9\], #lC\[0-9\]@PAGEOFF\\\]" 2 { target *-*-darwin* } } } */ + + /* { dg-final { scan-assembler-times "fmov\td\[0-9\]+, 1\\\.5e\\\+0" 1 } } */ + +diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c b/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c +index ae5b3797021..8a691add222 100644 +--- a/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c ++++ b/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c +@@ -1,5 +1,6 @@ + /* Verify that CFA register is restored to SP after FP is restored. */ + /* { dg-do compile } */ ++/* { dg-skip-if "no cfi insn support yet" *-*-darwin* } */ + /* { dg-options "-O0 -gdwarf-2" } */ + /* { dg-final { scan-assembler ".cfi_restore 30" } } */ + /* { dg-final { scan-assembler ".cfi_restore 29" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c +index 478875ff874..9a2b2e44893 100644 +--- a/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c ++++ b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c +@@ -15,4 +15,4 @@ TEST (fllf, float , long long, l) + + /* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */ + /* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */ +-/* { dg-final { scan-assembler-not "bl" } } */ ++/* { dg-final { scan-assembler-not "bl\t" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_13.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_13.c +index 9cc3942f153..52c90a92114 100644 +--- a/gcc/testsuite/gcc.target/aarch64/ldp_stp_13.c ++++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_13.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-require-effective-target arm_mabi_ilp32 } */ + /* { dg-options "-O2 -mabi=ilp32" } */ + + long long +diff --git a/gcc/testsuite/gcc.target/aarch64/memset-corner-cases-2.c b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases-2.c +index 9ee96f33255..dec73f98506 100644 +--- a/gcc/testsuite/gcc.target/aarch64/memset-corner-cases-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases-2.c +@@ -7,7 +7,7 @@ + /* 127 bytes should use libcall for size. + **set127byte: + ** mov x2, 127 +-** b memset ++** b _?memset + */ + void __attribute__((__noinline__)) + set127byte (int64_t *src, int c) +@@ -18,7 +18,7 @@ set127byte (int64_t *src, int c) + /* 128 bytes should use libcall for size. + **set128byte: + ** mov x2, 128 +-** b memset ++** b _?memset + */ + void __attribute__((__noinline__)) + set128byte (int64_t *src, int c) +diff --git a/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c +index c43f0199adc..733a11e585a 100644 +--- a/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c ++++ b/gcc/testsuite/gcc.target/aarch64/memset-corner-cases.c +@@ -77,7 +77,7 @@ set256byte (int64_t *src, char c) + **set257byte: + ** mov x2, 257 + ** mov w1, 99 +-** b memset ++** b _?memset + */ + void __attribute__((__noinline__)) + set257byte (int64_t *src) +diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c +index d5e9200562c..7f504ad687f 100644 +--- a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c ++++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c +@@ -14,6 +14,6 @@ TEST (dlld, double, long long, l) + TEST (fllf, float , long long, l) + + /* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */ +-/* { dg-final { scan-assembler-times "bl\tlrint" 4 } } */ +-/* { dg-final { scan-assembler-times "bl\tllrint" 2 } } */ ++/* { dg-final { scan-assembler-times "bl\t_*lrint" 4 } } */ ++/* { dg-final { scan-assembler-times "bl\t_*llrint" 2 } } */ + /* { dg-final { scan-assembler-not "fcvtzs" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/pr100518.c b/gcc/testsuite/gcc.target/aarch64/pr100518.c +index 5ca599f5d2e..4e7d6bc7d90 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr100518.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr100518.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-require-effective-target arm_mabi_ilp32 } */ + /* { dg-options "-mabi=ilp32 -mstrict-align -O2" } */ + + int unsigned_range_min, unsigned_range_max, a11___trans_tmp_1; +diff --git a/gcc/testsuite/gcc.target/aarch64/pr62308.c b/gcc/testsuite/gcc.target/aarch64/pr62308.c +index 1cf6e212dca..4c1a733e84d 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr62308.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr62308.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "Darwin platforms do not support big-endian arm64" *-*-darwin* } */ + /* { dg-options "-mbig-endian" } */ + + typedef int __attribute__((vector_size(16))) v4si; +diff --git a/gcc/testsuite/gcc.target/aarch64/pr78255.c b/gcc/testsuite/gcc.target/aarch64/pr78255.c +index b078cf3e1c1..fc5d859ee68 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr78255.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr78255.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "Darwin platforms do not support tiny" *-*-darwin* } */ + /* { dg-options "-O2 -mcmodel=tiny" } */ + + extern int bar (void *); +diff --git a/gcc/testsuite/gcc.target/aarch64/pr78561.c b/gcc/testsuite/gcc.target/aarch64/pr78561.c +index 048d2d7969f..635214edde1 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr78561.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr78561.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "Darwin platforms do not support tiny" *-*-darwin* } */ + /* { dg-options "-Og -O3 -mcmodel=tiny" } */ + + int +diff --git a/gcc/testsuite/gcc.target/aarch64/pr80295.c b/gcc/testsuite/gcc.target/aarch64/pr80295.c +index b3866d8d6a9..7a7f127b65f 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr80295.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr80295.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-require-effective-target arm_mabi_ilp32 } */ + /* { dg-options "-mabi=ilp32" } */ + + void f (void *b) +diff --git a/gcc/testsuite/gcc.target/aarch64/pr87305.c b/gcc/testsuite/gcc.target/aarch64/pr87305.c +index 8beaa9176e0..c3f98e8eaec 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr87305.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr87305.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "Darwin platforms do not support big-endian arm64" *-*-darwin* } */ + /* { dg-options "-Ofast -mbig-endian -w" } */ + + int cc; +diff --git a/gcc/testsuite/gcc.target/aarch64/pr92424-1.c b/gcc/testsuite/gcc.target/aarch64/pr92424-1.c +index c413a2c306e..59f7435dc83 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr92424-1.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr92424-1.c +@@ -1,6 +1,7 @@ + /* { dg-do "compile" } */ + /* { dg-options "-O1" } */ + /* { dg-final { check-function-bodies "**" "" } } */ ++/* { dg-skip-if "unimplemented patchable function entry" *-*-darwin* } */ + + /* Note: this test only checks the instructions in the function bodies, + not the placement of the patch label or nops before the futncion. */ +diff --git a/gcc/testsuite/gcc.target/aarch64/pr94201.c b/gcc/testsuite/gcc.target/aarch64/pr94201.c +index 69176169186..051c742e98e 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr94201.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr94201.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-require-effective-target arm_mabi_ilp32 } */ + /* { dg-options "-mcmodel=tiny -mabi=ilp32 -fPIC" } */ + + extern int bar (void *); +diff --git a/gcc/testsuite/gcc.target/aarch64/pr94577.c b/gcc/testsuite/gcc.target/aarch64/pr94577.c +index 6f2d3612c26..6a52e52dc39 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr94577.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr94577.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-require-effective-target arm_mabi_ilp32 } */ + /* { dg-options "-mcmodel=large -mabi=ilp32" } */ + + void +diff --git a/gcc/testsuite/gcc.target/aarch64/pr97535.c b/gcc/testsuite/gcc.target/aarch64/pr97535.c +index 7d4db485f1f..6f1ee8035eb 100644 +--- a/gcc/testsuite/gcc.target/aarch64/pr97535.c ++++ b/gcc/testsuite/gcc.target/aarch64/pr97535.c +@@ -13,4 +13,4 @@ void setRaw(const void *raw) + + /* At any optimization level this should be a function call + and not inlined. */ +-/* { dg-final { scan-assembler "bl\tmemcpy" } } */ ++/* { dg-final { scan-assembler "bl\t_*memcpy" } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c +index 8eec6824f37..193c65717ed 100644 +--- a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c +@@ -1,5 +1,6 @@ + /* { dg-do compile } */ + /* { dg-options "-Ofast" } */ ++/* { dg-skip-if "no system variant_pcs support" *-*-darwin* } */ + + __attribute__ ((__simd__ ("notinbranch"))) + __attribute__ ((__nothrow__ , __leaf__ , __const__)) +@@ -12,5 +13,5 @@ void bar(double * f, int n) + f[i] = foo(f[i]); + } + +-/* { dg-final { scan-assembler-not {\.variant_pcs\tfoo} } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_foo} 1 } } */ ++/* { dg-final { scan-assembler-not {\.variant_pcs\t_?foo} } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnN2v_foo} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c +index 95f6a6803e8..6fd57735b3a 100644 +--- a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c ++++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c +@@ -1,5 +1,6 @@ + /* { dg-do compile } */ + /* { dg-options "-Ofast" } */ ++/* { dg-skip-if "no system variant_pcs support" *-*-darwin* } */ + + __attribute__ ((__simd__)) + __attribute__ ((__nothrow__ , __leaf__ , __const__)) +@@ -17,8 +18,8 @@ double foo(double x) + return x * x / 3.0; + } + +-/* { dg-final { scan-assembler-not {\.variant_pcs\tfoo} } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnM1v_foo} 1 } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnM2v_foo} 1 } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN1v_foo} 1 } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_foo} 1 } } */ ++/* { dg-final { scan-assembler-not {\.variant_pcs\t_?foo} } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnM1v_foo} 1 } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnM2v_foo} 1 } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnN1v_foo} 1 } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnN2v_foo} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c +index eddcef3597c..62ee482a892 100644 +--- a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c ++++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c +@@ -1,5 +1,6 @@ + /* { dg-do compile } */ + /* { dg-options "-Ofast" } */ ++/* { dg-skip-if "no system variant_pcs support" *-*-darwin* } */ + + __attribute__ ((__simd__ ("notinbranch"))) + __attribute__ ((__nothrow__ , __leaf__ , __const__)) +@@ -12,5 +13,5 @@ void foo(double *f, int n) + f[i] = log(f[i]); + } + +-/* { dg-final { scan-assembler-not {\.variant_pcs\tlog} } } */ +-/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_log} 1 } } */ ++/* { dg-final { scan-assembler-not {\.variant_pcs\t_?log} } } */ ++/* { dg-final { scan-assembler-times {\.variant_pcs\t_?_ZGVnN2v_log} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-1.c b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-1.c +index 6885894a97e..ebba23c9d02 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-1.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-1.c +@@ -1,6 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -funwind-tables" } */ + /* { dg-require-effective-target supports_stack_clash_protection } */ ++/* { dg-skip-if "no cfi insn support yet" *-*-darwin* } */ + + #define SIZE 128*1024 + #include "stack-check-prologue.h" +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-2.c b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-2.c +index 5796a53be06..e15fbd6196c 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-2.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-2.c +@@ -1,6 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -funwind-tables" } */ + /* { dg-require-effective-target supports_stack_clash_protection } */ ++/* { dg-skip-if "no cfi insn support yet" *-*-darwin* } */ + + #define SIZE 1280*1024 + 512 + #include "stack-check-prologue.h" +diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-3.c b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-3.c +index c4b7bb601c4..ccaf2e6f8cf 100644 +--- a/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-3.c ++++ b/gcc/testsuite/gcc.target/aarch64/stack-check-cfa-3.c +@@ -1,6 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-O3 -fopenmp-simd -march=armv8-a+sve -fstack-clash-protection --param stack-clash-protection-guard-size=16 -funwind-tables" } */ + /* { dg-require-effective-target supports_stack_clash_protection } */ ++/* { dg-skip-if "no cfi insn support yet" *-*-darwin* } */ + + #include "stack-check-prologue-16.c" + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/aarch64-sve.exp b/gcc/testsuite/gcc.target/aarch64/sve/aarch64-sve.exp +index 71dd6687c6b..7a62814edbb 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve/aarch64-sve.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve/aarch64-sve.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } then { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp b/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp +index a271f1793f4..2da5720d1f3 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle-asm.exp +@@ -24,6 +24,11 @@ if {![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle.exp b/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle.exp +index ce71c9c1fd4..c7bd136f202 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/aarch64-sve-acle.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pcs/aarch64-sve-pcs.exp b/gcc/testsuite/gcc.target/aarch64/sve/pcs/aarch64-sve-pcs.exp +index 83786733f35..9ab68902def 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve/pcs/aarch64-sve-pcs.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve/pcs/aarch64-sve-pcs.exp +@@ -25,6 +25,10 @@ if {![istarget aarch64*-*-*] } then { + return + } + ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp b/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp +index 60652dbf8fb..010e32132cb 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve2/aarch64-sve2.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } then { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp b/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp +index e08cd612190..a7e5f364770 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle-asm.exp +@@ -24,6 +24,11 @@ if {![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle.exp b/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle.exp +index f0255967c9d..82092e337f6 100644 +--- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle.exp ++++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/aarch64-sve2-acle.exp +@@ -25,6 +25,11 @@ if {![istarget aarch64*-*-*] } { + return + } + ++# Darwin doesn't support sve ++if { [istarget *-*-darwin*] } then { ++ return ++} ++ + # Load support procs. + load_lib gcc-dg.exp + +diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c +index fc6a4f3ec78..2d9e94bc625 100644 +--- a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c ++++ b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c +@@ -1,4 +1,5 @@ + /* { dg-do link } */ ++/* { dg-skip-if "no mcmodel tiny" *-*-darwin* } */ + /* { dg-options "-O3 -save-temps -mcmodel=tiny" } */ + + char fixed_regs[0x00080000]; +diff --git a/gcc/testsuite/gcc.target/aarch64/uaddw-3.c b/gcc/testsuite/gcc.target/aarch64/uaddw-3.c +index 39cbd6b6cc2..b4ed187bd2c 100644 +--- a/gcc/testsuite/gcc.target/aarch64/uaddw-3.c ++++ b/gcc/testsuite/gcc.target/aarch64/uaddw-3.c +@@ -1,10 +1,11 @@ + /* { dg-do compile } */ + /* { dg-options "-O3" } */ ++/* { dg-additional-options "-fno-signed-char" { target *-*-darwin* } } */ + + #pragma GCC target "+nosve" + + int +-t6(int len, void * dummy, char * __restrict x) ++t6(int len, void * dummy, unsigned char * __restrict x) + { + len = len & ~31; + unsigned short result = 0; +diff --git a/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c b/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c +index d025e989a1e..f218504c719 100644 +--- a/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c ++++ b/gcc/testsuite/gcc.target/aarch64/vect-cse-codegen.c +@@ -6,8 +6,8 @@ + + /* + **test1: +-** adrp x[0-9]+, .LC[0-9]+ +-** ldr q[0-9]+, \[x[0-9]+, #:lo12:.LC[0-9]+\] ++** adrp x[0-9]+, (.LC[0-9]+|lC[0-9]+@PAGE) ++** ldr q[0-9]+, \[x[0-9]+, #(:lo12:.LC[0-9]+|lC[0-9]+@PAGEOFF)\] + ** add v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d + ** str q[0-9]+, \[x[0-9]+\] + ** fmov x[0-9]+, d[0-9]+ +@@ -27,13 +27,14 @@ test1 (uint64_t a, uint64x2_t b, uint64x2_t* rt) + + /* + **test2: +-** adrp x[0-9]+, .LC[0-1]+ +-** ldr q[0-9]+, \[x[0-9]+, #:lo12:.LC[0-9]+\] ++** adrp x[0-9]+, (.LC[0-1]+|lC[0-1]+@PAGE) ++** ldr q[0-9]+, \[x[0-9]+, #(:lo12:.LC[0-9]+|lC[0-9]+@PAGEOFF)\] + ** add v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d + ** str q[0-9]+, \[x[0-9]+\] + ** fmov x[0-9]+, d[0-9]+ + ** orr x[0-9]+, x[0-9]+, x[0-9]+ + ** ret ++ + */ + + uint64_t +@@ -48,8 +49,8 @@ test2 (uint64_t a, uint64x2_t b, uint64x2_t* rt) + + /* + **test3: +-** adrp x[0-9]+, .LC[0-9]+ +-** ldr q[0-9]+, \[x[0-9]+, #:lo12:.LC[0-9]+\] ++** adrp x[0-9]+, (.LC[0-9]+|lC[0-9]+@PAGE) ++** ldr q[0-9]+, \[x[0-9]+, #(:lo12:.LC[0-9]+|lC[0-9]+@PAGEOFF)\] + ** add v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s + ** str q[0-9]+, \[x1\] + ** fmov w[0-9]+, s[0-9]+ +diff --git a/gcc/testsuite/gfortran.dg/coarray/caf.exp b/gcc/testsuite/gfortran.dg/coarray/caf.exp +index 8683a2ab435..e76cb69dcd9 100644 +--- a/gcc/testsuite/gfortran.dg/coarray/caf.exp ++++ b/gcc/testsuite/gfortran.dg/coarray/caf.exp +@@ -28,6 +28,7 @@ + + # Load procedures from common libraries. + load_lib gfortran-dg.exp ++load_lib atomic-dg.exp + + # If a testcase doesn't have special options, use these. + global DEFAULT_FFLAGS +@@ -47,6 +48,7 @@ global gfortran_test_path + global gfortran_aux_module_flags + set gfortran_test_path $srcdir/$subdir + set gfortran_aux_module_flags $DEFAULT_FFLAGS ++ + proc dg-compile-aux-modules { args } { + global gfortran_test_path + global gfortran_aux_module_flags +@@ -69,9 +71,21 @@ proc dg-compile-aux-modules { args } { + } + + # Add -latomic only where supported. Assume built-in support elsewhere. +-set maybe_atomic_lib "" + if [check_effective_target_libatomic_available] { +- set maybe_atomic_lib "-latomic" ++ #set maybe_atomic_lib "-latomic" ++ if ![is_remote host] { ++ if [info exists TOOL_OPTIONS] { ++ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" ++ } else { ++ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]" ++ } ++ } else { ++ set maybe_atomic_lib "" ++ } ++ set t [get_multilibs] ++ puts "maybe al $maybe_atomic_lib ml $t" ++} else { ++ set maybe_atomic_lib "" + } + + # Main loop. +diff --git a/gcc/testsuite/gfortran.dg/dg.exp b/gcc/testsuite/gfortran.dg/dg.exp +index bd7ad95ad0d..36fc2972b2e 100644 +--- a/gcc/testsuite/gfortran.dg/dg.exp ++++ b/gcc/testsuite/gfortran.dg/dg.exp +@@ -18,6 +18,7 @@ + + # Load support procs. + load_lib gfortran-dg.exp ++load_lib atomic-dg.exp + + # If a testcase doesn't have special options, use these. + global DEFAULT_FFLAGS +@@ -53,12 +54,30 @@ proc dg-compile-aux-modules { args } { + } + } + ++# coarray tests might need libatomic. Assume that it is either not needed or ++# provided by builtins if it's not available. ++if [check_effective_target_libatomic_available] { ++ if ![is_remote host] { ++ if [info exists TOOL_OPTIONS] { ++ set maybe_atomic_lib "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" ++ } else { ++ set maybe_atomic_lib "[atomic_link_flags [get_multilibs]]" ++ } ++ } else { ++ set maybe_atomic_lib "" ++ } ++ set t [get_multilibs] ++ puts "dg set al $maybe_atomic_lib ml $t" ++} ++ ++puts "DEFAULT_FFLAGS $DEFAULT_FFLAGS" ++ + # Main loop. + gfortran-dg-runtest [lsort \ +- [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS ++ [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] $maybe_atomic_lib $DEFAULT_FFLAGS + + gfortran-dg-runtest [lsort \ +- [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $DEFAULT_FFLAGS ++ [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] $maybe_atomic_lib $DEFAULT_FFLAGS + + + # All done. +diff --git a/gcc/testsuite/gfortran.dg/pr95690.f90 b/gcc/testsuite/gfortran.dg/pr95690.f90 +index 47a5df9e894..1afa9d3c467 100644 +--- a/gcc/testsuite/gfortran.dg/pr95690.f90 ++++ b/gcc/testsuite/gfortran.dg/pr95690.f90 +@@ -2,8 +2,8 @@ + module m + contains + subroutine s +- print *, (erfc) ! { dg-error "not a floating constant" "" { target i?86-*-* x86_64-*-* sparc*-*-* cris-*-* } } +- end ! { dg-error "not a floating constant" "" { target { ! "i?86-*-* x86_64-*-* sparc*-*-* cris-*-*" } } } ++ print *, (erfc) ! { dg-error "not a floating constant" "" { target i?86-*-* x86_64-*-* sparc*-*-* cris-*-* aarch64-apple-darwin* } } ++ end ! { dg-error "not a floating constant" "" { target { ! "i?86-*-* x86_64-*-* sparc*-*-* cris-*-* aarch64-apple-darwin*" } } } + function erfc() + end + end +diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp +index 7e0f85dc9b0..88c6ece8caa 100644 +--- a/gcc/testsuite/lib/asan-dg.exp ++++ b/gcc/testsuite/lib/asan-dg.exp +@@ -78,7 +78,7 @@ proc asan_link_flags_1 { paths lib } { + || [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ " + append flags " -B${gccpath}/libsanitizer/${lib}/ " +- append flags " -L${gccpath}/libsanitizer/${lib}/.libs " ++ append flags " -B${gccpath}/libsanitizer/${lib}/.libs " + append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs" + } + } else { +diff --git a/gcc/testsuite/lib/atomic-dg.exp b/gcc/testsuite/lib/atomic-dg.exp +index 86dcfa674ea..c9244fb6cac 100644 +--- a/gcc/testsuite/lib/atomic-dg.exp ++++ b/gcc/testsuite/lib/atomic-dg.exp +@@ -33,7 +33,7 @@ proc atomic_link_flags { paths } { + if { [file exists "${gccpath}/libatomic/.libs/libatomic.a"] + || [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] } { + append flags " -B${gccpath}/libatomic/ " +- append flags " -L${gccpath}/libatomic/.libs" ++ append flags " -B${gccpath}/libatomic/.libs" + append ld_library_path ":${gccpath}/libatomic/.libs" + } + } else { +diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp +index a80630bb2a8..195611f1f72 100644 +--- a/gcc/testsuite/lib/scanasm.exp ++++ b/gcc/testsuite/lib/scanasm.exp +@@ -763,7 +763,7 @@ proc scan-lto-assembler { args } { + # to function bodies in array RESULT. FILENAME has already been uploaded + # locally where necessary and is known to exist. + +-proc parse_function_bodies { filename result } { ++proc parse_ELF_function_bodies { filename result } { + upvar $result up_result + + # Regexp for the start of a function definition (name in \1). +@@ -793,6 +793,44 @@ proc parse_function_bodies { filename result } { + close $fd + } + ++proc parse_MACHO_function_bodies { filename result } { ++ upvar $result up_result ++ ++ # Regexp for the start of a function definition (name in \1). ++ set label {^(_[a-zA-Z_]\S+):$} ++ set start {^LFB[0-9]+} ++ ++ # Regexp for the end of a function definition. ++ set terminator {^LFE[0-9]+} ++ ++ # Regexp for lines that aren't interesting. ++ set fluff {^\s*(?:\.|//|@)} ++ set fluff3 {^L[0-9ACESV]} ++ ++ set fd [open $filename r] ++ set in_function 0 ++ while { [gets $fd line] >= 0 } { ++ if { !$in_function && [regexp $label $line dummy function_name] } { ++ set in_function 1 ++ set function_body "" ++ } elseif { $in_function == 1 } { ++ if { [regexp $start $line] } { ++ set in_function 2 ++ } else { ++ set in_function 0 ++ } ++ } elseif { $in_function == 2 } { ++ if { [regexp $terminator $line] } { ++ set up_result($function_name) $function_body ++ set in_function 0 ++ } elseif { ![regexp $fluff $line] && ![regexp $fluff3 $line] } { ++ append function_body $line "\n" ++ } ++ } ++ } ++ close $fd ++} ++ + # FUNCTIONS is an array that maps function names to function bodies. + # Return true if it contains a definition of function NAME and if + # that definition matches BODY_REGEXP. +@@ -820,6 +858,14 @@ proc check-function-bodies { args } { + error "too many arguments to check-function-bodies" + } + ++ set isELF 1 ++ # some targets have a __USER_LABEL_PREFIX__ ++ set needsULP 0 ++ if { [istarget *-*-darwin*] } { ++ set isELF 0 ++ set needsULP 1 ++ } ++ + if { [llength $args] >= 3 } { + set required_flags [lindex $args 2] + +@@ -876,7 +922,11 @@ proc check-function-bodies { args } { + remote_upload host "$filename" + } + if { [file exists $output_filename] } { +- parse_function_bodies $output_filename functions ++ if { $isELF } { ++ parse_ELF_function_bodies $output_filename functions ++ } else { ++ parse_MACHO_function_bodies $output_filename functions ++ } + set have_bodies 1 + } else { + verbose -log "$testcase: output file does not exist" +@@ -921,6 +971,9 @@ proc check-function-bodies { args } { + if { $xfail_all || [string equal $selector "F"] } { + setup_xfail "*-*-*" + } ++ if { $needsULP } { ++ set function_name "_$function_name" ++ } + set testname "$testcase check-function-bodies $function_name" + if { !$have_bodies } { + unresolved $testname +diff --git a/gcc/testsuite/lib/target-libpath.exp b/gcc/testsuite/lib/target-libpath.exp +index d09cd515d20..280ce390845 100644 +--- a/gcc/testsuite/lib/target-libpath.exp ++++ b/gcc/testsuite/lib/target-libpath.exp +@@ -67,6 +67,7 @@ proc set_ld_library_path_env_vars { } { + global orig_dyld_library_path + global orig_path + global orig_gcc_exec_prefix ++ global ENABLE_DARWIN_AT_RPATH + global env + + # Save the original GCC_EXEC_PREFIX. +@@ -133,6 +134,7 @@ proc set_ld_library_path_env_vars { } { + # + # Doing this is somewhat of a hack as ld_library_path gets repeated in + # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. ++ if { ![istarget *-*-darwin*] } { + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + } else { +@@ -166,11 +168,23 @@ proc set_ld_library_path_env_vars { } { + } else { + setenv LD_LIBRARY_PATH_64 "$ld_library_path" + } +- if { $orig_dyld_library_path_saved } { +- setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" +- } else { +- setenv DYLD_LIBRARY_PATH "$ld_library_path" + } ++ if { [istarget *-*-darwin*] } { ++ if { [info exists ENABLE_DARWIN_AT_RPATH] || [istarget *-*-darwin1\[5-9\]*] ++ || [istarget *-*-darwin2*] } { ++ # Either we are not using DYLD_LIBRARY_PATH or we're on a version of the ++ # OS for which it is not passed through system exes. ++ if [info exists env(DYLD_LIBRARY_PATH)] { ++ unsetenv DYLD_LIBRARY_PATH ++ } ++ } else { ++ if { $orig_dyld_library_path_saved } { ++ setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" ++ } else { ++ setenv DYLD_LIBRARY_PATH "$ld_library_path" ++ } ++ } ++ } + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + if { $orig_path_saved } { + setenv PATH "$ld_library_path:$orig_path" +@@ -179,6 +193,7 @@ proc set_ld_library_path_env_vars { } { + } + } + ++ verbose -log "set paths" + verbose -log "LD_LIBRARY_PATH=[getenv LD_LIBRARY_PATH]" + verbose -log "LD_RUN_PATH=[getenv LD_RUN_PATH]" + verbose -log "SHLIB_PATH=[getenv SHLIB_PATH]" +diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp +index 244fe2306f4..75581914d6c 100644 +--- a/gcc/testsuite/lib/target-supports.exp ++++ b/gcc/testsuite/lib/target-supports.exp +@@ -8485,7 +8485,7 @@ proc check_effective_target_section_anchors { } { + return [check_cached_effective_target section_anchors { + expr { [istarget powerpc*-*-*] + || [istarget arm*-*-*] +- || [istarget aarch64*-*-*] }}] ++ || ([istarget aarch64*-*-*] && ![istarget aarch64*-*-darwin*]) }}] + } + + # Return 1 if the target supports atomic operations on "int_128" values. +@@ -11526,6 +11526,15 @@ proc check_effective_target_arm_thumb2_ok_no_arm_v8_1_lob { } { + return 0 + } + ++# Return 1 if this is an ARM target where -mabi=ilp32 can be used. ++ ++proc check_effective_target_arm_mabi_ilp32 { } { ++ return [check_no_compiler_messages_nocache arm_mabi_ilp32 assembly { ++ int main() { return 0; } ++ } "-mabi=ilp32"] ++} ++ ++ + # Returns 1 if the target is using glibc, 0 otherwise. + + proc check_effective_target_glibc { } { +diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm +index 92852c3ecea..e0974539ecf 100644 +--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm ++++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-class-meta.mm +@@ -19,6 +19,7 @@ this behavior may be defined or documented (for example, if class + + /* { dg-do run } */ + /* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ ++/* { dg-skip-if "API unsupported" { arm64*-*-darwin* aarch64*-*-darwin* } { "-fnext-runtime" } { "" } } */ + /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + /* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */ + // { dg-additional-options "-Wno-objc-root-class" } +diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm +index f6e3d8d22e0..a23968a89b5 100644 +--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm ++++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm +@@ -6,6 +6,7 @@ + + /* { dg-do run } */ + /* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ ++/* { dg-skip-if "API unsupported" { arm64*-*-darwin* aarch64*-*-darwin* } { "-fnext-runtime" } { "" } } */ + /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + /* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */ + // { dg-additional-options "-Wno-objc-root-class" } +diff --git a/gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-4.mm b/gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-4.mm +index 1155db5f83f..e0dd8062373 100644 +--- a/gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-4.mm ++++ b/gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-4.mm +@@ -18,4 +18,4 @@ + + /* { dg-final { scan-assembler ".section __DATA, __cfstring" } } */ + /* { dg-final { scan-assembler ".long\t___CFConstantStringClassReference\n\t.long\t1992\n\t.long\t.*\n\t.long\t19\n" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t19\n" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t19\n} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm +index e1dad124cd6..eb89710d890 100644 +--- a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm ++++ b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm +@@ -33,4 +33,4 @@ @interface NSConstantString : NSSimpleCString + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._NSConstantString\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm +index 30a9228a64e..c1b58dc6cb8 100644 +--- a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm ++++ b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm +@@ -33,4 +33,4 @@ @interface XStr : XString { + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__XStrClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._XStr\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._XStr\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm +index a1a14295e90..8457f46be53 100644 +--- a/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm ++++ b/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm +@@ -25,4 +25,4 @@ @interface NSConstantString: NSObject { + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._NSConstantString\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m b/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m +index 6c1c76a87a3..41a48f9c685 100644 +--- a/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m ++++ b/gcc/testsuite/objc.dg/gnu-api-2-class-meta.m +@@ -19,6 +19,7 @@ this behavior may be defined or documented (for example, if class + + /* { dg-do run } */ + /* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ ++/* { dg-skip-if "API unsupported" { arm64*-*-darwin* aarch64*-*-darwin* } { "-fnext-runtime" } { "" } } */ + /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + /* { dg-additional-options "-Wno-objc-root-class" } */ + /* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */ +diff --git a/gcc/testsuite/objc.dg/gnu-api-2-class.m b/gcc/testsuite/objc.dg/gnu-api-2-class.m +index d11dae0e6dc..1386ebc2f99 100644 +--- a/gcc/testsuite/objc.dg/gnu-api-2-class.m ++++ b/gcc/testsuite/objc.dg/gnu-api-2-class.m +@@ -6,6 +6,7 @@ + + /* { dg-do run } */ + /* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ ++/* { dg-skip-if "API unsupported" { arm64*-*-darwin* aarch64*-*-darwin* } { "-fnext-runtime" } { "" } } */ + /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + /* { dg-additional-options "-Wno-objc-root-class" } */ + /* { dg-additional-options "-DOBJC_OLD_DISPATCH_PROTOTYPES" { target { *-*-darwin* } } } */ +diff --git a/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m +index 1155db5f83f..e0dd8062373 100644 +--- a/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m ++++ b/gcc/testsuite/objc.dg/torture/strings/const-cfstring-4.m +@@ -18,4 +18,4 @@ + + /* { dg-final { scan-assembler ".section __DATA, __cfstring" } } */ + /* { dg-final { scan-assembler ".long\t___CFConstantStringClassReference\n\t.long\t1992\n\t.long\t.*\n\t.long\t19\n" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t___CFConstantStringClassReference\n\t.long\t1992\n\t.space 4\n\t.quad\t.*\n\t.quad\t19\n" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t___CFConstantStringClassReference\n\t.(long|word)\t1992\n\t.space 4\n\t.(quad|xword)\t.*\n\t.(quad|xword)\t19\n} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-10.m b/gcc/testsuite/objc.dg/torture/strings/const-str-10.m +index 6565dc20007..81b0d326c56 100644 +--- a/gcc/testsuite/objc.dg/torture/strings/const-str-10.m ++++ b/gcc/testsuite/objc.dg/torture/strings/const-str-10.m +@@ -34,4 +34,4 @@ @interface NSConstantString : NSSimpleCString + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._NSConstantString\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-11.m b/gcc/testsuite/objc.dg/torture/strings/const-str-11.m +index 2bdb1531e1d..b044b0fd8c7 100644 +--- a/gcc/testsuite/objc.dg/torture/strings/const-str-11.m ++++ b/gcc/testsuite/objc.dg/torture/strings/const-str-11.m +@@ -33,4 +33,4 @@ @interface XStr : XString { + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__XStrClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._XStr\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._XStr\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/testsuite/objc.dg/torture/strings/const-str-9.m b/gcc/testsuite/objc.dg/torture/strings/const-str-9.m +index 966ea5e498d..d3d2916ed06 100644 +--- a/gcc/testsuite/objc.dg/torture/strings/const-str-9.m ++++ b/gcc/testsuite/objc.dg/torture/strings/const-str-9.m +@@ -25,4 +25,4 @@ @interface NSConstantString: NSObject { + /* { dg-final { scan-assembler ".section __OBJC, __cstring_object" { target { *-*-darwin* && { ! lp64 } } } } } */ + /* { dg-final { scan-assembler ".section __DATA, __objc_stringobj" { target { *-*-darwin* && { lp64 } } } } } */ + /* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" { target { *-*-darwin* && { ! lp64 } } } } } */ +-/* { dg-final { scan-assembler ".quad\t_OBJC_CLASS_._NSConstantString\n\t.quad\t.*\n\t.long\t5\n\t.space" { target { *-*-darwin* && { lp64 } } } } } */ ++/* { dg-final { scan-assembler {.(quad|xword)\t_OBJC_CLASS_._NSConstantString\n\t.(quad|xword)\t.*\n\t.(long|word)\t5\n\t.space} { target { *-*-darwin* && { lp64 } } } } } */ +diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc +index 078ceab3ca3..0308f558036 100644 +--- a/gcc/tree-nested.cc ++++ b/gcc/tree-nested.cc +@@ -611,6 +611,14 @@ get_trampoline_type (struct nesting_info *info) + if (trampoline_type) + return trampoline_type; + ++ /* When trampolines are created off-stack then the only thing we need in the ++ local frame is a single pointer. */ ++ if (flag_off_stack_trampolines) ++ { ++ trampoline_type = build_pointer_type (void_type_node); ++ return trampoline_type; ++ } ++ + align = TRAMPOLINE_ALIGNMENT; + size = TRAMPOLINE_SIZE; + +@@ -2786,17 +2794,27 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) + + /* Compute the address of the field holding the trampoline. */ + x = get_frame_field (info, target_context, x, &wi->gsi); +- x = build_addr (x); +- x = gsi_gimplify_val (info, x, &wi->gsi); + +- /* Do machine-specific ugliness. Normally this will involve +- computing extra alignment, but it can really be anything. */ +- if (descr) +- builtin = builtin_decl_implicit (BUILT_IN_ADJUST_DESCRIPTOR); ++ /* APB: We don't need to do the adjustment calls when using off-stack ++ trampolines, any such adjustment will be done when the off-stack ++ trampoline is created. */ ++ if (!descr && flag_off_stack_trampolines) ++ x = gsi_gimplify_val (info, x, &wi->gsi); + else +- builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE); +- call = gimple_build_call (builtin, 1, x); +- x = init_tmp_var_with_call (info, &wi->gsi, call); ++ { ++ x = build_addr (x); ++ ++ x = gsi_gimplify_val (info, x, &wi->gsi); ++ ++ /* Do machine-specific ugliness. Normally this will involve ++ computing extra alignment, but it can really be anything. */ ++ if (descr) ++ builtin = builtin_decl_implicit (BUILT_IN_ADJUST_DESCRIPTOR); ++ else ++ builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE); ++ call = gimple_build_call (builtin, 1, x); ++ x = init_tmp_var_with_call (info, &wi->gsi, call); ++ } + + /* Cast back to the proper function type. */ + x = build1 (NOP_EXPR, TREE_TYPE (t), x); +@@ -3375,6 +3393,7 @@ build_init_call_stmt (struct nesting_info *info, tree decl, tree field, + static void + finalize_nesting_tree_1 (struct nesting_info *root) + { ++ gimple_seq cleanup_list = NULL; + gimple_seq stmt_list = NULL; + gimple *stmt; + tree context = root->context; +@@ -3506,9 +3525,48 @@ finalize_nesting_tree_1 (struct nesting_info *root) + if (!field) + continue; + +- x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE); +- stmt = build_init_call_stmt (root, i->context, field, x); +- gimple_seq_add_stmt (&stmt_list, stmt); ++ if (flag_off_stack_trampolines) ++ { ++ /* We pass a whole bunch of arguments to the builtin function that ++ creates the off-stack trampoline, these are ++ 1. The nested function chain value (that must be passed to the ++ nested function so it can find the function arguments). ++ 2. A pointer to the nested function implementation, ++ 3. The address in the local stack frame where we should write ++ the address of the trampoline. ++ ++ When this code was originally written I just kind of threw ++ everything at the builtin, figuring I'd work out what was ++ actually needed later, I think, the stack pointer could ++ certainly be dropped, arguments #2 and #4 are based off the ++ stack pointer anyway, so #1 doesn't seem to add much value. */ ++ tree arg1, arg2, arg3; ++ ++ gcc_assert (DECL_STATIC_CHAIN (i->context)); ++ arg1 = build_addr (root->frame_decl); ++ arg2 = build_addr (i->context); ++ ++ x = build3 (COMPONENT_REF, TREE_TYPE (field), ++ root->frame_decl, field, NULL_TREE); ++ arg3 = build_addr (x); ++ ++ x = builtin_decl_implicit (BUILT_IN_NESTED_PTR_CREATED); ++ stmt = gimple_build_call (x, 3, arg1, arg2, arg3); ++ gimple_seq_add_stmt (&stmt_list, stmt); ++ ++ /* This call to delete the nested function trampoline is added to ++ the cleanup list, and called when we exit the current scope. */ ++ x = builtin_decl_implicit (BUILT_IN_NESTED_PTR_DELETED); ++ stmt = gimple_build_call (x, 0); ++ gimple_seq_add_stmt (&cleanup_list, stmt); ++ } ++ else ++ { ++ /* Original code to initialise the on stack trampoline. */ ++ x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE); ++ stmt = build_init_call_stmt (root, i->context, field, x); ++ gimple_seq_add_stmt (&stmt_list, stmt); ++ } + } + } + +@@ -3533,11 +3591,40 @@ finalize_nesting_tree_1 (struct nesting_info *root) + /* If we created initialization statements, insert them. */ + if (stmt_list) + { +- gbind *bind; +- annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); +- bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); +- gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); +- gimple_bind_set_body (bind, stmt_list); ++ if (flag_off_stack_trampolines) ++ { ++ /* Handle the new, off stack trampolines. */ ++ gbind *bind; ++ annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); ++ annotate_all_with_location (cleanup_list, DECL_SOURCE_LOCATION (context)); ++ bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); ++ gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); ++ ++ gimple_seq xxx_list = NULL; ++ ++ if (cleanup_list != NULL) ++ { ++ /* We Maybe shouldn't be creating this try/finally if -fno-exceptions is ++ in use. If this is the case, then maybe we should, instead, be ++ inserting the cleanup code onto every path out of this function? Not ++ yet figured out how we would do this. */ ++ gtry *t = gimple_build_try (stmt_list, cleanup_list, GIMPLE_TRY_FINALLY); ++ gimple_seq_add_stmt (&xxx_list, t); ++ } ++ else ++ xxx_list = stmt_list; ++ ++ gimple_bind_set_body (bind, xxx_list); ++ } ++ else ++ { ++ /* The traditional, on stack trampolines. */ ++ gbind *bind; ++ annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); ++ bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); ++ gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); ++ gimple_bind_set_body (bind, stmt_list); ++ } + } + + /* If a chain_decl was created, then it needs to be registered with +diff --git a/gcc/tree.cc b/gcc/tree.cc +index 4cf3785270b..5cba2ab8171 100644 +--- a/gcc/tree.cc ++++ b/gcc/tree.cc +@@ -9766,6 +9766,23 @@ build_common_builtin_nodes (void) + "__builtin_nonlocal_goto", + ECF_NORETURN | ECF_NOTHROW); + ++ tree ptr_ptr_type_node = build_pointer_type (ptr_type_node); ++ ++ ftype = build_function_type_list (void_type_node, ++ ptr_type_node, // void *chain ++ ptr_type_node, // void *func ++ ptr_ptr_type_node, // void **dst ++ NULL_TREE); ++ local_define_builtin ("__builtin_nested_func_ptr_created", ftype, ++ BUILT_IN_NESTED_PTR_CREATED, ++ "__builtin_nested_func_ptr_created", ECF_NOTHROW); ++ ++ ftype = build_function_type_list (void_type_node, ++ NULL_TREE); ++ local_define_builtin ("__builtin_nested_func_ptr_deleted", ftype, ++ BUILT_IN_NESTED_PTR_DELETED, ++ "__builtin_nested_func_ptr_deleted", ECF_NOTHROW); ++ + ftype = build_function_type_list (void_type_node, + ptr_type_node, ptr_type_node, NULL_TREE); + local_define_builtin ("__builtin_setjmp_setup", ftype, +diff --git a/libada/configure b/libada/configure +index 162d9731f26..9c8b133d817 100755 +--- a/libada/configure ++++ b/libada/configure +@@ -3212,6 +3212,9 @@ case "${host}" in + # sets the default TLS model and affects inlining. + PICFLAG=-fPIC + ;; ++ loongarch*-*-*) ++ PICFLAG=-fpic ++ ;; + mips-sgi-irix6*) + # PIC is the default. + ;; +diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am +index d88515e4a03..3c921f4a86d 100644 +--- a/libatomic/Makefile.am ++++ b/libatomic/Makefile.am +@@ -65,8 +65,13 @@ libatomic_version_script = + libatomic_version_dep = + endif + libatomic_version_info = -version-info $(libtool_VERSION) ++if ENABLE_DARWIN_AT_RPATH ++libatomic_darwin_rpath = -Wc,-nodefaultrpaths ++libatomic_darwin_rpath += -Wl,-rpath,@loader_path ++endif + +-libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags) ++libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ ++ $(lt_host_flags) $(libatomic_darwin_rpath) + libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \ + fenv.c fence.c flag.c + +diff --git a/libatomic/Makefile.in b/libatomic/Makefile.in +index 80d25653dc7..179f9217ad6 100644 +--- a/libatomic/Makefile.in ++++ b/libatomic/Makefile.in +@@ -403,7 +403,12 @@ noinst_LTLIBRARIES = libatomic_convenience.la + @LIBAT_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBAT_BUILD_VERSIONED_SHLIB_TRUE@libatomic_version_dep = $(top_srcdir)/libatomic.map + @LIBAT_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBAT_BUILD_VERSIONED_SHLIB_TRUE@libatomic_version_dep = libatomic.map-sun + libatomic_version_info = -version-info $(libtool_VERSION) +-libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libatomic_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ ++ $(lt_host_flags) $(libatomic_darwin_rpath) ++ + libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \ + fenv.c fence.c flag.c + +diff --git a/libatomic/configure b/libatomic/configure +index 92853dd8a45..935d5559aed 100755 +--- a/libatomic/configure ++++ b/libatomic/configure +@@ -658,6 +658,8 @@ OPT_LDFLAGS + SECTION_LDFLAGS + enable_aarch64_lse + libtool_VERSION ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + MAINT + MAINTAINER_MODE_FALSE + MAINTAINER_MODE_TRUE +@@ -803,6 +805,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_maintainer_mode + enable_symvers + enable_werror +@@ -1452,6 +1455,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +@@ -9576,6 +9581,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9593,10 +9639,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11382,7 +11437,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11385 "configure" ++#line 11440 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11488,7 +11543,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11491 "configure" ++#line 11546 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11773,6 +11828,15 @@ fi + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # For libtool versioning info, format is CURRENT:REVISION:AGE + libtool_VERSION=3:0:2 + +@@ -15900,6 +15964,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + if test -z "${LIBAT_BUILD_VERSIONED_SHLIB_TRUE}" && test -z "${LIBAT_BUILD_VERSIONED_SHLIB_FALSE}"; then + as_fn_error $? "conditional \"LIBAT_BUILD_VERSIONED_SHLIB\" was never defined. +diff --git a/libatomic/configure.ac b/libatomic/configure.ac +index 5563551aaae..6b9d3085806 100644 +--- a/libatomic/configure.ac ++++ b/libatomic/configure.ac +@@ -156,6 +156,8 @@ AC_SUBST(enable_shared) + AC_SUBST(enable_static) + AM_MAINTAINER_MODE + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + # For libtool versioning info, format is CURRENT:REVISION:AGE + libtool_VERSION=3:0:2 + AC_SUBST(libtool_VERSION) +diff --git a/libatomic/testsuite/Makefile.in b/libatomic/testsuite/Makefile.in +index 333980ec2c1..8bc70562e5b 100644 +--- a/libatomic/testsuite/Makefile.in ++++ b/libatomic/testsuite/Makefile.in +@@ -262,6 +262,7 @@ target_alias = @target_alias@ + target_cpu = @target_cpu@ + target_os = @target_os@ + target_vendor = @target_vendor@ ++tmake_file = @tmake_file@ + toolexecdir = @toolexecdir@ + toolexeclibdir = @toolexeclibdir@ + top_build_prefix = @top_build_prefix@ +diff --git a/libatomic/testsuite/lib/libatomic.exp b/libatomic/testsuite/lib/libatomic.exp +index 38f3e5673e2..300e5096f79 100644 +--- a/libatomic/testsuite/lib/libatomic.exp ++++ b/libatomic/testsuite/lib/libatomic.exp +@@ -152,6 +152,7 @@ proc libatomic_init { args } { + lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.." + + if [istarget *-*-darwin*] { ++ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs" + lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" + } + +diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in +index 08cdd21fb40..8898251161d 100644 +--- a/libbacktrace/Makefile.in ++++ b/libbacktrace/Makefile.in +@@ -15,7 +15,7 @@ + @SET_MAKE@ + + # Makefile.am -- Backtrace Makefile. +-# Copyright (C) 2012-2021 Free Software Foundation, Inc. ++# Copyright (C) 2012-2022 Free Software Foundation, Inc. + + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are +diff --git a/libbacktrace/backtrace.c b/libbacktrace/backtrace.c +index d28575ec897..cf6491682a7 100644 +--- a/libbacktrace/backtrace.c ++++ b/libbacktrace/backtrace.c +@@ -70,6 +70,13 @@ unwind (struct _Unwind_Context *context, void *vdata) + uintptr_t pc; + int ip_before_insn = 0; + ++#ifdef __APPLE__ ++# undef HAVE_GETIPINFO ++# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 ++# define HAVE_GETIPINFO 1 ++# endif ++#endif ++ + #ifdef HAVE_GETIPINFO + pc = _Unwind_GetIPInfo (context, &ip_before_insn); + #else +diff --git a/libbacktrace/configure b/libbacktrace/configure +index 17f470a4bec..957095aaf1b 100755 +--- a/libbacktrace/configure ++++ b/libbacktrace/configure +@@ -675,6 +675,8 @@ PIC_FLAG + WARN_FLAGS + EXTRA_FLAGS + BACKTRACE_FILE ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + OTOOL64 + OTOOL + LIPO +@@ -799,6 +801,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_largefile + enable_cet + enable_werror +@@ -1447,6 +1450,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --disable-largefile omit support for large files + --enable-cet enable Intel CET in target libraries [default=auto] + --disable-werror disable building with -Werror +@@ -9705,6 +9710,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9722,10 +9768,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11511,7 +11566,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11514 "configure" ++#line 11569 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11617,7 +11672,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11620 "configure" ++#line 11675 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11856,6 +11911,15 @@ CC="$lt_save_CC" + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # Check whether --enable-largefile was given. + if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +@@ -14273,6 +14337,10 @@ if test -z "${HAVE_DWZ_TRUE}" && test -z "${HAVE_DWZ_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DWZ\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${HAVE_ELF_TRUE}" && test -z "${HAVE_ELF_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ELF\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac +index 597c9705db8..7f89bf33c6b 100644 +--- a/libbacktrace/configure.ac ++++ b/libbacktrace/configure.ac +@@ -84,6 +84,8 @@ AM_CONDITIONAL(HAVE_DWZ, test "$DWZ" != "") + LT_INIT + AM_PROG_LIBTOOL + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + AC_SYS_LARGEFILE + + backtrace_supported=yes +diff --git a/libbacktrace/simple.c b/libbacktrace/simple.c +index 6a1a1c92a12..811255ab6b5 100644 +--- a/libbacktrace/simple.c ++++ b/libbacktrace/simple.c +@@ -65,6 +65,13 @@ simple_unwind (struct _Unwind_Context *context, void *vdata) + uintptr_t pc; + int ip_before_insn = 0; + ++#ifdef __APPLE__ ++# undef HAVE_GETIPINFO ++# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 ++# define HAVE_GETIPINFO 1 ++# endif ++#endif ++ + #ifdef HAVE_GETIPINFO + pc = _Unwind_GetIPInfo (context, &ip_before_insn); + #else +diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am +index 6e3a34ff7e2..44d282c7676 100644 +--- a/libcc1/Makefile.am ++++ b/libcc1/Makefile.am +@@ -55,6 +55,10 @@ marshall_c_source = marshall-c.hh + marshall_cxx_source = marshall-cp.hh + + libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym ++if ENABLE_DARWIN_AT_RPATH ++libcc1plugin_la_LDFLAGS += -Wc,-nodefaultrpaths ++libcc1plugin_la_LDFLAGS += -Wl,-rpath,@loader_path ++endif + libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_c_source) + libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C) +@@ -65,6 +69,10 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@ + + libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym ++if ENABLE_DARWIN_AT_RPATH ++libcp1plugin_la_LDFLAGS += -Wc,-nodefaultrpaths ++libcp1plugin_la_LDFLAGS += -Wl,-rpath,@loader_path ++endif + libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_cxx_source) + libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX) +@@ -76,6 +84,10 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + + LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) + libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym ++if ENABLE_DARWIN_AT_RPATH ++libcc1_la_LDFLAGS += -Wc,-nodefaultrpaths ++libcc1_la_LDFLAGS += -Wl,-rpath,@loader_path ++endif + libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \ + compiler.cc compiler.hh names.cc names.hh $(shared_source) \ + $(marshall_c_source) $(marshall_cxx_source) +diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in +index f8f590d71e9..440567a47d2 100644 +--- a/libcc1/Makefile.in ++++ b/libcc1/Makefile.in +@@ -90,6 +90,12 @@ build_triplet = @build@ + host_triplet = @host@ + target_triplet = @target@ + @DARWIN_DYNAMIC_LOOKUP_TRUE@am__append_1 = -Wl,-undefined,dynamic_lookup ++@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_2 = -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_3 = -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_4 = -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +@@ -405,7 +411,8 @@ shared_source = callbacks.cc callbacks.hh connection.cc connection.hh \ + + marshall_c_source = marshall-c.hh + marshall_cxx_source = marshall-cp.hh +-libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym ++libcc1plugin_la_LDFLAGS = -module -export-symbols \ ++ $(srcdir)/libcc1plugin.sym $(am__append_2) + libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_c_source) + +@@ -416,7 +423,8 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@ + +-libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym ++libcp1plugin_la_LDFLAGS = -module -export-symbols \ ++ $(srcdir)/libcp1plugin.sym $(am__append_3) + libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \ + $(shared_source) $(marshall_cxx_source) + +@@ -428,7 +436,8 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(CXXFLAGS) $(libcp1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@ + + LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) +-libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym ++libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym \ ++ $(am__append_4) + libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \ + compiler.cc compiler.hh names.cc names.hh $(shared_source) \ + $(marshall_c_source) $(marshall_cxx_source) +diff --git a/libcc1/configure b/libcc1/configure +index 01cfb2806da..42fb85a4047 100755 +--- a/libcc1/configure ++++ b/libcc1/configure +@@ -646,6 +646,8 @@ gcc_version + get_gcc_base_ver + CET_HOST_FLAGS + visibility ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + CXXCPP + am__fastdepCXX_FALSE + am__fastdepCXX_TRUE +@@ -787,6 +789,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_cet + with_gcc_major_version_only + enable_werror_always +@@ -1439,6 +1442,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-cet enable Intel CET in host libraries [default=auto] + --enable-werror-always enable -Werror despite compiler version + --enable-plugin enable plugin support +@@ -8971,6 +8976,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -8988,10 +9034,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -10777,7 +10832,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10780 "configure" ++#line 10835 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -10883,7 +10938,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10886 "configure" ++#line 10941 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12165,6 +12220,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -12182,12 +12278,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -14518,6 +14627,14 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + visibility= + if test "$GXX" = yes; then +@@ -15369,6 +15486,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${DARWIN_DYNAMIC_LOOKUP_TRUE}" && test -z "${DARWIN_DYNAMIC_LOOKUP_FALSE}"; then + as_fn_error $? "conditional \"DARWIN_DYNAMIC_LOOKUP\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libcc1/configure.ac b/libcc1/configure.ac +index 36f5a7e09f1..e8d068e0ac4 100644 +--- a/libcc1/configure.ac ++++ b/libcc1/configure.ac +@@ -38,6 +38,7 @@ AM_MAINTAINER_MODE + LT_INIT([disable-static]) + AM_PROG_LIBTOOL + AC_PROG_CXX ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + visibility= + if test "$GXX" = yes; then +diff --git a/libffi/Makefile.am b/libffi/Makefile.am +index c6d6f849c53..d2ae0c04c7b 100644 +--- a/libffi/Makefile.am ++++ b/libffi/Makefile.am +@@ -214,7 +214,12 @@ libffi.map: $(top_srcdir)/libffi.map.in + $(COMPILE) -D$(TARGET) -DGENERATE_LIBFFI_MAP \ + -E -x assembler-with-cpp -o $@ $(top_srcdir)/libffi.map.in + +-libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) ++if ENABLE_DARWIN_AT_RPATH ++libffi_darwin_rpath = -Wl,-rpath,@loader_path ++endif ++libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \ ++ $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \ ++ $(libffi_darwin_rpath) + libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep) + + AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src +diff --git a/libffi/Makefile.in b/libffi/Makefile.in +index 5524a6a571e..34e77a45d1a 100644 +--- a/libffi/Makefile.in ++++ b/libffi/Makefile.in +@@ -597,7 +597,11 @@ AM_CFLAGS = -Wall -g -fexceptions $(CET_FLAGS) $(am__append_2) + @LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map + @LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map-sun + libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version` +-libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libffi_darwin_rpath = -Wl,-rpath,@loader_path ++libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \ ++ $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \ ++ $(libffi_darwin_rpath) ++ + libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep) + AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src + AM_CCASFLAGS = $(AM_CPPFLAGS) $(CET_FLAGS) +diff --git a/libffi/configure b/libffi/configure +index 575641cca1d..002320ca302 100755 +--- a/libffi/configure ++++ b/libffi/configure +@@ -667,6 +667,8 @@ MAINT + MAINTAINER_MODE_FALSE + MAINTAINER_MODE_TRUE + READELF ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + CXXCPP + CPP + OTOOL64 +@@ -810,6 +812,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_maintainer_mode + enable_pax_emutramp + enable_debug +@@ -1465,6 +1468,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +@@ -9766,6 +9771,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9783,10 +9829,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11572,7 +11627,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11575 "configure" ++#line 11630 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11678,7 +11733,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11681 "configure" ++#line 11736 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12554,6 +12609,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -12571,12 +12667,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -14926,6 +15035,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + # Only expand once: + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. +@@ -17071,6 +17188,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libffi/configure.ac b/libffi/configure.ac +index 014d89d0423..716f20ae313 100644 +--- a/libffi/configure.ac ++++ b/libffi/configure.ac +@@ -55,6 +55,7 @@ AC_SUBST(CET_FLAGS) + AM_PROG_AS + AM_PROG_CC_C_O + AC_PROG_LIBTOOL ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + AC_CHECK_TOOL(READELF, readelf) + +diff --git a/libgcc/config.host b/libgcc/config.host +index 8c56fcae5d2..48eed32e195 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -82,7 +82,7 @@ m32c*-*-*) + cpu_type=m32c + tmake_file=t-fdpbit + ;; +-aarch64*-*-*) ++aarch64*-*-* | arm64*-*-*) + cpu_type=aarch64 + ;; + alpha*-*-*) +@@ -241,7 +241,46 @@ case ${host} in + ;; + esac + tmake_file="$tmake_file t-slibgcc-darwin" +- extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a" ++ # We are not using libtool to build the libs here, so we need to replicate ++ # a little of the logic around setting Darwin rpaths. Setting an explicit ++ # yes or no is honoured, otherwise we choose a suitable default. ++ # Sadly, this has to be kept in line with the rules in libtool.m4. ++ # This make fragment will override the setting in t-slibgcc-darwin so it ++ # must appear after it. ++ if test "x$enable_darwin_at_rpath" = "x"; then ++ echo "enable_darwin_at_rpath is unset" 1>&2 ++ case ${host} in ++ *-darwin[45678]*) ;; ++ *-darwin9* | *-darwin1[01234]*) ;; # We might default these on later. ++ *-darwin*) ++ echo "but is needed after macOS 10.11 (setting it on)" 1>&2 ++ enable_darwin_at_rpath=yes ++ ;; ++ esac ++ else ++ echo "enable_darwin_at_rpath is '$enable_darwin_at_rpath'" 1>&2 ++ fi ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ tmake_file="$tmake_file t-darwin-rpath " ++ fi ++ case ${host} in ++ *-*-darwin2* | *-*-darwin1[89]* | aarch64*-*-darwin*) ++ tmake_file="t-darwin-min-8 $tmake_file" ++ ;; ++ *-*-darwin9* | *-*-darwin1[0-7]*) ++ tmake_file="t-darwin-min-5 $tmake_file" ++ ;; ++ *-*-darwin[4-8]*) ++ tmake_file="t-darwin-min-1 $tmake_file" ++ ;; ++ *) ++ # Fall back to configuring for the oldest system known to work with ++ # all archs and the current sources. ++ tmake_file="t-darwin-min-5 $tmake_file" ++ echo "Warning: libgcc configured to support macOS 10.5" 1>&2 ++ ;; ++ esac ++ extra_parts="crt3.o crttms.o crttme.o libemutls_w.a" + ;; + *-*-dragonfly*) + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip" +@@ -384,6 +423,17 @@ aarch64*-*-elf | aarch64*-*-rtems*) + tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" + md_unwind_header=aarch64/aarch64-unwind.h + ;; ++aarch64*-*-darwin*) ++ extra_parts="$extra_parts crtfastmath.o" ++ tmake_file="${tmake_file} ${cpu_type}/t-aarch64" ++ tmake_file="${tmake_file} ${cpu_type}/t-lse " ++ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp " ++ tmake_file="${tmake_file} t-crtfm" ++ md_unwind_header=aarch64/aarch64-unwind.h ++ if test x$off_stack_trampolines = xyes; then ++ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" ++ fi ++ ;; + aarch64*-*-freebsd*) + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} ${cpu_type}/t-aarch64" +@@ -408,6 +458,9 @@ aarch64*-*-linux*) + tmake_file="${tmake_file} ${cpu_type}/t-aarch64" + tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" + tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" ++ if test x$off_stack_trampolines = xyes; then ++ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" ++ fi + ;; + aarch64*-*-vxworks7*) + extra_parts="$extra_parts crtfastmath.o" +@@ -701,12 +754,17 @@ hppa*-*-netbsd*) + i[34567]86-*-darwin*) + tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" + tm_file="$tm_file i386/darwin-lib.h" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" + ;; + x86_64-*-darwin*) + tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" + tm_file="$tm_file i386/darwin-lib.h" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" ++ if test x$off_stack_trampolines = xyes; then ++ tmake_file="${tmake_file} i386/t-heap-trampoline" ++ fi + ;; + i[34567]86-*-elfiamcu) + tmake_file="$tmake_file i386/t-crtstuff t-softfp-sfdftf i386/32/t-softfp i386/32/t-iamcu i386/t-softfp t-softfp t-dfprules" +@@ -773,6 +831,9 @@ x86_64-*-linux*) + tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" + tm_file="${tm_file} i386/elf-lib.h" + md_unwind_header=i386/linux-unwind.h ++ if test x$off_stack_trampolines = xyes; then ++ tmake_file="${tmake_file} i386/t-heap-trampoline" ++ fi + ;; + x86_64-*-kfreebsd*-gnu) + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" +@@ -1169,12 +1230,14 @@ powerpc-*-darwin*) + # We build the darwin10 EH shim for Rosetta (running on x86 machines). + tm_file="$tm_file i386/darwin-lib.h" + tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" + ;; + powerpc64-*-darwin*) + # We build the darwin10 EH shim for Rosetta (running on x86 machines). + tm_file="$tm_file i386/darwin-lib.h" + tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble" ++ extra_parts="$extra_parts libd10-uwfef.a " + extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" + ;; + powerpc*-*-freebsd*) +diff --git a/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c +new file mode 100644 +index 00000000000..c8b83681ed7 +--- /dev/null ++++ b/libgcc/config/aarch64/heap-trampoline.c +@@ -0,0 +1,172 @@ ++/* Copyright The GNU Toolchain Authors. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if __APPLE__ ++/* For pthread_jit_write_protect_np */ ++#include ++#endif ++ ++void *allocate_trampoline_page (void); ++int get_trampolines_per_page (void); ++struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); ++void *allocate_trampoline_page (void); ++ ++void __builtin_nested_func_ptr_created (void *chain, void *func, void **dst); ++void __builtin_nested_func_ptr_deleted (void); ++ ++#if defined(__gnu_linux__) ++static const uint32_t aarch64_trampoline_insns[] = { ++ 0xd503245f, /* hint 34 */ ++ 0x580000b1, /* ldr x17, .+20 */ ++ 0x580000d2, /* ldr x18, .+24 */ ++ 0xd61f0220, /* br x17 */ ++ 0xd5033f9f, /* dsb sy */ ++ 0xd5033fdf /* isb */ ++}; ++ ++#elif __APPLE__ ++static const uint32_t aarch64_trampoline_insns[] = { ++ 0xd503245f, /* hint 34 */ ++ 0x580000b1, /* ldr x17, .+20 */ ++ 0x580000d0, /* ldr x16, .+24 */ ++ 0xd61f0220, /* br x17 */ ++ 0xd5033f9f, /* dsb sy */ ++ 0xd5033fdf /* isb */ ++}; ++ ++#else ++#error "Unsupported AArch64 platform for heap trampolines" ++#endif ++ ++struct aarch64_trampoline { ++ uint32_t insns[6]; ++ void *func_ptr; ++ void *chain_ptr; ++}; ++ ++struct tramp_ctrl_data ++{ ++ struct tramp_ctrl_data *prev; ++ ++ int free_trampolines; ++ ++ /* This will be pointing to an executable mmap'ed page. */ ++ struct aarch64_trampoline *trampolines; ++}; ++ ++int ++get_trampolines_per_page (void) ++{ ++ return getpagesize() / sizeof(struct aarch64_trampoline); ++} ++ ++static _Thread_local struct tramp_ctrl_data *tramp_ctrl_curr = NULL; ++ ++void * ++allocate_trampoline_page (void) ++{ ++ void *page; ++ ++#if defined(__gnu_linux__) ++ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, ++ MAP_ANON | MAP_PRIVATE, 0, 0); ++#elif __APPLE__ ++ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, ++ MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); ++#else ++ page = MAP_FAILED; ++#endif ++ ++ return page; ++} ++ ++struct tramp_ctrl_data * ++allocate_tramp_ctrl (struct tramp_ctrl_data *parent) ++{ ++ struct tramp_ctrl_data *p = malloc (sizeof (struct tramp_ctrl_data)); ++ if (p == NULL) ++ return NULL; ++ ++ p->trampolines = allocate_trampoline_page (); ++ ++ if (p->trampolines == MAP_FAILED) ++ return NULL; ++ ++ p->prev = parent; ++ p->free_trampolines = get_trampolines_per_page(); ++ ++ return p; ++} ++ ++void ++__builtin_nested_func_ptr_created (void *chain, void *func, void **dst) ++{ ++ if (tramp_ctrl_curr == NULL) ++ { ++ tramp_ctrl_curr = allocate_tramp_ctrl (NULL); ++ if (tramp_ctrl_curr == NULL) ++ abort (); ++ } ++ ++ if (tramp_ctrl_curr->free_trampolines == 0) ++ { ++ void *tramp_ctrl = allocate_tramp_ctrl (tramp_ctrl_curr); ++ if (!tramp_ctrl) ++ abort (); ++ ++ tramp_ctrl_curr = tramp_ctrl; ++ } ++ ++ struct aarch64_trampoline *trampoline ++ = &tramp_ctrl_curr->trampolines[get_trampolines_per_page () ++ - tramp_ctrl_curr->free_trampolines]; ++ ++#if __APPLE__ ++ /* Disable write protection for the MAP_JIT regions in this thread (see ++ https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon) */ ++ pthread_jit_write_protect_np (0); ++#endif ++ ++ memcpy (trampoline->insns, aarch64_trampoline_insns, ++ sizeof(aarch64_trampoline_insns)); ++ trampoline->func_ptr = func; ++ trampoline->chain_ptr = chain; ++ ++#if __APPLE__ ++ /* Re-enable write protection. */ ++ pthread_jit_write_protect_np (1); ++#endif ++ ++ tramp_ctrl_curr->free_trampolines -= 1; ++ ++ __builtin___clear_cache ((void *)trampoline->insns, ++ ((void *)trampoline->insns + sizeof(trampoline->insns))); ++ ++ *dst = &trampoline->insns; ++} ++ ++void ++__builtin_nested_func_ptr_deleted (void) ++{ ++ if (tramp_ctrl_curr == NULL) ++ abort (); ++ ++ tramp_ctrl_curr->free_trampolines += 1; ++ ++ if (tramp_ctrl_curr->free_trampolines == get_trampolines_per_page ()) ++ { ++ if (tramp_ctrl_curr->prev == NULL) ++ return; ++ ++ munmap (tramp_ctrl_curr->trampolines, getpagesize()); ++ struct tramp_ctrl_data *prev = tramp_ctrl_curr->prev; ++ free (tramp_ctrl_curr); ++ tramp_ctrl_curr = prev; ++ } ++} +diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S +index 9c29cf08b59..97b68c42cc1 100644 +--- a/libgcc/config/aarch64/lse.S ++++ b/libgcc/config/aarch64/lse.S +@@ -58,7 +58,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #endif + + /* Declare the symbol gating the LSE implementations. */ ++#if __ELF__ + .hidden __aarch64_have_lse_atomics ++#else ++ .private_extern __aarch64_have_lse_atomics ++#endif + + /* Turn size and memory model defines into mnemonic fragments. */ + #if SIZE == 1 +@@ -164,6 +168,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define BTI_C hint 34 + + /* Start and end a function. */ ++#if __ELF__ + .macro STARTFN name + .text + .balign 16 +@@ -187,6 +192,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + cbz w(tmp0), \label + .endm + ++#else ++.macro STARTFN name ++ .text ++ .balign 16 ++ .private_extern _\name ++ .cfi_startproc ++_\name: ++ BTI_C ++.endm ++ ++.macro ENDFN name ++ .cfi_endproc ++.endm ++ ++/* Branch to LABEL if LSE is disabled. */ ++.macro JUMP_IF_NOT_LSE label ++ adrp x(tmp0), ___aarch64_have_lse_atomics@PAGE ++ ldrb w(tmp0), [x(tmp0), ___aarch64_have_lse_atomics@PAGEOFF] ++ cbz w(tmp0), \label ++.endm ++ ++#endif ++ + #ifdef L_cas + + STARTFN NAME(cas) +diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h +index be9b42174c4..5dc1827ee3a 100644 +--- a/libgcc/config/aarch64/sfp-machine.h ++++ b/libgcc/config/aarch64/sfp-machine.h +@@ -122,6 +122,27 @@ void __sfp_handle_exceptions (int); + + + /* Define ALIASNAME as a strong alias for NAME. */ ++#if defined __APPLE__ ++/* Mach-O doesn't support aliasing, so we build a secondary function for ++ the alias - we need to do a bit of a dance to find out what the type of ++ the arguments is and then apply that to the secondary function. ++ If these functions ever return anything but CMPtype we need to revisit ++ this... */ ++typedef float alias_HFtype __attribute__ ((mode (HF))); ++typedef float alias_SFtype __attribute__ ((mode (SF))); ++typedef float alias_DFtype __attribute__ ((mode (DF))); ++typedef float alias_TFtype __attribute__ ((mode (TF))); ++#define ALIAS_SELECTOR \ ++ CMPtype (*) (alias_HFtype, alias_HFtype): (alias_HFtype) 0, \ ++ CMPtype (*) (alias_SFtype, alias_SFtype): (alias_SFtype) 0, \ ++ CMPtype (*) (alias_DFtype, alias_DFtype): (alias_DFtype) 0, \ ++ CMPtype (*) (alias_TFtype, alias_TFtype): (alias_TFtype) 0 ++#define strong_alias(name, aliasname) \ ++ CMPtype aliasname (__typeof (_Generic (name, ALIAS_SELECTOR)) a, \ ++ __typeof (_Generic (name, ALIAS_SELECTOR)) b) \ ++ { return name (a, b); } ++#else + # define strong_alias(name, aliasname) _strong_alias(name, aliasname) + # define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); ++#endif +diff --git a/libgcc/config/aarch64/t-darwin b/libgcc/config/aarch64/t-darwin +new file mode 100644 +index 00000000000..f6ecda7b608 +--- /dev/null ++++ b/libgcc/config/aarch64/t-darwin +@@ -0,0 +1,7 @@ ++# Ensure we have a suitable minimum OS version. ++ ++HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0 ++ ++LIB2_SIDITI_CONV_FUNCS = yes ++ ++BUILD_LIBGCCS1 = +diff --git a/libgcc/config/aarch64/t-heap-trampoline b/libgcc/config/aarch64/t-heap-trampoline +new file mode 100644 +index 00000000000..3f70c2cd0c0 +--- /dev/null ++++ b/libgcc/config/aarch64/t-heap-trampoline +@@ -0,0 +1,20 @@ ++# Copyright The GNU Toolchain Authors. ++ ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++LIB2ADD += $(srcdir)/config/aarch64/heap-trampoline.c ++HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0 +diff --git a/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c +new file mode 100644 +index 00000000000..96e13bf828e +--- /dev/null ++++ b/libgcc/config/i386/heap-trampoline.c +@@ -0,0 +1,172 @@ ++/* Copyright The GNU Toolchain Authors. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 ++/* For pthread_jit_write_protect_np */ ++#include ++#endif ++ ++void *allocate_trampoline_page (void); ++int get_trampolines_per_page (void); ++struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); ++void *allocate_trampoline_page (void); ++ ++void __builtin_nested_func_ptr_created (void *chain, void *func, void **dst); ++void __builtin_nested_func_ptr_deleted (void); ++ ++static const uint8_t trampoline_insns[] = { ++ /* movabs $,%r11 */ ++ 0x49, 0xbb, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* movabs $,%r10 */ ++ 0x49, 0xba, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* rex.WB jmpq *%r11 */ ++ 0x41, 0xff, 0xe3 ++}; ++ ++union ix86_trampoline { ++ uint8_t insns[sizeof(trampoline_insns)]; ++ ++ struct __attribute__((packed)) fields { ++ uint8_t insn_0[2]; ++ void *func_ptr; ++ uint8_t insn_1[2]; ++ void *chain_ptr; ++ uint8_t insn_2[3]; ++ } fields; ++}; ++ ++struct tramp_ctrl_data ++{ ++ struct tramp_ctrl_data *prev; ++ ++ int free_trampolines; ++ ++ /* This will be pointing to an executable mmap'ed page. */ ++ union ix86_trampoline *trampolines; ++}; ++ ++int ++get_trampolines_per_page (void) ++{ ++ return getpagesize() / sizeof(union ix86_trampoline); ++} ++ ++static _Thread_local struct tramp_ctrl_data *tramp_ctrl_curr = NULL; ++ ++void * ++allocate_trampoline_page (void) ++{ ++ void *page; ++ ++#if defined(__gnu_linux__) ++ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, ++ MAP_ANON | MAP_PRIVATE, 0, 0); ++#elif __APPLE__ ++# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 ++ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, ++ MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); ++# else ++ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, ++ MAP_ANON | MAP_PRIVATE, 0, 0); ++# endif ++#else ++ page = MAP_FAILED; ++#endif ++ ++ return page; ++} ++ ++struct tramp_ctrl_data * ++allocate_tramp_ctrl (struct tramp_ctrl_data *parent) ++{ ++ struct tramp_ctrl_data *p = malloc (sizeof (struct tramp_ctrl_data)); ++ if (p == NULL) ++ return NULL; ++ ++ p->trampolines = allocate_trampoline_page (); ++ ++ if (p->trampolines == MAP_FAILED) ++ return NULL; ++ ++ p->prev = parent; ++ p->free_trampolines = get_trampolines_per_page(); ++ ++ return p; ++} ++ ++void ++__builtin_nested_func_ptr_created (void *chain, void *func, void **dst) ++{ ++ if (tramp_ctrl_curr == NULL) ++ { ++ tramp_ctrl_curr = allocate_tramp_ctrl (NULL); ++ if (tramp_ctrl_curr == NULL) ++ abort (); ++ } ++ ++ if (tramp_ctrl_curr->free_trampolines == 0) ++ { ++ void *tramp_ctrl = allocate_tramp_ctrl (tramp_ctrl_curr); ++ if (!tramp_ctrl) ++ abort (); ++ ++ tramp_ctrl_curr = tramp_ctrl; ++ } ++ ++ union ix86_trampoline *trampoline ++ = &tramp_ctrl_curr->trampolines[get_trampolines_per_page () ++ - tramp_ctrl_curr->free_trampolines]; ++ ++#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 ++ /* Disable write protection for the MAP_JIT regions in this thread (see ++ https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon) */ ++ pthread_jit_write_protect_np (0); ++#endif ++ ++ memcpy (trampoline->insns, trampoline_insns, ++ sizeof(trampoline_insns)); ++ trampoline->fields.func_ptr = func; ++ trampoline->fields.chain_ptr = chain; ++ ++#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 ++ /* Re-enable write protection. */ ++ pthread_jit_write_protect_np (1); ++#endif ++ ++ tramp_ctrl_curr->free_trampolines -= 1; ++ ++ __builtin___clear_cache ((void *)trampoline->insns, ++ ((void *)trampoline->insns + sizeof(trampoline->insns))); ++ ++ *dst = &trampoline->insns; ++} ++ ++void ++__builtin_nested_func_ptr_deleted (void) ++{ ++ if (tramp_ctrl_curr == NULL) ++ abort (); ++ ++ tramp_ctrl_curr->free_trampolines += 1; ++ ++ if (tramp_ctrl_curr->free_trampolines == get_trampolines_per_page ()) ++ { ++ if (tramp_ctrl_curr->prev == NULL) ++ return; ++ ++ munmap (tramp_ctrl_curr->trampolines, getpagesize()); ++ struct tramp_ctrl_data *prev = tramp_ctrl_curr->prev; ++ free (tramp_ctrl_curr); ++ tramp_ctrl_curr = prev; ++ } ++} +diff --git a/libgcc/config/i386/t-heap-trampoline b/libgcc/config/i386/t-heap-trampoline +new file mode 100644 +index 00000000000..76f438d9529 +--- /dev/null ++++ b/libgcc/config/i386/t-heap-trampoline +@@ -0,0 +1,20 @@ ++# Copyright The GNU Toolchain Authors. ++ ++# This file is part of GCC. ++# ++# GCC is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3, or (at your option) ++# any later version. ++# ++# GCC is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GCC; see the file COPYING3. If not see ++# . ++ ++LIB2ADD += $(srcdir)/config/i386/heap-trampoline.c ++HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=10.8 +diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin +index 299d26c2c96..a708583d965 100644 +--- a/libgcc/config/t-darwin ++++ b/libgcc/config/t-darwin +@@ -1,15 +1,15 @@ + # Set this as a minimum (unless overriden by arch t-files) since it's a + # reasonable lowest common denominator that works for all our archs. +-HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=10.4 ++HOST_LIBGCC2_CFLAGS += $(DARWIN_MIN_LIB_VERSION) + + crt3.o: $(srcdir)/config/darwin-crt3.c +- $(crt_compile) -mmacosx-version-min=10.4 -c $< ++ $(crt_compile) $(DARWIN_MIN_CRT_VERSION) -c $< + + crttms.o: $(srcdir)/config/darwin-crt-tm.c +- $(crt_compile) -mmacosx-version-min=10.4 -DSTART -c $< ++ $(crt_compile) $(DARWIN_MIN_CRT_VERSION) -DSTART -c $< + + crttme.o: $(srcdir)/config/darwin-crt-tm.c +- $(crt_compile) -mmacosx-version-min=10.4 -DEND -c $< ++ $(crt_compile) $(DARWIN_MIN_CRT_VERSION) -DEND -c $< + + # Make emutls weak so that we can deal with -static-libgcc, override the + # hidden visibility when this is present in libgcc_eh. +@@ -24,7 +24,8 @@ libemutls_w.a: emutls_s.o + $(AR_CREATE_FOR_TARGET) $@ $< + $(RANLIB_FOR_TARGET) $@ + +-# Patch to __Unwind_Find_Enclosing_Function for Darwin10. ++# This has to be built for 10.6, even if the toolchain will not target that ++# version + d10-uwfef.o: $(srcdir)/config/darwin10-unwind-find-enc-func.c libgcc_tm.h + $(crt_compile) -mmacosx-version-min=10.6 -c $< + +diff --git a/libgcc/config/t-darwin-min-1 b/libgcc/config/t-darwin-min-1 +new file mode 100644 +index 00000000000..8c2cf8acd39 +--- /dev/null ++++ b/libgcc/config/t-darwin-min-1 +@@ -0,0 +1,3 @@ ++# Support building with -mmacosx-version-min back to 10.1. ++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=10.4 ++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=10.1 +diff --git a/libgcc/config/t-darwin-min-4 b/libgcc/config/t-darwin-min-4 +new file mode 100644 +index 00000000000..04e980de4d5 +--- /dev/null ++++ b/libgcc/config/t-darwin-min-4 +@@ -0,0 +1,3 @@ ++# Support building with -mmacosx-version-min back to 10.4. ++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=10.4 ++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=10.4 +diff --git a/libgcc/config/t-darwin-min-5 b/libgcc/config/t-darwin-min-5 +new file mode 100644 +index 00000000000..138193151e7 +--- /dev/null ++++ b/libgcc/config/t-darwin-min-5 +@@ -0,0 +1,3 @@ ++# Support building with -mmacosx-version-min back to 10.5. ++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=10.5 ++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=10.5 +diff --git a/libgcc/config/t-darwin-min-8 b/libgcc/config/t-darwin-min-8 +new file mode 100644 +index 00000000000..9efc9dc0257 +--- /dev/null ++++ b/libgcc/config/t-darwin-min-8 +@@ -0,0 +1,3 @@ ++# Support building with -mmacosx-version-min back to 10.8. ++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=10.8 ++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=10.8 +diff --git a/libgcc/config/t-darwin-rpath b/libgcc/config/t-darwin-rpath +new file mode 100644 +index 00000000000..951539de7aa +--- /dev/null ++++ b/libgcc/config/t-darwin-rpath +@@ -0,0 +1,5 @@ ++# Use @rpath and add a search path to exes and dylibs that depend on this. ++SHLIB_RPATH = @rpath ++ ++# Enable the libgcc_s.1.dylib compatibility lib to find the dependent 1.1.dylib. ++SHLIB_LOADER_PATH = -Wl,-rpath,@loader_path +diff --git a/libgcc/config/t-slibgcc-darwin b/libgcc/config/t-slibgcc-darwin +index a8f69666a82..ee449de32e6 100644 +--- a/libgcc/config/t-slibgcc-darwin ++++ b/libgcc/config/t-slibgcc-darwin +@@ -1,4 +1,4 @@ +-# Build a shared libgcc library with the darwin linker. ++# Build a shared libgcc library able to use embedded runpaths. + + SHLIB_SOVERSION = 1.1 + SHLIB_SO_MINVERSION = 1 +@@ -6,7 +6,6 @@ SHLIB_VERSTRING = -compatibility_version $(SHLIB_SO_MINVERSION) \ + -current_version $(SHLIB_SOVERSION) + SHLIB_EXT = .dylib + SHLIB_LC = -lSystem +-SHLIB_INSTALL_DIR = $(slibdir) + + SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk + SHLIB_MKMAP_OPTS = -v leading_underscore=1 +@@ -23,11 +22,20 @@ SHLIB_SONAME = @shlib_base_name@$(SHLIB_EXT) + # subdir. The code under MULTIBUILDTOP combines these into a single FAT + # library, that is what we eventually install. + ++# When enable_darwin_at_rpath is true, use @rpath instead of $(slibdir) for ++# this and dylibs that depend on this. So this def must come first and be ++# overridden in a make fragment that depends on the rpath setting. ++SHLIB_RPATH = $(slibdir) ++ ++# Likewise, we only want to add an @loader_path to the shared libs when ++# we have enable_darwin_at_rpath. ++SHLIB_LOADER_PATH = ++ + SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \ +- -install_name $(SHLIB_INSTALL_DIR)/$(SHLIB_INSTALL_NAME) \ ++ -install_name $(SHLIB_RPATH)/$(SHLIB_INSTALL_NAME) \ + -single_module -o $(SHLIB_DIR)/$(SHLIB_SONAME) \ + -Wl,-exported_symbols_list,$(SHLIB_MAP) \ +- $(SHLIB_VERSTRING) \ ++ $(SHLIB_VERSTRING) -nodefaultrpaths \ + @multilib_flags@ @shlib_objs@ $(SHLIB_LC) + + # we do our own thing +@@ -63,9 +71,9 @@ EHS_INSTNAME = libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT) + libgcc_ehs$(SHLIB_EXT): $(LIBEHSOBJS) $(extra-parts) + mkdir -p $(MULTIDIR) + $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \ +- -install_name $(SHLIB_INSTALL_DIR)/$(EHS_INSTNAME) \ ++ -install_name $(SHLIB_RPATH)/$(EHS_INSTNAME) \ + -o $(MULTIDIR)/libgcc_ehs$(SHLIB_EXT) $(SHLIB_VERSTRING) \ +- $(LIBEHSOBJS) $(SHLIB_LC) ++ -nodefaultrpaths $(LIBEHSOBJS) $(SHLIB_LC) + + all: libgcc_ehs$(SHLIB_EXT) + +@@ -121,12 +129,13 @@ libgcc_s.1.dylib: all-multi libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) \ + cp ../$${mlib}/libgcc/$${mlib}/libgcc_ehs$(SHLIB_EXT) \ + ./libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \ + arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \ +- $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \ ++ $(CC) -arch $${arch} -nodefaultlibs -dynamiclib -nodefaultrpaths \ ++ $(SHLIB_LOADER_PATH) \ + -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \ + -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ + -Wl,-reexport_library,libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ +- -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \ +- -compatibility_version 1 -current_version 1 ; \ ++ -install_name $(SHLIB_RPATH)/libgcc_s.1.dylib \ ++ -compatibility_version 1 -current_version 1.1 ; \ + done + $(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T* + rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T* +@@ -140,13 +149,14 @@ libgcc_s.1.dylib: all-multi libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) + cp ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT) \ + ./libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \ + arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \ +- $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \ ++ $(CC) -arch $${arch} -nodefaultlibs -dynamiclib -nodefaultrpaths \ ++ $(SHLIB_LOADER_PATH) \ + -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \ + -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ + -lSystem \ + -Wl,-reexported_symbols_list,$(srcdir)/config/darwin-unwind.ver \ +- -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \ +- -compatibility_version 1 -current_version 1 ; \ ++ -install_name $(SHLIB_RPATH)/libgcc_s.1.dylib \ ++ -compatibility_version 1 -current_version 1.1 ; \ + done + $(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T* + rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T* +diff --git a/libgcc/configure b/libgcc/configure +index 1f9b2ac578b..a5c228bc3a1 100755 +--- a/libgcc/configure ++++ b/libgcc/configure +@@ -630,7 +630,6 @@ LIPO + AR + toolexeclibdir + toolexecdir +-enable_gcov + target_subdir + host_subdir + build_subdir +@@ -654,6 +653,8 @@ build_cpu + build + with_aix_soname + enable_vtable_verify ++enable_gcov ++off_stack_trampolines + enable_shared + libgcc_topdir + target_alias +@@ -701,6 +702,8 @@ with_target_subdir + with_cross_host + with_ld + enable_shared ++enable_off_stack_trampolines ++enable_gcov + enable_vtable_verify + with_aix_soname + enable_version_specific_runtime_libs +@@ -708,7 +711,6 @@ with_toolexeclibdir + with_slibdir + enable_maintainer_mode + with_build_libsubdir +-enable_gcov + enable_largefile + enable_decimal_float + with_system_libunwind +@@ -1342,12 +1344,15 @@ Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-shared don't provide a shared libgcc ++ --enable-off-stack-trampolines ++ Specify whether to support generating off-stack trampolines ++ ++ --disable-gcov don't provide libgcov and related host tools + --enable-vtable-verify Enable vtable verification feature + --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +- --disable-gcov don't provide libgcov and related host tools + --disable-largefile omit support for large files + --enable-decimal-float={no,yes,bid,dpd} + enable decimal float extension to C. Selecting 'bid' +@@ -2252,6 +2257,48 @@ fi + + + ++# Check whether --enable-off-stack-trampolines was given. ++if test "${enable_off_stack_trampolines+set}" = set; then : ++ enableval=$enable_off_stack_trampolines; ++case "$target" in ++ x86_64-*-linux* | x86_64-*-darwin1[4-9]* | x86_64-*-darwin2*) ++ off_stack_trampolines=$enableval ++ ;; ++ aarch64*-*-linux* ) ++ off_stack_trampolines=$enableval ++ ;; ++ aarch64*-*darwin* ) ++ off_stack_trampolines=$enableval ++ ;; ++ *) ++ as_fn_error $? "Configure option --enable-off-stack-trampolines is not supported \ ++for this platform" "$LINENO" 5 ++ off_stack_trampolines=no ++ ;; ++esac ++else ++ ++case "$target" in ++ *-*-darwin2*) ++ off_stack_trampolines=yes ++ ;; ++ *) ++ off_stack_trampolines=no ++ ;; ++esac ++fi ++ ++ ++ ++# Check whether --enable-gcov was given. ++if test "${enable_gcov+set}" = set; then : ++ enableval=$enable_gcov; ++else ++ enable_gcov=yes ++fi ++ ++ ++ + # Check whether --enable-vtable-verify was given. + if test "${enable_vtable_verify+set}" = set; then : + enableval=$enable_vtable_verify; case "$enableval" in +diff --git a/libgcc/configure.ac b/libgcc/configure.ac +index 2fc9d5d7c93..7d11bf00142 100644 +--- a/libgcc/configure.ac ++++ b/libgcc/configure.ac +@@ -68,6 +68,40 @@ AC_ARG_ENABLE(shared, + ], [enable_shared=yes]) + AC_SUBST(enable_shared) + ++AC_ARG_ENABLE([off-stack-trampolines], ++ [AS_HELP_STRING([--enable-off-stack-trampolines] ++ [Specify whether to support generating off-stack trampolines])],[ ++case "$target" in ++ x86_64-*-linux* | x86_64-*-darwin1[[4-9]]* | x86_64-*-darwin2*) ++ off_stack_trampolines=$enableval ++ ;; ++ aarch64*-*-linux* ) ++ off_stack_trampolines=$enableval ++ ;; ++ aarch64*-*darwin* ) ++ off_stack_trampolines=$enableval ++ ;; ++ *) ++ AC_MSG_ERROR([Configure option --enable-off-stack-trampolines is not supported \ ++for this platform]) ++ off_stack_trampolines=no ++ ;; ++esac],[ ++case "$target" in ++ *-*-darwin2*) ++ off_stack_trampolines=yes ++ ;; ++ *) ++ off_stack_trampolines=no ++ ;; ++esac]) ++AC_SUBST(off_stack_trampolines) ++ ++AC_ARG_ENABLE(gcov, ++[ --disable-gcov don't provide libgcov and related host tools], ++[], [enable_gcov=yes]) ++AC_SUBST(enable_gcov) ++ + AC_ARG_ENABLE(vtable-verify, + [ --enable-vtable-verify Enable vtable verification feature ], + [case "$enableval" in +diff --git a/libgcc/libgcc-std.ver.in b/libgcc/libgcc-std.ver.in +index 513ddd0bd0d..fc0b4052a3b 100644 +--- a/libgcc/libgcc-std.ver.in ++++ b/libgcc/libgcc-std.ver.in +@@ -1943,4 +1943,7 @@ GCC_4.8.0 { + GCC_7.0.0 { + __PFX__divmoddi4 + __PFX__divmodti4 ++ ++ __builtin_nested_func_ptr_created ++ __builtin_nested_func_ptr_deleted + } +diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h +index fc24ac34502..536e517b62f 100644 +--- a/libgcc/libgcc2.h ++++ b/libgcc/libgcc2.h +@@ -29,6 +29,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #pragma GCC visibility push(default) + #endif + ++extern void __builtin_nested_func_ptr_created (void *, void *, void **); ++extern void __builtin_nested_func_ptr_deleted (void); ++ + extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t); + extern void __clear_cache (void *, void *); + extern void __eprintf (const char *, const char *, unsigned int, const char *) +diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am +index 5ce0cd7cd05..2073bf6c5ef 100644 +--- a/libgfortran/Makefile.am ++++ b/libgfortran/Makefile.am +@@ -37,6 +37,11 @@ else + version_arg = + version_dep = + endif ++extra_darwin_ldflags_libgfortran = @extra_ldflags_libgfortran@ ++if ENABLE_DARWIN_AT_RPATH ++extra_darwin_ldflags_libgfortran += -Wc,-nodefaultrpaths ++extra_darwin_ldflags_libgfortran += -Wl,-rpath,@loader_path ++endif + + gfor_c_HEADERS = ISO_Fortran_binding.h + gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include +@@ -50,7 +55,7 @@ libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS) + libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ + $(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \ + $(HWCAP_LDFLAGS) \ +- $(LIBM) $(extra_ldflags_libgfortran) \ ++ $(LIBM) $(extra_darwin_ldflags_libgfortran) \ + $(version_arg) -Wc,-shared-libgcc + libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) + +diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in +index 7ac6bfba657..52dd5f1819e 100644 +--- a/libgfortran/Makefile.in ++++ b/libgfortran/Makefile.in +@@ -91,8 +91,10 @@ POST_UNINSTALL = : + build_triplet = @build@ + host_triplet = @host@ + target_triplet = @target@ +-@LIBGFOR_MINIMAL_TRUE@am__append_1 = -DLIBGFOR_MINIMAL +-@LIBGFOR_MINIMAL_FALSE@am__append_2 = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++@LIBGFOR_MINIMAL_TRUE@am__append_2 = -DLIBGFOR_MINIMAL ++@LIBGFOR_MINIMAL_FALSE@am__append_3 = \ + @LIBGFOR_MINIMAL_FALSE@io/close.c \ + @LIBGFOR_MINIMAL_FALSE@io/file_pos.c \ + @LIBGFOR_MINIMAL_FALSE@io/format.c \ +@@ -110,7 +112,7 @@ target_triplet = @target@ + @LIBGFOR_MINIMAL_FALSE@io/fbuf.c \ + @LIBGFOR_MINIMAL_FALSE@io/async.c + +-@LIBGFOR_MINIMAL_FALSE@am__append_3 = \ ++@LIBGFOR_MINIMAL_FALSE@am__append_4 = \ + @LIBGFOR_MINIMAL_FALSE@intrinsics/access.c \ + @LIBGFOR_MINIMAL_FALSE@intrinsics/c99_functions.c \ + @LIBGFOR_MINIMAL_FALSE@intrinsics/chdir.c \ +@@ -143,9 +145,9 @@ target_triplet = @target@ + @LIBGFOR_MINIMAL_FALSE@intrinsics/umask.c \ + @LIBGFOR_MINIMAL_FALSE@intrinsics/unlink.c + +-@IEEE_SUPPORT_TRUE@am__append_4 = ieee/ieee_helper.c +-@LIBGFOR_MINIMAL_TRUE@am__append_5 = runtime/minimal.c +-@LIBGFOR_MINIMAL_FALSE@am__append_6 = \ ++@IEEE_SUPPORT_TRUE@am__append_5 = ieee/ieee_helper.c ++@LIBGFOR_MINIMAL_TRUE@am__append_6 = runtime/minimal.c ++@LIBGFOR_MINIMAL_FALSE@am__append_7 = \ + @LIBGFOR_MINIMAL_FALSE@runtime/backtrace.c \ + @LIBGFOR_MINIMAL_FALSE@runtime/convert_char.c \ + @LIBGFOR_MINIMAL_FALSE@runtime/environ.c \ +@@ -157,7 +159,7 @@ target_triplet = @target@ + + + # dummy sources for libtool +-@onestep_TRUE@am__append_7 = libgfortran_c.c libgfortran_f.f90 ++@onestep_TRUE@am__append_8 = libgfortran_c.c libgfortran_f.f90 + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ +@@ -589,7 +591,7 @@ AMTAR = @AMTAR@ + + # Some targets require additional compiler options for IEEE compatibility. + AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) \ +- $(IEEE_FLAGS) $(am__append_1) ++ $(IEEE_FLAGS) $(am__append_2) + AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ + AM_FCFLAGS = @AM_FCFLAGS@ $(IEEE_FLAGS) + AR = @AR@ +@@ -748,6 +750,8 @@ gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) + @LIBGFOR_USE_SYMVER_FALSE@version_dep = + @LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.ver + @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.ver-sun gfortran.ver ++extra_darwin_ldflags_libgfortran = @extra_ldflags_libgfortran@ \ ++ $(am__append_1) + gfor_c_HEADERS = ISO_Fortran_binding.h + gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include + LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \ +@@ -759,7 +763,7 @@ libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS) + libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ + $(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \ + $(HWCAP_LDFLAGS) \ +- $(LIBM) $(extra_ldflags_libgfortran) \ ++ $(LIBM) $(extra_darwin_ldflags_libgfortran) \ + $(version_arg) -Wc,-shared-libgcc + + libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) +@@ -780,7 +784,7 @@ AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \ + -I$(MULTIBUILDTOP)../libbacktrace \ + -I../libbacktrace + +-gfor_io_src = io/size_from_kind.c $(am__append_2) ++gfor_io_src = io/size_from_kind.c $(am__append_3) + gfor_io_headers = \ + io/io.h \ + io/fbuf.h \ +@@ -802,7 +806,7 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \ + intrinsics/selected_int_kind.f90 \ + intrinsics/selected_real_kind.f90 intrinsics/trigd.c \ + intrinsics/unpack_generic.c runtime/in_pack_generic.c \ +- runtime/in_unpack_generic.c $(am__append_3) $(am__append_4) ++ runtime/in_unpack_generic.c $(am__append_4) $(am__append_5) + @IEEE_SUPPORT_TRUE@gfor_ieee_helper_src = ieee/ieee_helper.c + @IEEE_SUPPORT_FALSE@gfor_ieee_src = + @IEEE_SUPPORT_TRUE@gfor_ieee_src = \ +@@ -811,8 +815,8 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \ + @IEEE_SUPPORT_TRUE@ieee/ieee_features.F90 + + gfor_src = runtime/bounds.c runtime/compile_options.c runtime/memory.c \ +- runtime/string.c runtime/select.c $(am__append_5) \ +- $(am__append_6) ++ runtime/string.c runtime/select.c $(am__append_6) \ ++ $(am__append_7) + i_all_c = \ + $(srcdir)/generated/all_l1.c \ + $(srcdir)/generated/all_l2.c \ +@@ -1652,7 +1656,7 @@ intrinsics/random_init.f90 + + BUILT_SOURCES = $(gfor_built_src) $(gfor_built_specific_src) \ + $(gfor_built_specific2_src) $(gfor_misc_specifics) \ +- $(am__append_7) ++ $(am__append_8) + prereq_SRC = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \ + $(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src) + +diff --git a/libgfortran/configure b/libgfortran/configure +index ae64dca3114..f288af81ff5 100755 +--- a/libgfortran/configure ++++ b/libgfortran/configure +@@ -655,6 +655,8 @@ extra_ldflags_libgfortran + ac_ct_FC + FCFLAGS + FC ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -824,6 +826,7 @@ enable_static + with_pic + enable_fast_install + enable_libtool_lock ++enable_darwin_at_rpath + enable_largefile + enable_libquadmath_support + with_gcc_major_version_only +@@ -1479,6 +1482,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --disable-largefile omit support for large files + --disable-libquadmath-support + disable libquadmath support for Fortran +@@ -10939,6 +10944,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10956,10 +11002,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12766,7 +12821,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12769 "configure" ++#line 12824 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12872,7 +12927,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12875 "configure" ++#line 12930 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13274,6 +13329,14 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + #AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10 + + # We need gfortran to compile parts of the library +@@ -14917,6 +14980,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_FC=no + hardcode_direct_FC=no + hardcode_automatic_FC=yes +@@ -14934,10 +15038,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs_FC=no +@@ -16190,9 +16303,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + # extra LD Flags which are required for targets ++extra_ldflags_libgfortran= + case "${host}" in +- *-darwin*) +- # Darwin needs -single_module when linking libgfortran ++ *-*-darwin[4567]*) ++ # Earlier Darwin needs -single_module when linking libgfortran + extra_ldflags_libgfortran=-Wl,-single_module + ;; + esac +@@ -28519,6 +28633,10 @@ if test -z "${HAVE_HWCAP_TRUE}" && test -z "${HAVE_HWCAP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_HWCAP\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${LIBGFOR_BUILD_QUAD_TRUE}" && test -z "${LIBGFOR_BUILD_QUAD_FALSE}"; then + as_fn_error $? "conditional \"LIBGFOR_BUILD_QUAD\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac +index 97cc490cb5e..a21f56648a2 100644 +--- a/libgfortran/configure.ac ++++ b/libgfortran/configure.ac +@@ -282,6 +282,7 @@ LT_LIB_M + ACX_LT_HOST_FLAGS + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + #AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10 + + # We need gfortran to compile parts of the library +@@ -290,9 +291,10 @@ FC="$GFORTRAN" + AC_PROG_FC(gfortran) + + # extra LD Flags which are required for targets ++extra_ldflags_libgfortran= + case "${host}" in +- *-darwin*) +- # Darwin needs -single_module when linking libgfortran ++ *-*-darwin[[4567]]*) ++ # Earlier Darwin needs -single_module when linking libgfortran + extra_ldflags_libgfortran=-Wl,-single_module + ;; + esac +diff --git a/libgo/configure b/libgo/configure +index ffe17c9be55..de5c1ac9b3d 100755 +--- a/libgo/configure ++++ b/libgo/configure +@@ -708,6 +708,8 @@ glibgo_toolexecdir + WERROR + WARN_FLAGS + CC_FOR_BUILD ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + CPP +@@ -11544,7 +11546,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11547 "configure" ++#line 11549 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11650,7 +11652,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11653 "configure" ++#line 11655 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13779,6 +13781,14 @@ CC="$lt_save_CC" + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} + +@@ -16321,6 +16331,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${USE_LIBFFI_TRUE}" && test -z "${USE_LIBFFI_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBFFI\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libgo/configure.ac b/libgo/configure.ac +index 7e2b98ba67c..7b0222bb620 100644 +--- a/libgo/configure.ac ++++ b/libgo/configure.ac +@@ -53,6 +53,7 @@ AC_LIBTOOL_DLOPEN + AM_PROG_LIBTOOL + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} + AC_SUBST(CC_FOR_BUILD) +diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am +index f8b2a06d63e..81ba6c634fa 100644 +--- a/libgomp/Makefile.am ++++ b/libgomp/Makefile.am +@@ -53,9 +53,14 @@ else + libgomp_version_script = + libgomp_version_dep = + endif ++ + libgomp_version_info = -version-info $(libtool_VERSION) ++if ENABLE_DARWIN_AT_RPATH ++libgomp_darwin_rpath = -Wc,-nodefaultrpaths ++libgomp_darwin_rpath += -Wl,-rpath,@loader_path ++endif + libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ +- $(lt_host_flags) ++ $(lt_host_flags) $(libgomp_darwin_rpath) + libgomp_la_DEPENDENCIES = $(libgomp_version_dep) + libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) + +diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in +index 6f0cb716135..5cfb149c2ba 100644 +--- a/libgomp/Makefile.in ++++ b/libgomp/Makefile.in +@@ -546,8 +546,11 @@ nodist_toolexeclib_HEADERS = libgomp.spec + @LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver + @LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver-sun + libgomp_version_info = -version-info $(libtool_VERSION) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libgomp_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path + libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ +- $(lt_host_flags) ++ $(lt_host_flags) $(libgomp_darwin_rpath) + + libgomp_la_DEPENDENCIES = $(libgomp_version_dep) + libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) +diff --git a/libgomp/configure b/libgomp/configure +index 85fdb4d3f48..71b5987dc9a 100755 +--- a/libgomp/configure ++++ b/libgomp/configure +@@ -692,6 +692,8 @@ FC + MAINT + MAINTAINER_MODE_FALSE + MAINTAINER_MODE_TRUE ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -832,6 +834,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_maintainer_mode + with_cuda_driver + with_cuda_driver_include +@@ -1493,6 +1496,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +@@ -9625,6 +9630,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9642,10 +9688,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11431,7 +11486,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11434 "configure" ++#line 11489 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11537,7 +11592,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11540 "configure" ++#line 11595 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11798,6 +11853,14 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +@@ -13473,6 +13536,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_FC=no + hardcode_direct_FC=no + hardcode_automatic_FC=yes +@@ -13490,10 +13594,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs_FC=no +@@ -17213,6 +17326,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then + as_fn_error $? "conditional \"BUILD_INFO\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libgomp/configure.ac b/libgomp/configure.ac +index a9b1f3973f7..654fca1f445 100644 +--- a/libgomp/configure.ac ++++ b/libgomp/configure.ac +@@ -149,6 +149,7 @@ AM_PROG_LIBTOOL + ACX_LT_HOST_FLAGS + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + AM_MAINTAINER_MODE + +diff --git a/libiberty/aclocal.m4 b/libiberty/aclocal.m4 +index 3378316dced..1a00b771fe1 100644 +--- a/libiberty/aclocal.m4 ++++ b/libiberty/aclocal.m4 +@@ -12,10 +12,61 @@ + # PARTICULAR PURPOSE. + + m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) ++# AM_CONDITIONAL -*- Autoconf -*- ++ ++# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_CONDITIONAL(NAME, SHELL-CONDITION) ++# ------------------------------------- ++# Define a conditional. ++AC_DEFUN([AM_CONDITIONAL], ++[AC_PREREQ([2.52])dnl ++ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], ++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl ++AC_SUBST([$1_TRUE])dnl ++AC_SUBST([$1_FALSE])dnl ++_AM_SUBST_NOTMAKE([$1_TRUE])dnl ++_AM_SUBST_NOTMAKE([$1_FALSE])dnl ++m4_define([_AM_COND_VALUE_$1], [$2])dnl ++if $2; then ++ $1_TRUE= ++ $1_FALSE='#' ++else ++ $1_TRUE='#' ++ $1_FALSE= ++fi ++AC_CONFIG_COMMANDS_PRE( ++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then ++ AC_MSG_ERROR([[conditional "$1" was never defined. ++Usually this means the macro was only invoked conditionally.]]) ++fi])]) ++ ++# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# _AM_SUBST_NOTMAKE(VARIABLE) ++# --------------------------- ++# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. ++# This macro is traced by Automake. ++AC_DEFUN([_AM_SUBST_NOTMAKE]) ++ ++# AM_SUBST_NOTMAKE(VARIABLE) ++# -------------------------- ++# Public sister of _AM_SUBST_NOTMAKE. ++AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) ++ + m4_include([../config/acx.m4]) + m4_include([../config/cet.m4]) + m4_include([../config/enable.m4]) + m4_include([../config/no-executables.m4]) ++m4_include([../config/override.m4]) + m4_include([../config/picflag.m4]) + m4_include([../config/warnings.m4]) + m4_include([acinclude.m4]) +diff --git a/libiberty/configure b/libiberty/configure +index 0a797255c70..a346be40cc2 100755 +--- a/libiberty/configure ++++ b/libiberty/configure +@@ -632,6 +632,8 @@ PICFLAG + INSTALL_DATA + INSTALL_SCRIPT + INSTALL_PROGRAM ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + OUTPUT_OPTION + NO_MINUS_C_MINUS_O + ac_libiberty_warn_cflags +@@ -2459,6 +2461,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ++ ++ ++ + # This works around the fact that libtool configuration may change LD + # for this particular configuration, but some shells, instead of + # keeping the changes in LD private, export them just because LD is +@@ -5046,6 +5051,15 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + ac_config_headers="$ac_config_headers config.h:config.in" + + +@@ -5208,6 +5222,9 @@ case "${host}" in + # sets the default TLS model and affects inlining. + PICFLAG=-fPIC + ;; ++ loongarch*-*-*) ++ PICFLAG=-fpic ++ ;; + mips-sgi-irix6*) + # PIC is the default. + ;; +@@ -7837,6 +7854,10 @@ LTLIBOBJS=$ac_ltlibobjs + + + ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/libiberty/configure.ac b/libiberty/configure.ac +index 84a7b378fad..4dad84ea77a 100644 +--- a/libiberty/configure.ac ++++ b/libiberty/configure.ac +@@ -190,6 +190,8 @@ dnl AM_DISABLE_SHARED + dnl When we start using libtool: + dnl AM_PROG_LIBTOOL + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + dnl When we start using automake: + dnl AM_CONFIG_HEADER(config.h:config.in) + AC_CONFIG_HEADER(config.h:config.in) +diff --git a/libitm/Makefile.am b/libitm/Makefile.am +index 3f31ad30556..a25317b07fe 100644 +--- a/libitm/Makefile.am ++++ b/libitm/Makefile.am +@@ -54,7 +54,12 @@ libitm_version_info = -version-info $(libtool_VERSION) + # want or need libstdc++. + libitm_la_DEPENDENCIES = $(libitm_version_dep) + libitm_la_LINK = $(LINK) $(libitm_la_LDFLAGS) +-libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) ++if ENABLE_DARWIN_AT_RPATH ++libitm_darwin_rpath = -Wc,-nodefaultrpaths ++libitm_darwin_rpath += -Wl,-rpath,@loader_path ++endif ++libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) \ ++ $(libitm_darwin_rpath) + + libitm_la_SOURCES = \ + aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc barrier.cc beginend.cc \ +diff --git a/libitm/Makefile.in b/libitm/Makefile.in +index 7f53ea9b9db..ed28db45057 100644 +--- a/libitm/Makefile.in ++++ b/libitm/Makefile.in +@@ -481,7 +481,12 @@ libitm_version_info = -version-info $(libtool_VERSION) + # want or need libstdc++. + libitm_la_DEPENDENCIES = $(libitm_version_dep) + libitm_la_LINK = $(LINK) $(libitm_la_LDFLAGS) +-libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libitm_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) \ ++ $(libitm_darwin_rpath) ++ + libitm_la_SOURCES = aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc \ + barrier.cc beginend.cc clone.cc eh_cpp.cc local.cc query.cc \ + retry.cc rwlock.cc useraction.cc util.cc sjlj.S tls.cc \ +diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S +index 296cb683a9f..941e886143e 100644 +--- a/libitm/config/aarch64/sjlj.S ++++ b/libitm/config/aarch64/sjlj.S +@@ -57,10 +57,19 @@ + + .text + .align 2 ++#if __ELF__ + .global _ITM_beginTransaction + .type _ITM_beginTransaction, %function + + _ITM_beginTransaction: ++ ++#elif __MACH__ ++ .global __ITM_beginTransaction ++ ++__ITM_beginTransaction: ++ ++#endif ++ + cfi_startproc + CFI_PAC_KEY + PAC_AND_BTI +@@ -84,8 +93,13 @@ _ITM_beginTransaction: + + /* Invoke GTM_begin_transaction with the struct we just built. */ + mov x1, sp ++#if __ELF__ + bl GTM_begin_transaction +- ++#elif __MACH__ ++ bl _GTM_begin_transaction ++#else ++#error "unexpected object format" ++#endif + /* Return; we don't need to restore any of the call-saved regs. */ + ldp x29, x30, [sp], 11*16 + cfi_adjust_cfa_offset(-11*16) +@@ -95,14 +109,23 @@ _ITM_beginTransaction: + CFI_PAC_TOGGLE + ret + cfi_endproc ++#if __ELF__ + .size _ITM_beginTransaction, . - _ITM_beginTransaction ++#endif + + .align 2 ++#if __ELF__ + .global GTM_longjmp + .hidden GTM_longjmp + .type GTM_longjmp, %function + + GTM_longjmp: ++ ++#elif __MACH__ ++ .private_extern _GTM_longjmp ++ ++_GTM_longjmp: ++#endif + /* The first parameter becomes the return value (x0). + The third parameter is ignored for now. */ + cfi_startproc +@@ -126,7 +149,9 @@ GTM_longjmp: + CFI_PAC_TOGGLE + br x30 + cfi_endproc ++#if __ELF__ + .size GTM_longjmp, . - GTM_longjmp ++#endif + + /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ + #define FEATURE_1_AND 0xc0000000 +diff --git a/libitm/configure b/libitm/configure +index 18fc2d3a10a..5beb48a6b99 100755 +--- a/libitm/configure ++++ b/libitm/configure +@@ -660,6 +660,8 @@ libtool_VERSION + MAINT + MAINTAINER_MODE_FALSE + MAINTAINER_MODE_TRUE ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + CXXCPP +@@ -810,6 +812,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_maintainer_mode + enable_linux_futex + enable_tls +@@ -1462,6 +1465,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +@@ -10252,6 +10257,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10269,10 +10315,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12058,7 +12113,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12061 "configure" ++#line 12116 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12164,7 +12219,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12167 "configure" ++#line 12222 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13040,6 +13095,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -13057,12 +13153,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -15414,6 +15523,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +@@ -18172,6 +18289,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then + as_fn_error $? "conditional \"BUILD_INFO\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libitm/configure.ac b/libitm/configure.ac +index 78a682376d9..209a025a90e 100644 +--- a/libitm/configure.ac ++++ b/libitm/configure.ac +@@ -157,6 +157,7 @@ AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes") + AM_PROG_LIBTOOL + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + AM_MAINTAINER_MODE + +diff --git a/libitm/configure.tgt b/libitm/configure.tgt +index 06e90973ef3..acaf4f85712 100644 +--- a/libitm/configure.tgt ++++ b/libitm/configure.tgt +@@ -50,7 +50,7 @@ fi + # Map the target cpu to an ARCH sub-directory. At the same time, + # work out any special compilation flags as necessary. + case "${target_cpu}" in +- aarch64*) ARCH=aarch64 ;; ++ aarch64* | arm64*) ARCH=aarch64 ;; + alpha*) ARCH=alpha ;; + rs6000 | powerpc*) + XCFLAGS="${XCFLAGS} -mhtm" +diff --git a/libitm/testsuite/lib/libitm.exp b/libitm/testsuite/lib/libitm.exp +index 6d8e3e71310..906534022eb 100644 +--- a/libitm/testsuite/lib/libitm.exp ++++ b/libitm/testsuite/lib/libitm.exp +@@ -158,6 +158,7 @@ proc libitm_init { args } { + } + + if [istarget *-*-darwin*] { ++ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/.libs" + lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" + } + +diff --git a/libitm/testsuite/libitm.c++/c++.exp b/libitm/testsuite/libitm.c++/c++.exp +index f92aa096104..295c5bd4703 100644 +--- a/libitm/testsuite/libitm.c++/c++.exp ++++ b/libitm/testsuite/libitm.c++/c++.exp +@@ -56,8 +56,10 @@ if { $lang_test_file_found } { + # Gather a list of all tests. + set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]] + ++ set stdcxxadder "" + if { $blddir != "" } { + set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" ++ set stdcxxadder "-B ${blddir}/${lang_library_path}" + } else { + set ld_library_path "$always_ld_library_path" + } +@@ -72,7 +74,7 @@ if { $lang_test_file_found } { + } + + # Main loop. +- dg-runtest $tests "" $libstdcxx_includes ++ dg-runtest $tests $stdcxxadder $libstdcxx_includes + } + + # All done. +diff --git a/libobjc/configure b/libobjc/configure +index 5d1b424a66d..21ac18723c3 100755 +--- a/libobjc/configure ++++ b/libobjc/configure +@@ -636,6 +636,9 @@ OBJC_BOEHM_GC_LIBS + OBJC_BOEHM_GC_INCLUDES + OBJC_BOEHM_GC + OBJC_GCFLAGS ++extra_ldflags_libobjc ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + SET_MAKE + CPP + OTOOL64 +@@ -667,7 +670,6 @@ RANLIB + AR + AS + XCFLAGS +-extra_ldflags_libobjc + lt_host_flags + OBJEXT + EXEEXT +@@ -755,6 +757,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_tls + enable_objc_gc + with_target_bdw_gc +@@ -1392,6 +1395,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-tls Use thread-local storage [default=yes] + --enable-objc-gc enable use of Boehm's garbage collector with the GNU + Objective-C runtime +@@ -3430,17 +3435,6 @@ esac + + + +-case "${host}" in +- *-darwin*) +- # Darwin needs -single_module when linking libobjc +- extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' +- ;; +- *-cygwin*|*-mingw*) +- # Tell libtool to build DLLs on Windows +- extra_ldflags_libobjc='$(lt_host_flags)' +- ;; +-esac +- + + # Add CET specific flags if CET is enabled + +@@ -3466,7 +3460,7 @@ case "$host" in + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs +- # and if assembler supports CET insn. ++ # and if compiler and assembler support CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -8944,6 +8938,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -8961,10 +8996,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -10771,7 +10815,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10784 "configure" ++#line 10818 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -10877,7 +10921,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10890 "configure" ++#line 10924 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11149,6 +11193,38 @@ $as_echo "no" >&6; } + fi + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ ++# Must come after libtool is initialized. ++case "${host}" in ++ *-darwin[4567]*) ++ # Earlier Darwin versions need -single_module when linking libobjc; they ++ # do not support @rpath. ++ extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' ++ ;; ++ *-darwin*) ++ # Otherwise, single_module is the default and multi-module is ignored and ++ # obsolete. ++ extra_ldflags_libobjc='$(lt_host_flags)' ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wc,-nodefaultrpaths" ++ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wl,-rpath,@loader_path" ++ fi ++ ;; ++ *-cygwin*|*-mingw*) ++ # Tell libtool to build DLLs on Windows ++ extra_ldflags_libobjc='$(lt_host_flags)' ++ ;; ++esac ++ ++ + # ------- + # Headers + # ------- +@@ -11890,6 +11966,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/libobjc/configure.ac b/libobjc/configure.ac +index f8f577cfbef..2a9bf1fed4c 100644 +--- a/libobjc/configure.ac ++++ b/libobjc/configure.ac +@@ -147,17 +147,6 @@ m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + + # extra LD Flags which are required for targets + ACX_LT_HOST_FLAGS +-case "${host}" in +- *-darwin*) +- # Darwin needs -single_module when linking libobjc +- extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' +- ;; +- *-cygwin*|*-mingw*) +- # Tell libtool to build DLLs on Windows +- extra_ldflags_libobjc='$(lt_host_flags)' +- ;; +-esac +-AC_SUBST(extra_ldflags_libobjc) + + # Add CET specific flags if CET is enabled + GCC_CET_FLAGS(CET_FLAGS) +@@ -182,6 +171,31 @@ AM_PROG_CC_C_O + + AC_PROG_MAKE_SET + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ ++# Must come after libtool is initialized. ++case "${host}" in ++ *-darwin[[4567]]*) ++ # Earlier Darwin versions need -single_module when linking libobjc; they ++ # do not support @rpath. ++ extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' ++ ;; ++ *-darwin*) ++ # Otherwise, single_module is the default and multi-module is ignored and ++ # obsolete. ++ extra_ldflags_libobjc='$(lt_host_flags)' ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wc,-nodefaultrpaths" ++ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wl,-rpath,@loader_path" ++ fi ++ ;; ++ *-cygwin*|*-mingw*) ++ # Tell libtool to build DLLs on Windows ++ extra_ldflags_libobjc='$(lt_host_flags)' ++ ;; ++esac ++AC_SUBST(extra_ldflags_libobjc) ++ + # ------- + # Headers + # ------- +diff --git a/liboffloadmic/configure b/liboffloadmic/configure +index dfa8287fd75..84447cbb7eb 100755 +--- a/liboffloadmic/configure ++++ b/liboffloadmic/configure +@@ -639,6 +639,8 @@ link_offloadmic_host + lt_cv_dlopen_libs + toolexeclibdir + toolexecdir ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + CXXCPP + OTOOL64 + OTOOL +@@ -782,6 +784,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + with_gcc_major_version_only + ' + ac_precious_vars='build_alias +@@ -1434,6 +1437,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -7900,23 +7905,25 @@ _LT_EOF + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 + $as_echo "$lt_cv_ld_force_load" >&6; } +- case $host_os in +- rhapsody* | darwin1.[012]) ++ # Allow for Darwin 4-7 (macOS 10.0-10.3) although these are not expect to ++ # build without first building modern cctools / linker. ++ case $host_cpu-$host_os in ++ *-rhapsody* | *-darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +- darwin1.*) ++ *-darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; +- darwin*) # darwin 5.x on +- # if running on 10.5 or later, the deployment target defaults +- # to the OS version, if on x86, and 10.4, the deployment +- # target defaults to 10.4. Don't you love it? +- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in +- 10.0,*86*-darwin8*|10.0,*-darwin[91]*) +- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ *-darwin*) ++ # darwin 5.x (macOS 10.1) onwards we only need to adjust when the ++ # deployment target is forced to an earlier version. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in ++ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) ++ ;; + 10.[012][,.]*) +- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; +- 10.*) +- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; +- esac ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ *) ++ ;; ++ esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then +@@ -9614,6 +9621,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9631,10 +9679,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11420,7 +11477,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11433 "configure" ++#line 11480 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11526,7 +11583,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11539 "configure" ++#line 11586 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12402,6 +12459,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -12419,12 +12517,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -14265,16 +14376,6 @@ freebsd* | dragonfly*) + esac + ;; + +-gnu*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LD_LIBRARY_PATH +- hardcode_into_libs=yes +- ;; +- + haiku*) + version_type=linux + need_lib_prefix=no +@@ -14396,7 +14497,7 @@ linux*oldld* | linux*aout* | linux*coff*) + # project, but have not yet been accepted: they are GCC-local changes + # for the time being. (See + # https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html) +-linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi) ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi) + version_type=linux + need_lib_prefix=no + need_version=no +@@ -14784,6 +14885,15 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + # Only expand once: + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # Forbid libtool to hardcode RPATH, because we want to be able to specify + # library search directory using LD_LIBRARY_PATH + hardcode_into_libs=no +@@ -14999,6 +15109,10 @@ if test -z "${LIBOFFLOADMIC_HOST_TRUE}" && test -z "${LIBOFFLOADMIC_HOST_FALSE}" + as_fn_error $? "conditional \"LIBOFFLOADMIC_HOST\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/liboffloadmic/configure.ac b/liboffloadmic/configure.ac +index f64f182e8ef..b96e7eaf9e3 100644 +--- a/liboffloadmic/configure.ac ++++ b/liboffloadmic/configure.ac +@@ -118,6 +118,8 @@ esac + + AC_LIBTOOL_DLOPEN + AM_PROG_LIBTOOL ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + # Forbid libtool to hardcode RPATH, because we want to be able to specify + # library search directory using LD_LIBRARY_PATH + hardcode_into_libs=no +diff --git a/liboffloadmic/plugin/Makefile.in b/liboffloadmic/plugin/Makefile.in +index 8d5ad0025c2..c53f2d32b3b 100644 +--- a/liboffloadmic/plugin/Makefile.in ++++ b/liboffloadmic/plugin/Makefile.in +@@ -123,10 +123,10 @@ subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../../config/acx.m4 \ + $(top_srcdir)/../../config/depstand.m4 \ +- $(top_srcdir)/../../config/toolexeclibdir.m4 \ + $(top_srcdir)/../../config/lead-dot.m4 \ + $(top_srcdir)/../../config/multi.m4 \ + $(top_srcdir)/../../config/override.m4 \ ++ $(top_srcdir)/../../config/toolexeclibdir.m4 \ + $(top_srcdir)/../../libtool.m4 \ + $(top_srcdir)/../../ltoptions.m4 \ + $(top_srcdir)/../../ltsugar.m4 \ +diff --git a/liboffloadmic/plugin/aclocal.m4 b/liboffloadmic/plugin/aclocal.m4 +index 9fa1d1216c1..1bb91402f66 100644 +--- a/liboffloadmic/plugin/aclocal.m4 ++++ b/liboffloadmic/plugin/aclocal.m4 +@@ -1169,10 +1169,10 @@ AC_SUBST([am__untar]) + + m4_include([../../config/acx.m4]) + m4_include([../../config/depstand.m4]) +-m4_include([../../config/toolexeclibdir.m4]) + m4_include([../../config/lead-dot.m4]) + m4_include([../../config/multi.m4]) + m4_include([../../config/override.m4]) ++m4_include([../../config/toolexeclibdir.m4]) + m4_include([../../libtool.m4]) + m4_include([../../ltoptions.m4]) + m4_include([../../ltsugar.m4]) +diff --git a/liboffloadmic/plugin/configure b/liboffloadmic/plugin/configure +index 0b21d7d4eed..a9416401a65 100755 +--- a/liboffloadmic/plugin/configure ++++ b/liboffloadmic/plugin/configure +@@ -635,6 +635,8 @@ LIBOBJS + get_gcc_base_ver + toolexeclibdir + toolexecdir ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + CXXCPP + CPP + OTOOL64 +@@ -778,6 +780,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + with_gcc_major_version_only + ' + ac_precious_vars='build_alias +@@ -1431,6 +1434,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -7280,23 +7285,25 @@ _LT_EOF + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 + $as_echo "$lt_cv_ld_force_load" >&6; } +- case $host_os in +- rhapsody* | darwin1.[012]) ++ # Allow for Darwin 4-7 (macOS 10.0-10.3) although these are not expect to ++ # build without first building modern cctools / linker. ++ case $host_cpu-$host_os in ++ *-rhapsody* | *-darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; +- darwin1.*) ++ *-darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; +- darwin*) # darwin 5.x on +- # if running on 10.5 or later, the deployment target defaults +- # to the OS version, if on x86, and 10.4, the deployment +- # target defaults to 10.4. Don't you love it? +- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in +- 10.0,*86*-darwin8*|10.0,*-darwin[91]*) +- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; ++ *-darwin*) ++ # darwin 5.x (macOS 10.1) onwards we only need to adjust when the ++ # deployment target is forced to an earlier version. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in ++ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) ++ ;; + 10.[012][,.]*) +- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; +- 10.*) +- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; +- esac ++ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ *) ++ ;; ++ esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then +@@ -9261,6 +9268,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9278,10 +9326,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11067,7 +11124,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11080 "configure" ++#line 11127 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11173,7 +11230,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11186 "configure" ++#line 11233 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12049,6 +12106,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -12066,12 +12164,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -13912,16 +14023,6 @@ freebsd* | dragonfly*) + esac + ;; + +-gnu*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LD_LIBRARY_PATH +- hardcode_into_libs=yes +- ;; +- + haiku*) + version_type=linux + need_lib_prefix=no +@@ -14043,7 +14144,7 @@ linux*oldld* | linux*aout* | linux*coff*) + # project, but have not yet been accepted: they are GCC-local changes + # for the time being. (See + # https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html) +-linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi) ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi) + version_type=linux + need_lib_prefix=no + need_version=no +@@ -14431,6 +14532,15 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + # Only expand once: + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # Forbid libtool to hardcode RPATH, because we want to be able to specify + # library search directory using LD_LIBRARY_PATH + hardcode_into_libs=no +@@ -14634,6 +14744,10 @@ if test -z "${PLUGIN_HOST_TRUE}" && test -z "${PLUGIN_HOST_FALSE}"; then + as_fn_error $? "conditional \"PLUGIN_HOST\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/liboffloadmic/plugin/configure.ac b/liboffloadmic/plugin/configure.ac +index cbcd0130d05..3329b03638d 100644 +--- a/liboffloadmic/plugin/configure.ac ++++ b/liboffloadmic/plugin/configure.ac +@@ -134,6 +134,8 @@ esac + + AC_LIBTOOL_DLOPEN + AM_PROG_LIBTOOL ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + # Forbid libtool to hardcode RPATH, because we want to be able to specify + # library search directory using LD_LIBRARY_PATH + hardcode_into_libs=no +diff --git a/libphobos/configure b/libphobos/configure +index 9da06f087d0..9fbb3c91e93 100755 +--- a/libphobos/configure ++++ b/libphobos/configure +@@ -707,6 +707,8 @@ get_gcc_base_ver + phobos_compiler_shared_flag + phobos_compiler_pic_flag + phobos_lt_pic_flag ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + OTOOL64 +@@ -838,6 +840,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + with_gcc_major_version_only + enable_werror + with_libatomic +@@ -1490,6 +1493,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-werror turns on -Werror [default=no] + --enable-version-specific-runtime-libs + Specify that runtime libraries should be installed +@@ -9944,6 +9949,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9961,10 +10007,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -11750,7 +11805,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11753 "configure" ++#line 11808 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11856,7 +11911,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11859 "configure" ++#line 11914 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13381,6 +13436,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_D=no + hardcode_direct_D=no + hardcode_automatic_D=yes +@@ -13398,10 +13494,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_D="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_D="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_D="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_D="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_D="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_D="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_D="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_D="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_D="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_D="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_D="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_D="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs_D=no +@@ -14002,6 +14107,14 @@ CFLAGS=$lt_save_CFLAGS + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + # libtool variables for Phobos shared and position-independent compiles. + # +@@ -15726,6 +15839,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${DRUNTIME_CPU_AARCH64_TRUE}" && test -z "${DRUNTIME_CPU_AARCH64_FALSE}"; then + as_fn_error $? "conditional \"DRUNTIME_CPU_AARCH64\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libphobos/configure.ac b/libphobos/configure.ac +index 31209ba2920..cc372587939 100644 +--- a/libphobos/configure.ac ++++ b/libphobos/configure.ac +@@ -93,6 +93,7 @@ AM_PROG_LIBTOOL + WITH_LOCAL_DRUNTIME([LT_LANG([D])], []) + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + # libtool variables for Phobos shared and position-independent compiles. + # +diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am +index 6ca4012b713..861ec0ebc03 100644 +--- a/libphobos/libdruntime/Makefile.am ++++ b/libphobos/libdruntime/Makefile.am +@@ -128,8 +128,11 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ + toolexeclib_LTLIBRARIES = libgdruntime.la + libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES) + libgdruntime_la_LIBTOOLFLAGS = ++if ENABLE_DARWIN_AT_RPATH ++libgdruntime_darwin_rpath = -Wl,-rpath,@loader_path ++endif + libgdruntime_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../src,-Bgcc \ +- -version-info $(libtool_VERSION) ++ -version-info $(libtool_VERSION) $(libgdruntime_darwin_rpath) + libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE) + libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) + # Also override library link commands: This is not strictly +diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in +index f7f78d71ff7..9f3361c7702 100644 +--- a/libphobos/libdruntime/Makefile.in ++++ b/libphobos/libdruntime/Makefile.in +@@ -805,8 +805,9 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ + toolexeclib_LTLIBRARIES = libgdruntime.la + libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES) + libgdruntime_la_LIBTOOLFLAGS = ++@ENABLE_DARWIN_AT_RPATH_TRUE@libgdruntime_darwin_rpath = -Wl,-rpath,@loader_path + libgdruntime_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../src,-Bgcc \ +- -version-info $(libtool_VERSION) ++ -version-info $(libtool_VERSION) $(libgdruntime_darwin_rpath) + + libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE) + libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) +diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am +index da7a2004ff8..a47d985c5b7 100644 +--- a/libphobos/src/Makefile.am ++++ b/libphobos/src/Makefile.am +@@ -44,8 +44,11 @@ toolexeclib_DATA = libgphobos.spec + toolexeclib_LTLIBRARIES = libgphobos.la + libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) + libgphobos_la_LIBTOOLFLAGS = ++if ENABLE_DARWIN_AT_RPATH ++libgphobos_darwin_rpath = -Wl,-rpath,@loader_path ++endif + libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ +- -version-info $(libtool_VERSION) ++ -version-info $(libtool_VERSION) $(libgphobos_darwin_rpath) + if ENABLE_LIBDRUNTIME_ONLY + libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la + else +diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in +index 6f58fee01ac..212ea2469f2 100644 +--- a/libphobos/src/Makefile.in ++++ b/libphobos/src/Makefile.in +@@ -528,8 +528,9 @@ toolexeclib_DATA = libgphobos.spec + toolexeclib_LTLIBRARIES = libgphobos.la + libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) + libgphobos_la_LIBTOOLFLAGS = ++@ENABLE_DARWIN_AT_RPATH_TRUE@libgphobos_darwin_rpath = -Wl,-rpath,@loader_path + libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ +- -version-info $(libtool_VERSION) ++ -version-info $(libtool_VERSION) $(libgphobos_darwin_rpath) + + @ENABLE_LIBDRUNTIME_ONLY_FALSE@libgphobos_la_LIBADD = \ + @ENABLE_LIBDRUNTIME_ONLY_FALSE@ ../libdruntime/libgdruntime_convenience.la $(LIBZ) +diff --git a/libquadmath/Makefile.am b/libquadmath/Makefile.am +index 35dffb46f6e..4bf4bf6eebc 100644 +--- a/libquadmath/Makefile.am ++++ b/libquadmath/Makefile.am +@@ -36,8 +36,13 @@ endif + + toolexeclib_LTLIBRARIES = libquadmath.la + libquadmath_la_LIBADD = ++ ++if ENABLE_DARWIN_AT_RPATH ++libquadmath_darwin_rpath = -Wc,-nodefaultrpaths ++libquadmath_darwin_rpath += -Wl,-rpath,@loader_path ++endif + libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ +- $(version_arg) $(lt_host_flags) -lm ++ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) + libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) + + nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h +diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in +index 8c011212258..b59aac7f1ac 100644 +--- a/libquadmath/Makefile.in ++++ b/libquadmath/Makefile.in +@@ -355,6 +355,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ + INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ + LD = @LD@ + LDFLAGS = @LDFLAGS@ ++LIBM = @LIBM@ + LIBOBJS = @LIBOBJS@ + LIBS = @LIBS@ + LIBTOOL = @LIBTOOL@ +@@ -463,8 +464,10 @@ AUTOMAKE_OPTIONS = foreign info-in-builddir + @BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun + @BUILD_LIBQUADMATH_TRUE@toolexeclib_LTLIBRARIES = libquadmath.la + @BUILD_LIBQUADMATH_TRUE@libquadmath_la_LIBADD = ++@BUILD_LIBQUADMATH_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@libquadmath_darwin_rpath = -Wc,-nodefaultrpaths \ ++@BUILD_LIBQUADMATH_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path + @BUILD_LIBQUADMATH_TRUE@libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ +-@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) -lm ++@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) + + @BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) + @BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h +diff --git a/libquadmath/configure b/libquadmath/configure +index b3ee64f9c7d..23a99be108f 100755 +--- a/libquadmath/configure ++++ b/libquadmath/configure +@@ -644,11 +644,14 @@ LIBQUAD_USE_SYMVER_GNU_FALSE + LIBQUAD_USE_SYMVER_GNU_TRUE + LIBQUAD_USE_SYMVER_FALSE + LIBQUAD_USE_SYMVER_TRUE ++LIBM + toolexeclibdir + toolexecdir + MAINT + MAINTAINER_MODE_FALSE + MAINTAINER_MODE_TRUE ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -785,6 +788,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_maintainer_mode + with_toolexeclibdir + enable_symvers +@@ -1435,6 +1439,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer +@@ -8979,6 +8985,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -8996,10 +9043,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -10806,7 +10862,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10819 "configure" ++#line 10865 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -10912,7 +10968,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10925 "configure" ++#line 10971 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11173,6 +11229,14 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +@@ -12137,6 +12201,148 @@ esac + + + ++LIBM= ++case $host in ++*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*-ncr-sysv4.3*) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5 ++$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; } ++if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lmw $LIBS" ++if test x$gcc_no_link = xyes; then ++ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 ++fi ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char _mwvalidcheckl (); ++int ++main () ++{ ++return _mwvalidcheckl (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_mw__mwvalidcheckl=yes ++else ++ ac_cv_lib_mw__mwvalidcheckl=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5 ++$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; } ++if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then : ++ LIBM="-lmw" ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 ++$as_echo_n "checking for cos in -lm... " >&6; } ++if ${ac_cv_lib_m_cos+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lm $LIBS" ++if test x$gcc_no_link = xyes; then ++ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 ++fi ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char cos (); ++int ++main () ++{ ++return cos (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_m_cos=yes ++else ++ ac_cv_lib_m_cos=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 ++$as_echo "$ac_cv_lib_m_cos" >&6; } ++if test "x$ac_cv_lib_m_cos" = xyes; then : ++ LIBM="$LIBM -lm" ++fi ++ ++ ;; ++*) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 ++$as_echo_n "checking for cos in -lm... " >&6; } ++if ${ac_cv_lib_m_cos+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lm $LIBS" ++if test x$gcc_no_link = xyes; then ++ as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 ++fi ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char cos (); ++int ++main () ++{ ++return cos (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_m_cos=yes ++else ++ ac_cv_lib_m_cos=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 ++$as_echo "$ac_cv_lib_m_cos" >&6; } ++if test "x$ac_cv_lib_m_cos" = xyes; then : ++ LIBM="-lm" ++fi ++ ++ ;; ++esac ++ ++ ++ + for ac_header in fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h + do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +@@ -13031,7 +13237,7 @@ case "$host" in + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs +- # and if assembler supports CET insn. ++ # and if compiler and assembler support CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -13397,6 +13603,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then + as_fn_error $? "conditional \"BUILD_INFO\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libquadmath/configure.ac b/libquadmath/configure.ac +index eec4084a45f..94a3f2179e9 100644 +--- a/libquadmath/configure.ac ++++ b/libquadmath/configure.ac +@@ -59,6 +59,7 @@ AM_PROG_LIBTOOL + ACX_LT_HOST_FLAGS + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + AM_MAINTAINER_MODE + +@@ -121,6 +122,8 @@ esac + AC_SUBST(toolexecdir) + AC_SUBST(toolexeclibdir) + ++AC_CHECK_LIBM ++ + AC_CHECK_HEADERS(fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h) + LIBQUAD_CHECK_MATH_H_SIGNGAM + +diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in +index aab88deb6e8..65e7f2e9553 100644 +--- a/libsanitizer/Makefile.in ++++ b/libsanitizer/Makefile.in +@@ -345,7 +345,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am +index 4f802f723d6..223d3e07816 100644 +--- a/libsanitizer/asan/Makefile.am ++++ b/libsanitizer/asan/Makefile.am +@@ -60,7 +60,12 @@ libasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + endif + libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) + +-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan) ++if ENABLE_DARWIN_AT_RPATH ++libasan_darwin_rpath = -Wc,-nodefaultrpaths ++libasan_darwin_rpath += -Wl,-rpath,@loader_path ++endif ++libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libasan) $(libasan_darwin_rpath) + + libasan_preinit.o: asan_preinit.o + cp $< $@ +diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in +index 2476fbc5a26..e88e5e0b0a7 100644 +--- a/libsanitizer/asan/Makefile.in ++++ b/libsanitizer/asan/Makefile.in +@@ -399,7 +399,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -466,7 +465,12 @@ libasan_la_LIBADD = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(top_builddir)/lsan/libsanitizer_lsan.la $(am__append_2) \ + $(am__append_3) $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libasan_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libasan) $(libasan_darwin_rpath) ++ + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +diff --git a/libsanitizer/configure b/libsanitizer/configure +index 771b135573a..dfd99e34288 100755 +--- a/libsanitizer/configure ++++ b/libsanitizer/configure +@@ -666,6 +666,8 @@ LSAN_SUPPORTED_FALSE + LSAN_SUPPORTED_TRUE + TSAN_SUPPORTED_FALSE + TSAN_SUPPORTED_TRUE ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + CXXCPP +@@ -817,6 +819,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_werror + with_gcc_major_version_only + enable_cet +@@ -1471,6 +1474,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --disable-werror disable building with -Werror + --enable-cet enable Intel CET in target libraries [default=auto] + +@@ -10553,6 +10558,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10570,10 +10616,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12359,7 +12414,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12362 "configure" ++#line 12417 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12465,7 +12520,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12468 "configure" ++#line 12523 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13341,6 +13396,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -13358,12 +13454,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -15763,6 +15872,15 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # The cast to long int works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +@@ -17152,6 +17270,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${TSAN_SUPPORTED_TRUE}" && test -z "${TSAN_SUPPORTED_FALSE}"; then + as_fn_error $? "conditional \"TSAN_SUPPORTED\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac +index 7f1ef3979c4..3549b904c62 100644 +--- a/libsanitizer/configure.ac ++++ b/libsanitizer/configure.ac +@@ -85,6 +85,8 @@ esac + AC_SUBST(enable_shared) + AC_SUBST(enable_static) + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + AC_CHECK_SIZEOF([void *]) + + if test "${multilib}" = "yes"; then +diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am +index e12c0a0ce71..4061078c734 100644 +--- a/libsanitizer/hwasan/Makefile.am ++++ b/libsanitizer/hwasan/Makefile.am +@@ -46,7 +46,11 @@ libhwasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + endif + libhwasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) + +-libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan) ++if ENABLE_DARWIN_AT_RPATH ++libhwasan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ ++endif ++libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libhwasan) $(libhwasan_darwin_rpath) + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in +index 67553f3979d..d20f2dc6eef 100644 +--- a/libsanitizer/hwasan/Makefile.in ++++ b/libsanitizer/hwasan/Makefile.in +@@ -387,7 +387,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -442,7 +441,10 @@ libhwasan_la_SOURCES = $(hwasan_files) + libhwasan_la_LIBADD = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libhwasan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ ++libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libhwasan) $(libhwasan_darwin_rpath) ++ + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in +index bce788aeea7..85dd386de47 100644 +--- a/libsanitizer/interception/Makefile.in ++++ b/libsanitizer/interception/Makefile.in +@@ -317,7 +317,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/libsanitizer/libbacktrace/Makefile.in b/libsanitizer/libbacktrace/Makefile.in +index ece4f11a855..c0243fa4aab 100644 +--- a/libsanitizer/libbacktrace/Makefile.in ++++ b/libsanitizer/libbacktrace/Makefile.in +@@ -367,7 +367,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am +index 6ff28ff5eea..7701b0e18cf 100644 +--- a/libsanitizer/lsan/Makefile.am ++++ b/libsanitizer/lsan/Makefile.am +@@ -41,8 +41,12 @@ if LIBBACKTRACE_SUPPORTED + liblsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + endif + liblsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan) +- ++if ENABLE_DARWIN_AT_RPATH ++liblsan_darwin_rpath = -Wc,-nodefaultrpaths ++liblsan_darwin_rpath += -Wl,-rpath,@loader_path ++endif ++liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_liblsan) $(liblsan_darwin_rpath) + liblsan_preinit.o: lsan_preinit.o + cp $< $@ + +diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in +index 857f244cd86..078edf01fda 100644 +--- a/libsanitizer/lsan/Makefile.in ++++ b/libsanitizer/lsan/Makefile.in +@@ -362,7 +362,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -414,7 +413,12 @@ liblsan_la_LIBADD = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(top_builddir)/interception/libinterception.la \ + $(am__append_1) $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan) ++@ENABLE_DARWIN_AT_RPATH_TRUE@liblsan_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_liblsan) $(liblsan_darwin_rpath) ++ + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +@@ -789,7 +793,6 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS \ + + .PRECIOUS: Makefile + +- + liblsan_preinit.o: lsan_preinit.o + cp $< $@ + +diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in +index c4b009fed83..e5e1c1d51fe 100644 +--- a/libsanitizer/sanitizer_common/Makefile.in ++++ b/libsanitizer/sanitizer_common/Makefile.in +@@ -354,7 +354,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am +index ae588a67df6..47ee50bee1a 100644 +--- a/libsanitizer/tsan/Makefile.am ++++ b/libsanitizer/tsan/Makefile.am +@@ -58,7 +58,11 @@ libtsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + libtsan_la_DEPENDENCIES +=$(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + endif + libtsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan) ++if ENABLE_DARWIN_AT_RPATH ++libtsan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ ++endif ++libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libtsan) $(libtsan_darwin_rpath) + + libtsan_preinit.o: tsan_preinit.o + cp $< $@ +diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in +index 538d2e8eb68..d6efff71e2f 100644 +--- a/libsanitizer/tsan/Makefile.in ++++ b/libsanitizer/tsan/Makefile.in +@@ -391,7 +391,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -466,7 +465,10 @@ libtsan_la_DEPENDENCIES = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(top_builddir)/interception/libinterception.la \ + $(TSAN_TARGET_DEPENDENT_OBJECTS) $(am__append_2) +-libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libtsan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ ++libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libtsan) $(libtsan_darwin_rpath) ++ + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am +index d480f26adc0..7769b3437e4 100644 +--- a/libsanitizer/ubsan/Makefile.am ++++ b/libsanitizer/ubsan/Makefile.am +@@ -36,7 +36,12 @@ if LIBBACKTRACE_SUPPORTED + libubsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la + endif + libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan) ++if ENABLE_DARWIN_AT_RPATH ++libubsan_darwin_rpath = -Wc,-nodefaultrpaths ++libubsan_darwin_rpath += -Wl,-rpath,@loader_path ++endif ++libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libubsan) $(libubsan_darwin_rpath) + + # Use special rules for files that require RTTI support. + ubsan_handlers_cxx.% ubsan_type_hash.% ubsan_type_hash_itanium.% : AM_CXXFLAGS += -frtti +diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in +index 497e0338696..7e51480e970 100644 +--- a/libsanitizer/ubsan/Makefile.in ++++ b/libsanitizer/ubsan/Makefile.in +@@ -356,7 +356,6 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ +-runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -401,7 +400,12 @@ libubsan_la_SOURCES = $(ubsan_files) + libubsan_la_LIBADD = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS) +-libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libubsan_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path ++libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(link_libubsan) $(libubsan_darwin_rpath) ++ + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and +diff --git a/libssp/Makefile.am b/libssp/Makefile.am +index 945dc3c8336..d2a92b3aed1 100644 +--- a/libssp/Makefile.am ++++ b/libssp/Makefile.am +@@ -49,8 +49,12 @@ libssp_la_SOURCES = \ + vsnprintf-chk.c vsprintf-chk.c + libssp_la_LIBADD = + libssp_la_DEPENDENCIES = $(version_dep) $(libssp_la_LIBADD) ++if ENABLE_DARWIN_AT_RPATH ++libssp_darwin_rpath = -Wc,-nodefaultrpaths ++libssp_darwin_rpath += -Wl,-rpath,@loader_path ++endif + libssp_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ +- $(version_arg) $(lt_host_flags) ++ $(version_arg) $(lt_host_flags) $(libssp_darwin_rpath) + + libssp_nonshared_la_SOURCES = \ + ssp-local.c +diff --git a/libssp/Makefile.in b/libssp/Makefile.in +index bc8a0dc2b28..1cf86361b96 100644 +--- a/libssp/Makefile.in ++++ b/libssp/Makefile.in +@@ -376,8 +376,11 @@ libssp_la_SOURCES = \ + + libssp_la_LIBADD = + libssp_la_DEPENDENCIES = $(version_dep) $(libssp_la_LIBADD) ++@ENABLE_DARWIN_AT_RPATH_TRUE@libssp_darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path + libssp_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ +- $(version_arg) $(lt_host_flags) ++ $(version_arg) $(lt_host_flags) $(libssp_darwin_rpath) + + libssp_nonshared_la_SOURCES = \ + ssp-local.c +diff --git a/libssp/configure b/libssp/configure +index 10ba209bde8..5d62fef54a1 100755 +--- a/libssp/configure ++++ b/libssp/configure +@@ -636,6 +636,8 @@ LIBOBJS + get_gcc_base_ver + toolexeclibdir + toolexecdir ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -781,6 +783,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + with_toolexeclibdir + with_gcc_major_version_only + ' +@@ -1426,6 +1429,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -4338,7 +4343,7 @@ case "$host" in + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs +- # and if assembler supports CET insn. ++ # and if compiler and assembler support CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -9165,6 +9170,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -9182,10 +9228,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -10992,7 +11047,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11005 "configure" ++#line 11050 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11098,7 +11153,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 11111 "configure" ++#line 11156 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11376,6 +11431,15 @@ fi + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ ++ + # Calculate toolexeclibdir + # Also toolexecdir, though it's only used in toolexeclibdir + case ${version_specific_libs} in +@@ -11585,6 +11649,10 @@ if test -z "${LIBSSP_USE_SYMVER_SUN_TRUE}" && test -z "${LIBSSP_USE_SYMVER_SUN_F + as_fn_error $? "conditional \"LIBSSP_USE_SYMVER_SUN\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/libssp/configure.ac b/libssp/configure.ac +index f30f81c54f6..90778e2355d 100644 +--- a/libssp/configure.ac ++++ b/libssp/configure.ac +@@ -165,6 +165,8 @@ AC_SUBST(enable_static) + + GCC_WITH_TOOLEXECLIBDIR + ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) ++ + # Calculate toolexeclibdir + # Also toolexecdir, though it's only used in toolexeclibdir + case ${version_specific_libs} in +diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure +index eac60392121..bdaa160dac6 100755 +--- a/libstdc++-v3/configure ++++ b/libstdc++-v3/configure +@@ -786,6 +786,8 @@ GLIBCXX_HOSTED_TRUE + glibcxx_compiler_shared_flag + glibcxx_compiler_pic_flag + glibcxx_lt_pic_flag ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -921,6 +923,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_hosted_libstdcxx + enable_libstdcxx_verbose + enable_libstdcxx_pch +@@ -1608,6 +1611,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --disable-hosted-libstdcxx + only build freestanding C++ runtime support + --disable-libstdcxx-verbose +@@ -10364,6 +10369,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10381,10 +10427,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12191,7 +12246,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12194 "configure" ++#line 12249 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12297,7 +12352,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12300 "configure" ++#line 12355 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13179,6 +13234,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -13196,12 +13292,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -15578,6 +15687,14 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + if test "$enable_vtable_verify" = yes; then + predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o" +@@ -15981,7 +16098,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } + # Fake what AC_TRY_COMPILE does. + + cat > conftest.$ac_ext << EOF +-#line 15984 "configure" ++#line 16101 "configure" + int main() + { + typedef bool atomic_type; +@@ -16016,7 +16133,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } + rm -f conftest* + + cat > conftest.$ac_ext << EOF +-#line 16019 "configure" ++#line 16136 "configure" + int main() + { + typedef short atomic_type; +@@ -16051,7 +16168,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } + rm -f conftest* + + cat > conftest.$ac_ext << EOF +-#line 16054 "configure" ++#line 16171 "configure" + int main() + { + // NB: _Atomic_word not necessarily int. +@@ -16087,7 +16204,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } + rm -f conftest* + + cat > conftest.$ac_ext << EOF +-#line 16090 "configure" ++#line 16207 "configure" + int main() + { + typedef long long atomic_type; +@@ -16243,7 +16360,7 @@ $as_echo "mutex" >&6; } + # unnecessary for this test. + + cat > conftest.$ac_ext << EOF +-#line 16246 "configure" ++#line 16363 "configure" + int main() + { + _Decimal32 d1; +@@ -16285,7 +16402,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + # unnecessary for this test. + + cat > conftest.$ac_ext << EOF +-#line 16288 "configure" ++#line 16405 "configure" + template + struct same + { typedef T2 type; }; +@@ -79038,6 +79155,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${GLIBCXX_HOSTED_TRUE}" && test -z "${GLIBCXX_HOSTED_FALSE}"; then + as_fn_error $? "conditional \"GLIBCXX_HOSTED\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac +index e59bcdb2944..f3dda5a4ff9 100644 +--- a/libstdc++-v3/configure.ac ++++ b/libstdc++-v3/configure.ac +@@ -99,6 +99,7 @@ AM_PROG_LIBTOOL + ACX_LT_HOST_FLAGS + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + if test "$enable_vtable_verify" = yes; then + predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o" +diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host +index ec32980aa0d..da5b1578d91 100644 +--- a/libstdc++-v3/configure.host ++++ b/libstdc++-v3/configure.host +@@ -234,11 +234,6 @@ case "${host_os}" in + darwin8 | darwin8.* ) + # For 8+ compatibility is better if not -flat_namespace. + OPT_LDFLAGS="${OPT_LDFLAGS} -Wl,-single_module" +- case "${host_cpu}" in +- i[34567]86 | x86_64) +- OPTIMIZE_CXXFLAGS="${OPTIMIZE_CXXFLAGS} -fvisibility-inlines-hidden" +- ;; +- esac + os_include_dir="os/bsd/darwin" + ;; + darwin*) +diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am +index 9c3f4aca655..016d68ecd5f 100644 +--- a/libstdc++-v3/src/Makefile.am ++++ b/libstdc++-v3/src/Makefile.am +@@ -133,8 +133,13 @@ libstdc___la_DEPENDENCIES = \ + $(top_builddir)/src/c++17/libc++17convenience.la \ + $(top_builddir)/src/c++20/libc++20convenience.la + ++if ENABLE_DARWIN_AT_RPATH ++libstdc___darwin_rpath = -Wc,-nodefaultrpaths ++libstdc___darwin_rpath += -Wl,-rpath,@loader_path ++endif ++ + libstdc___la_LDFLAGS = \ +- -version-info $(libtool_VERSION) ${version_arg} -lm ++ -version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath) + + libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) + +diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in +index 4a06f6cfec1..0dc6c9650fc 100644 +--- a/libstdc++-v3/src/Makefile.in ++++ b/libstdc++-v3/src/Makefile.in +@@ -546,8 +546,11 @@ libstdc___la_DEPENDENCIES = \ + $(top_builddir)/src/c++17/libc++17convenience.la \ + $(top_builddir)/src/c++20/libc++20convenience.la + ++@ENABLE_DARWIN_AT_RPATH_TRUE@libstdc___darwin_rpath = \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ ++@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path + libstdc___la_LDFLAGS = \ +- -version-info $(libtool_VERSION) ${version_arg} -lm ++ -version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath) + + libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) + @GLIBCXX_LDBL_ALT128_COMPAT_FALSE@@GLIBCXX_LDBL_COMPAT_TRUE@LTCXXCOMPILE64 = $(LTCXXCOMPILE) +diff --git a/libtool.m4 b/libtool.m4 +index 17f8e5f3074..5452de03793 100644 +--- a/libtool.m4 ++++ b/libtool.m4 +@@ -1039,6 +1039,45 @@ _LT_EOF + m4_defun([_LT_DARWIN_LINKER_FEATURES], + [ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ AC_ARG_ENABLE([darwin-at-rpath], ++ AS_HELP_STRING([--enable-darwin-at-path], ++ [install libraries with @rpath/library-name, requires rpaths to be added to executables]), ++ [if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[[45678]]*|UNSET,rhapsody*|10.[[01234]][[,.]]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&AS_MESSAGE_LOG_FD ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi], ++ [case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[[45678]]*|UNSET,rhapsody*|10.[[01234]][[,.]]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[[56789]]*|UNSET,darwin2*|10.1[[123456789]][[,.]]*|1[[123456789]].*[[,.]]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&AS_MESSAGE_LOG_FD ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ]) ++ + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes +@@ -1056,13 +1095,26 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&AS_MESSAGE_LOG_FD ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&AS_MESSAGE_LOG_FD ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + m4_if([$1], [CXX], + [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + ],[]) +@@ -4203,6 +4255,7 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) + ])# _LT_COMPILER_PIC + ++_LT_TAGVAR(enable_darwin_at_rpath, $1)=no + + # _LT_LINKER_SHLIBS([TAGNAME]) + # ---------------------------- +@@ -6441,7 +6494,6 @@ fi # test "$_lt_caught_CXX_error" != yes + AC_LANG_POP + ])# _LT_LANG_CXX_CONFIG + +- + # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) + # --------------------------------- + # Figure out "hidden" library dependencies from verbose +diff --git a/libvtv/configure b/libvtv/configure +index d64b4af5c6b..4280e3b20a9 100755 +--- a/libvtv/configure ++++ b/libvtv/configure +@@ -640,6 +640,8 @@ VTV_CYGMIN_FALSE + VTV_CYGMIN_TRUE + XCFLAGS + libtool_VERSION ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + enable_static + enable_shared + lt_host_flags +@@ -797,6 +799,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + enable_cet + with_gcc_major_version_only + ' +@@ -1446,6 +1449,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-cet enable Intel CET in target libraries [default=auto] + + Optional Packages: +@@ -10448,6 +10453,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10465,10 +10511,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12254,7 +12309,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12267 "configure" ++#line 12312 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12360,7 +12415,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12373 "configure" ++#line 12418 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13236,6 +13291,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes +@@ -13253,12 +13349,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + if test "$lt_cv_apple_cc_single_mod" != "yes"; then +- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}" ++ else ++ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" ++ fi + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + +@@ -15099,16 +15208,6 @@ freebsd* | dragonfly*) + esac + ;; + +-gnu*) +- version_type=linux +- need_lib_prefix=no +- need_version=no +- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' +- soname_spec='${libname}${release}${shared_ext}$major' +- shlibpath_var=LD_LIBRARY_PATH +- hardcode_into_libs=yes +- ;; +- + haiku*) + version_type=linux + need_lib_prefix=no +@@ -15230,7 +15329,7 @@ linux*oldld* | linux*aout* | linux*coff*) + # project, but have not yet been accepted: they are GCC-local changes + # for the time being. (See + # https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html) +-linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi) ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu* | uclinuxfdpiceabi) + version_type=linux + need_lib_prefix=no + need_version=no +@@ -15642,6 +15741,14 @@ esac + + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + # For libtool versioning info, format is CURRENT:REVISION:AGE + libtool_VERSION=1:0:0 +@@ -15672,7 +15779,7 @@ case "$host" in + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs +- # and if assembler supports CET insn. ++ # and if compiler and assembler support CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -15987,6 +16094,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${VTV_CYGMIN_TRUE}" && test -z "${VTV_CYGMIN_FALSE}"; then + as_fn_error $? "conditional \"VTV_CYGMIN\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libvtv/configure.ac b/libvtv/configure.ac +index f3b937e4b10..50aaadbb3a3 100644 +--- a/libvtv/configure.ac ++++ b/libvtv/configure.ac +@@ -153,6 +153,7 @@ AM_PROG_LIBTOOL + ACX_LT_HOST_FLAGS + AC_SUBST(enable_shared) + AC_SUBST(enable_static) ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + # For libtool versioning info, format is CURRENT:REVISION:AGE + libtool_VERSION=1:0:0 +diff --git a/lto-plugin/configure b/lto-plugin/configure +index b820accfd65..8faa13c4a8b 100755 +--- a/lto-plugin/configure ++++ b/lto-plugin/configure +@@ -634,6 +634,8 @@ LTLIBOBJS + LIBOBJS + target_noncanonical + lt_host_flags ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + OTOOL64 + OTOOL + LIPO +@@ -785,6 +787,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + ' + ac_precious_vars='build_alias + host_alias +@@ -1430,6 +1433,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -10275,6 +10280,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -10292,10 +10338,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -12081,7 +12136,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12084 "configure" ++#line 12139 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12187,7 +12242,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12190 "configure" ++#line 12245 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12424,6 +12479,14 @@ CC="$lt_save_CC" + # Only expand once: + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + + +@@ -12670,6 +12733,10 @@ if test -z "${LTO_PLUGIN_USE_SYMVER_SUN_TRUE}" && test -z "${LTO_PLUGIN_USE_SYMV + as_fn_error $? "conditional \"LTO_PLUGIN_USE_SYMVER_SUN\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + + : "${CONFIG_STATUS=./config.status}" + ac_write_fail=0 +diff --git a/lto-plugin/configure.ac b/lto-plugin/configure.ac +index bc5b618a495..317596288b2 100644 +--- a/lto-plugin/configure.ac ++++ b/lto-plugin/configure.ac +@@ -88,6 +88,7 @@ AM_CONDITIONAL(LTO_PLUGIN_USE_SYMVER_GNU, [test "x$lto_plugin_use_symver" = xgnu + AM_CONDITIONAL(LTO_PLUGIN_USE_SYMVER_SUN, [test "x$lto_plugin_use_symver" = xsun]) + + AM_PROG_LIBTOOL ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + ACX_LT_HOST_FLAGS + AC_SUBST(target_noncanonical) + AC_TYPE_INT64_T +diff --git a/zlib/configure b/zlib/configure +index f489f31bc70..f7adce0db2c 100755 +--- a/zlib/configure ++++ b/zlib/configure +@@ -639,6 +639,8 @@ TARGET_LIBRARY_FALSE + TARGET_LIBRARY_TRUE + toolexeclibdir + toolexecdir ++ENABLE_DARWIN_AT_RPATH_FALSE ++ENABLE_DARWIN_AT_RPATH_TRUE + CPP + OTOOL64 + OTOOL +@@ -776,6 +778,7 @@ with_pic + enable_fast_install + with_gnu_ld + enable_libtool_lock ++enable_darwin_at_rpath + with_toolexeclibdir + enable_host_shared + ' +@@ -1419,6 +1422,8 @@ Optional Features: + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-darwin-at-path install libraries with @rpath/library-name, requires ++ rpaths to be added to executables + --enable-host-shared build host code as shared libraries + + Optional Packages: +@@ -4169,7 +4174,7 @@ case "$host" in + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs +- # and if assembler supports CET insn. ++ # and if compiler and assembler support CET insn. + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +@@ -8908,6 +8913,47 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + darwin* | rhapsody*) + + ++ ++ # Publish an arg to allow the user to select that Darwin host (and target) ++ # libraries should be given install-names like @rpath/libfoo.dylib. This ++ # requires that the user of the library then adds an 'rpath' to the DSO that ++ # needs access. ++ # NOTE: there are defaults below, for systems that support rpaths. The person ++ # configuring can override the defaults for any system version that supports ++ # them - they are, however, forced off for system versions without support. ++ # Check whether --enable-darwin-at-rpath was given. ++if test "${enable_darwin_at_rpath+set}" = set; then : ++ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then ++ # This is not supported before macOS 10.5 / Darwin9. ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&5 ++ enable_darwin_at_rpath=no ++ ;; ++ esac ++ fi ++else ++ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in ++ # As above, before 10.5 / Darwin9 this does not work. ++ UNSET,darwin[45678]*|UNSET,rhapsody*|10.[01234][,.]*) ++ enable_darwin_at_rpath=no ++ ;; ++ ++ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use ++ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key ++ # system executables (e.g. /bin/sh). Force rpaths on for these systems. ++ UNSET,darwin1[56789]*|UNSET,darwin2*|10.1[123456789][,.]*|1[123456789].*[,.]* ) ++ echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&5 ++ enable_darwin_at_rpath=yes ++ ;; ++ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can ++ # work with either DYLD_LIBRARY_PATH or embedded rpaths. ++ ++ esac ++ ++fi ++ ++ + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes +@@ -8925,10 +8971,19 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all +- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" +- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" +- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" +- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ if test "x$enable_darwin_at_rpath" = "xyes"; then ++ echo "using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ else ++ echo "NOT using Darwin @rpath" 1>&5 ++ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" ++ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" ++ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" ++ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" ++ fi + + else + ld_shlibs=no +@@ -10735,7 +10790,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10748 "configure" ++#line 10793 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -10841,7 +10896,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 10854 "configure" ++#line 10899 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -11078,6 +11133,14 @@ CC="$lt_save_CC" + # Only expand once: + + ++ if test x$enable_darwin_at_rpath = xyes; then ++ ENABLE_DARWIN_AT_RPATH_TRUE= ++ ENABLE_DARWIN_AT_RPATH_FALSE='#' ++else ++ ENABLE_DARWIN_AT_RPATH_TRUE='#' ++ ENABLE_DARWIN_AT_RPATH_FALSE= ++fi ++ + + # Find CPP now so that any conditional tests below won't do it and + # thereby make the resulting definitions conditional. +@@ -11708,6 +11771,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then ++ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${TARGET_LIBRARY_TRUE}" && test -z "${TARGET_LIBRARY_FALSE}"; then + as_fn_error $? "conditional \"TARGET_LIBRARY\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/zlib/configure.ac b/zlib/configure.ac +index be1cfe29651..2327d003a05 100644 +--- a/zlib/configure.ac ++++ b/zlib/configure.ac +@@ -64,6 +64,7 @@ GCC_CET_FLAGS(CET_FLAGS) + AC_SUBST(CET_FLAGS) + + AC_PROG_LIBTOOL ++AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + + # Find CPP now so that any conditional tests below won't do it and + # thereby make the resulting definitions conditional. From 49c407b9a63bbf42650eb72c07af2e4c5389207f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 17:41:44 -0700 Subject: [PATCH 130/350] build/pkgs/gcc/spkg-build.in: Remove workarounds for ancient OS X --- build/pkgs/gcc/spkg-build.in | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/build/pkgs/gcc/spkg-build.in b/build/pkgs/gcc/spkg-build.in index 2c07c4ea988..215201207d6 100644 --- a/build/pkgs/gcc/spkg-build.in +++ b/build/pkgs/gcc/spkg-build.in @@ -1,41 +1,6 @@ # Exit on error set -e -# The ld (linker) on old Darwin systems doesn't understand -# -compatibility_version, it needs -dylib_compatibility_version. -# Similarly for a few more options. We create an ld wrapper to fix -# these command line options. -if { uname -sr | grep 'Darwin [0-9]\.' ;} &>/dev/null; then - mkdir -p bin/ - LD=`which "${LD:-ld}"` - - echo '#!/bin/bash' >>"bin/ld" - echo '# ld wrapper generated by the GCC spkg' >>"bin/ld" - echo >>"bin/ld" - # Hardcode the path to the "real" ld. - echo "LD=$LD" >>"bin/ld" - -cat >>"bin/ld" <<'EOF' - -for arg in "$@"; do - arg=`echo "$arg" | sed \ - -e 's/^-\(compatibility_version\)/-dylib_\1/' \ - -e 's/^-\(current_version\)/-dylib_\1/' \ - -e 's/^-\(install_name\)/-dylib_\1/' \ - ` - argv=("${argv[@]}" "$arg") -done - -exec "$LD" "${argv[@]}" -EOF - - chmod +x "bin/ld" - - # Make GCC use this ld wrapper (found in the $PATH) - export LD=ld - export PATH="$(pwd)/bin:$PATH" -fi - # On OS X 10.9, g++ and the cdefs.h header are currently incompatible # Temporary workaround posted at http://trac.macports.org/ticket/41033 if { uname -sr | grep 'Darwin 13\.' ;} &>/dev/null; then From ba6de8339036d621352d9baacc0efb4591f52fe3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 18:58:20 -0700 Subject: [PATCH 131/350] build/pkgs/gcc/build-gcc: Unset AS, LD --- build/pkgs/gcc/build-gcc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pkgs/gcc/build-gcc b/build/pkgs/gcc/build-gcc index 1b3c72b1298..a185603d453 100755 --- a/build/pkgs/gcc/build-gcc +++ b/build/pkgs/gcc/build-gcc @@ -54,9 +54,11 @@ fi if [ -n "$AS" -a "$AS" != "as" ]; then CONFIGURE_AS="--with-as=$AS" fi +unset AS if [ -n "$LD" -a "$LD" != "ld" ]; then CONFIGURE_LD="--with-ld=$LD" fi +unset LD # Use SAGE_CXX_WITHOUT_STD instead of CXX. # This fixes #29162 (gfortran 9.2.0 compile error on debian-jessie with gcc 4.9.2) From 5d9563be5c4853d61e4127b19c9c3bd1e1468f7a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 19:28:51 -0700 Subject: [PATCH 132/350] build/pkgs/gfortran/spkg-build.in: Work around build failure with Apple gcc (clang) --- build/pkgs/gfortran/spkg-build.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/gfortran/spkg-build.in b/build/pkgs/gfortran/spkg-build.in index ac74c12ad5c..bf4ce381cfe 100644 --- a/build/pkgs/gfortran/spkg-build.in +++ b/build/pkgs/gfortran/spkg-build.in @@ -8,4 +8,4 @@ case $(uname -m),"$ARCH" in ;; esac -./build-gcc --disable-bootstrap --enable-languages=fortran $EXTRA_GCC_CONFIGURE +./build-gcc --disable-bootstrap --enable-languages=fortran --disable-darwin-at-rpath $EXTRA_GCC_CONFIGURE From 6e6af03773b262fd791c8dd5aeaf2256bdc84adc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Sep 2022 20:24:03 -0700 Subject: [PATCH 133/350] build/pkgs/openblas: Update to 0.3.21 --- build/pkgs/openblas/checksums.ini | 6 +++--- build/pkgs/openblas/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/openblas/checksums.ini b/build/pkgs/openblas/checksums.ini index eb87a1d197d..e6e83e7d891 100644 --- a/build/pkgs/openblas/checksums.ini +++ b/build/pkgs/openblas/checksums.ini @@ -1,5 +1,5 @@ tarball=openblas-VERSION.tar.gz -sha1=45ec54b75f53f5b704250e60bd8e82a49b430619 -md5=abfaa43d995046ca4c56ccf14165c93c -cksum=3182749926 +sha1=b052d196ad694b29302e074b3eb8cc66745f6e2f +md5=ffb6120e2309a2280471716301824805 +cksum=241092070 upstream_url=https://github.com/xianyi/OpenBLAS/archive/vVERSION.tar.gz diff --git a/build/pkgs/openblas/package-version.txt b/build/pkgs/openblas/package-version.txt index f9a4b5f993c..dfdc368868b 100644 --- a/build/pkgs/openblas/package-version.txt +++ b/build/pkgs/openblas/package-version.txt @@ -1 +1 @@ -0.3.20 +0.3.21 From 86bb4bf346761997c86983ef2669f8f68361bc95 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 21 Sep 2022 15:30:37 +0900 Subject: [PATCH 134/350] Making things more lazy with invert. --- src/sage/data_structures/stream.py | 100 ++++++++++++++++++----------- src/sage/rings/lazy_series.py | 24 +++++-- src/sage/rings/lazy_series_ring.py | 3 +- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index cbef85d64dd..9c52e581e95 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -98,6 +98,7 @@ from sage.rings.infinity import infinity from sage.arith.misc import divisors from sage.misc.misc_c import prod +from sage.misc.lazy_attribute import lazy_attribute from sage.combinat.integer_vector_weighted import iterator_fast as wt_int_vec_iter from sage.combinat.sf.sfa import _variables_recursive, _raise_variables from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis @@ -142,7 +143,6 @@ def __ne__(self, other): False sage: CS != Stream(False, -2) False - """ return False @@ -1650,9 +1650,31 @@ def __init__(self, series): raise ZeroDivisionError("the Dirichlet inverse only exists if the coefficient with index 1 is non-zero") super().__init__(series, series._is_sparse, 1) - self._ainv = None self._zero = ZZ.zero() + @lazy_attribute + def _ainv(self): + """ + The inverse of the leading coefficient. + + EXAMPLES:: + + sage: from sage.data_structures.stream import (Stream_exact, Stream_dirichlet_invert) + sage: f = Stream_exact([0, 3], True, constant=2) + sage: g = Stream_dirichlet_invert(f) + sage: g._ainv + 1/3 + + sage: f = Stream_exact([Zmod(6)(5)], False, constant=2) + sage: g = Stream_dirichlet_invert(f) + sage: g._ainv + 5 + """ + try: + return ~self._series[1] + except TypeError: + return self._series[1].inverse_of_unit() + def get_coefficient(self, n): """ Return the ``n``-th coefficient of ``self``. @@ -1671,11 +1693,6 @@ def get_coefficient(self, n): sage: [g[i] for i in range(8)] [0, 1/3, -2/9, -2/9, -2/27, -2/9, 2/27, -2/9] """ - if self._ainv is None: - try: - self._ainv = ~self._series[1] - except TypeError: - self._ainv = self._series[1].inverse_of_unit() if n == 1: return self._ainv c = self._zero @@ -2298,7 +2315,6 @@ class Stream_cauchy_invert(Stream_unary): sage: g = Stream_cauchy_invert(f) sage: [g[i] for i in range(10)] [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0] - """ def __init__(self, series, approximate_order=None): """ @@ -2310,19 +2326,42 @@ def __init__(self, series, approximate_order=None): sage: f = Stream_exact([1, -1], False) sage: g = Stream_cauchy_invert(f) """ - if approximate_order is None: - v = series.order() - try: - self._ainv = ~series[v] - except TypeError: - self._ainv = series[v].inverse_of_unit() + if series._true_order: + v = -series._approximate_order + self._true_order = True + elif approximate_order is None: + v = -series._approximate_order else: - v = approximate_order - self._ainv = None - - super().__init__(series, series._is_sparse, -v) + v = -approximate_order + super().__init__(series, series._is_sparse, v) self._zero = ZZ.zero() + @lazy_attribute + def _ainv(self): + r""" + The inverse of the leading coefficient. + + EXAMPLES:: + + sage: from sage.data_structures.stream import (Stream_cauchy_invert, Stream_exact) + sage: f = Stream_exact([2, -3], False) + sage: g = Stream_cauchy_invert(f) + sage: g._ainv + 1/2 + + sage: f = Stream_exact([Zmod(6)(5)], False, constant=2) + sage: g = Stream_cauchy_invert(f) + sage: g._ainv + 5 + """ + v = -self._series.order() + self._approximate_order = v + self._true_order = True + try: + return ~self._series[v] + except TypeError: + return self._series[v].inverse_of_unit() + def get_coefficient(self, n): """ Return the ``n``-th coefficient of ``self``. @@ -2341,16 +2380,11 @@ def get_coefficient(self, n): sage: [g.get_coefficient(i) for i in range(10)] [-2, 1, 0, 0, 0, 0, 0, 0, 0, 0] """ - if self._ainv is None: - self._approximate_order = -self._series.order() - try: - self._ainv = ~self._series[self._approximate_order] - except TypeError: - self._ainv = self._series[self._approximate_order].inverse_of_unit() - - # if self._ainv is not None, self._approximate_order is the - # true order + if not self._series._true_order: + self._ainv # this computes the true order of ``self`` v = self._approximate_order + if n < v: + return ZZ.zero() if n == v: return self._ainv @@ -2374,18 +2408,10 @@ def iterate_coefficients(self): sage: [next(n) for i in range(10)] [1, -4, 7, -8, 8, -8, 8, -8, 8, -8] """ - if self._ainv is None: - self._approximate_order = -self._series.order() - try: - self._ainv = ~self._series[self._approximate_order] - except TypeError: - self._ainv = self._series[self._approximate_order].inverse_of_unit() - - # if self._ainv is not None, self._approximate_order is the - # true order + yield self._ainv + # This is the true order, which is computed in self._ainv v = self._approximate_order n = 0 # Counts the number of places from v. - yield self._ainv # Note that the first entry of the cache will correspond to # z^v, when the stream corresponds to a Laurent series. diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 26d74121416..c4972aec939 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -668,6 +668,11 @@ def shift(self, n): sage: f.shift(5).shift(-5) - f 0 + sage: L. = LazyPowerSeriesRing(QQ) + sage: f = x.shift(-3); f + x^-2 + sage: f.parent() + Lazy Laurent Series Ring in x over Rational Field """ if isinstance(self._coeff_stream, Stream_zero): return self @@ -687,6 +692,10 @@ def shift(self, n): else: coeff_stream = Stream_shift(self._coeff_stream, n) P = self.parent() + # If we shift it too much, then it needs to go into the fraction field + # FIXME? This is different than the polynomial rings, which truncates the terms + if coeff_stream._true_order and coeff_stream._approximate_order < P._minimal_valuation: + P = P.fraction_field() return P.element_class(P, coeff_stream) __lshift__ = shift @@ -3697,16 +3706,21 @@ def revert(self): raise ValueError("compositional inverse does not exist") raise ValueError("cannot determine whether the compositional inverse exists") - if not coeff_stream[1]: + if coeff_stream._approximate_order > 1: raise ValueError("compositional inverse does not exist") - if coeff_stream[0]: - raise ValueError("cannot determine whether the compositional inverse exists") + #if not coeff_stream[1]: + # raise ValueError("compositional inverse does not exist") + + #if coeff_stream[0]: + # raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() g = P.undefined(valuation=1) - # TODO: shift instead of (self / z) should be more efficient - g.define(z / ((self / z)(g))) + # The following is mathematically equivalent to + # z / ((self / z)(g)) + # but more efficient and more lazy. + g.define((~self.shift(-1)(g)).shift(1)) return g compositional_inverse = revert diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 25f6a0e0278..8ab786a60a3 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -2051,7 +2051,8 @@ class LazyCompletionGradedAlgebra(LazySeriesRing): Element = LazyCompletionGradedAlgebraElement def __init__(self, basis, sparse=True, category=None): - """Initialize ``self``. + """ + Initialize ``self``. TESTS:: From 472bd3c8eb254222227b593c9c8154541e0c2d98 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 21 Sep 2022 15:27:53 +0200 Subject: [PATCH 135/350] switch to lazy evaluation of the approximate order --- src/sage/data_structures/stream.py | 277 ++++++++++++++++++++--------- src/sage/rings/lazy_series.py | 54 ++++-- src/sage/rings/lazy_series_ring.py | 8 +- 3 files changed, 234 insertions(+), 105 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 9c52e581e95..adb58515cb6 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -111,11 +111,29 @@ class Stream(): INPUT: - ``sparse`` -- boolean; whether the implementation of the stream is sparse - - ``approximate_order`` -- integer; a lower bound for the order - of the stream - ``true_order`` -- boolean; if the approximate order is the actual order + + .. NOTE:: + + An implementation of a stream class depending on other stream + classes must not access coefficients or the approximate order + of these, in order not to interfere with lazy definitions for + :class:`Stream_uninitialized`. + + If an approximate order or even the true order is known, it + must be set after calling ``super().__init__``. + + Otherwise, a lazy attribute `_approximate_order` has to be + defined. Any initialization code depending on the + approximate orders of input streams can be put into this + definition. + + However, keep in mind that (trivially) this initialization + code is not executed if `_approximate_order` is set to a + value before it is accessed. + """ - def __init__(self, sparse, approximate_order, true_order=False): + def __init__(self, sparse, true_order): """ Initialize ``self``. @@ -125,9 +143,12 @@ def __init__(self, sparse, approximate_order, true_order=False): sage: CS = Stream(True, 1) """ self._is_sparse = sparse - self._approximate_order = approximate_order self._true_order = true_order + @lazy_attribute + def _approximate_order(self): + raise NotImplementedError + def __ne__(self, other): """ Check inequality of ``self`` and ``other``. @@ -162,6 +183,7 @@ def is_nonzero(self): """ return False + class Stream_inexact(Stream): """ An abstract base class for the stream when we do not know it is @@ -182,7 +204,7 @@ class Stream_inexact(Stream): will allow shortcuts. """ - def __init__(self, is_sparse, approximate_order): + def __init__(self, is_sparse, true_order): """ Initialize the stream class for a stream whose coefficients are not necessarily eventally constant. @@ -196,15 +218,20 @@ def __init__(self, is_sparse, approximate_order): True """ - super().__init__(is_sparse, approximate_order) - + super().__init__(is_sparse, true_order) if self._is_sparse: self._cache = dict() # cache of known coefficients else: self._cache = list() - self._offset = approximate_order # self[n] = self._cache[n-self._offset] self._iter = self.iterate_coefficients() + @lazy_attribute + def _offset(self): + # self[n] = self._cache[n-self._offset] + if self._is_sparse: + raise ValueError("_offset is only for sparse streams") + return self._approximate_order + def is_nonzero(self): r""" Return ``True`` if and only if the cache contains a nonzero element. @@ -604,7 +631,6 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, # insist that the last entry of initial_coefficients is # different from constant, because __eq__ below would become # complicated otherwise - for i, v in enumerate(initial_coefficients): if v: # We have found the first nonzero coefficient @@ -630,7 +656,8 @@ def __init__(self, initial_coefficients, is_sparse, constant=None, degree=None, assert self._initial_coefficients or self._constant, "Stream_exact should only be used for non-zero streams" - super().__init__(is_sparse, order, true_order=True) + super().__init__(is_sparse, True) + self._approximate_order = order def __getitem__(self, n): """ @@ -862,7 +889,7 @@ class Stream_iterator(Stream_inexact): [0, 0, 1, 2, 3, 4, 5, 6, 7, 8] """ - def __init__(self, iter, approximate_order): + def __init__(self, iter, approximate_order, true_order=False): """ Initialize. @@ -873,7 +900,8 @@ def __init__(self, iter, approximate_order): sage: TestSuite(f).run(skip="_test_pickling") """ self.iterate_coefficients = lambda: iter - super().__init__(False, approximate_order) + super().__init__(False, true_order) + self._approximate_order = approximate_order class Stream_function(Stream_inexact): @@ -906,7 +934,7 @@ class Stream_function(Stream_inexact): sage: f.get_coefficient(4) 4 """ - def __init__(self, function, is_sparse, approximate_order): + def __init__(self, function, is_sparse, approximate_order, true_order=False): """ Initialize. @@ -917,7 +945,8 @@ def __init__(self, function, is_sparse, approximate_order): sage: TestSuite(f).run(skip="_test_pickling") """ self.get_coefficient = function - super().__init__(is_sparse, approximate_order) + super().__init__(is_sparse, true_order) + self._approximate_order = approximate_order class Stream_uninitialized(Stream_inexact): @@ -941,7 +970,7 @@ class Stream_uninitialized(Stream_inexact): sage: C.get_coefficient(4) 0 """ - def __init__(self, is_sparse, approximate_order): + def __init__(self, is_sparse, approximate_order, true_order=False): """ Initialize ``self``. @@ -954,7 +983,8 @@ def __init__(self, is_sparse, approximate_order): self._target = None if approximate_order is None: raise ValueError("the valuation must be specified for undefined series") - super().__init__(is_sparse, approximate_order) + super().__init__(is_sparse, true_order) + self._approximate_order = approximate_order def get_coefficient(self, n): """ @@ -1019,7 +1049,7 @@ class Stream_unary(Stream_inexact): [0, 4, 8, 12, 16, 20, 24, 28, 32, 36] """ - def __init__(self, series, *args, **kwargs): + def __init__(self, series, is_sparse): """ Initialize ``self``. @@ -1034,7 +1064,7 @@ def __init__(self, series, *args, **kwargs): sage: TestSuite(g).run() """ self._series = series - super().__init__(*args, **kwargs) + super().__init__(is_sparse, False) def __hash__(self): """ @@ -1044,7 +1074,7 @@ def __hash__(self): sage: from sage.data_structures.stream import Stream_unary sage: from sage.data_structures.stream import Stream_function - sage: M = Stream_unary(Stream_function(lambda n: 1, False, 1), True, 0) + sage: M = Stream_unary(Stream_function(lambda n: 1, False, 1), True) sage: hash(M) == hash(M) True """ @@ -1097,7 +1127,7 @@ class Stream_binary(Stream_inexact): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ - def __init__(self, left, right, *args, **kwargs): + def __init__(self, left, right, is_sparse): """ Initialize ``self``. @@ -1116,7 +1146,7 @@ def __init__(self, left, right, *args, **kwargs): """ self._left = left self._right = right - super().__init__(*args, **kwargs) + super().__init__(is_sparse, False) def __hash__(self): """ @@ -1128,7 +1158,7 @@ def __hash__(self): sage: from sage.data_structures.stream import Stream_function sage: M = Stream_function(lambda n: n, True, 0) sage: N = Stream_function(lambda n: -2*n, True, 0) - sage: O = Stream_binary(M, N, True, 0) + sage: O = Stream_binary(M, N, True) sage: hash(O) == hash(O) True """ @@ -1244,17 +1274,22 @@ class Stream_zero(Stream): 0 """ - def __init__(self, sparse): - """ - Initialize ``self``. + def __init__(self, is_sparse): + """Initialize ``self``. TESTS:: sage: from sage.data_structures.stream import Stream_zero sage: s = Stream_zero(False) sage: TestSuite(s).run() + + .. TODO:: + + Having ``is_sparse`` as argument here does not really + make sense, since this stream does not cache values. """ - return super().__init__(sparse, infinity, true_order=infinity) + super().__init__(is_sparse, True) + self._approximate_order = infinity def __getitem__(self, n): """ @@ -1356,9 +1391,12 @@ def __init__(self, left, right): """ if left._is_sparse != right._is_sparse: raise NotImplementedError + super().__init__(left, right, left._is_sparse) - a = min(left._approximate_order, right._approximate_order) - super().__init__(left, right, left._is_sparse, a) + @lazy_attribute + def _approximate_order(self): + # this is not the true order, because we may have cancellation + return min(self._left._approximate_order, self._right._approximate_order) def get_coefficient(self, n): """ @@ -1403,7 +1441,6 @@ class Stream_sub(Stream_binary): sage: [u[i] for i in range(10)] [1, 0, -1, -2, -3, -4, -5, -6, -7, -8] """ - def __init__(self, left, right): """ initialize ``self``. @@ -1417,9 +1454,12 @@ def __init__(self, left, right): """ if left._is_sparse != right._is_sparse: raise NotImplementedError + super().__init__(left, right, left._is_sparse) - a = min(left._approximate_order, right._approximate_order) - super().__init__(left, right, left._is_sparse, a) + @lazy_attribute + def _approximate_order(self): + # this is not the true order, because we may have cancellation + return min(self._left._approximate_order, self._right._approximate_order) def get_coefficient(self, n): """ @@ -1481,9 +1521,12 @@ def __init__(self, left, right): """ if left._is_sparse != right._is_sparse: raise NotImplementedError + super().__init__(left, right, left._is_sparse) - a = left._approximate_order + right._approximate_order - super().__init__(left, right, left._is_sparse, a) + @lazy_attribute + def _approximate_order(self): + # this is not the true order, unless we have an integral domain + return self._left._approximate_order + self._right._approximate_order def get_coefficient(self, n): """ @@ -1567,24 +1610,30 @@ def __init__(self, left, right): sage: from sage.data_structures.stream import (Stream_dirichlet_convolve, Stream_function, Stream_exact) sage: f = Stream_function(lambda n: n, True, 1) sage: g = Stream_exact([1], True, constant=0) - sage: Stream_dirichlet_convolve(f, g) + sage: h = Stream_dirichlet_convolve(f, g) + sage: h[1] Traceback (most recent call last): ... - AssertionError: Dirichlet convolution is only defined for coefficient streams with minimal index of nonzero coefficient at least 1 - sage: Stream_dirichlet_convolve(g, f) + ValueError: Dirichlet convolution is only defined for coefficient streams with minimal index of nonzero coefficient at least 1 + sage: h = Stream_dirichlet_convolve(g, f) + sage: h[1] Traceback (most recent call last): ... - AssertionError: Dirichlet convolution is only defined for coefficient streams with minimal index of nonzero coefficient at least 1 + ValueError: Dirichlet convolution is only defined for coefficient streams with minimal index of nonzero coefficient at least 1 """ if left._is_sparse != right._is_sparse: raise NotImplementedError + super().__init__(left, right, left._is_sparse) - assert left._approximate_order > 0 and right._approximate_order > 0, "Dirichlet convolution is only defined for coefficient streams with minimal index of nonzero coefficient at least 1" - - vl = left._approximate_order - vr = right._approximate_order - a = vl * vr - super().__init__(left, right, left._is_sparse, a) + @lazy_attribute + def _approximate_order(self): + # this is not the true order, unless we have an integral domain + if (self._left._approximate_order <= 0 + or self._right._approximate_order <= 0): + raise ValueError("Dirichlet convolution is only defined for " + "coefficient streams with minimal index of " + "nonzero coefficient at least 1") + return self._left._approximate_order * self._right._approximate_order def get_coefficient(self, n): """ @@ -1642,16 +1691,23 @@ def __init__(self, series): sage: from sage.data_structures.stream import (Stream_exact, Stream_dirichlet_invert) sage: f = Stream_exact([0, 0], True, constant=1) sage: g = Stream_dirichlet_invert(f) + sage: g[1] Traceback (most recent call last): ... ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero """ - if series._approximate_order > 1: - raise ZeroDivisionError("the Dirichlet inverse only exists if the coefficient with index 1 is non-zero") - - super().__init__(series, series._is_sparse, 1) + super().__init__(series, series._is_sparse) self._zero = ZZ.zero() + @lazy_attribute + def _approximate_order(self): + # this is the true order, but we want to check first + if self._series._approximate_order > 1: + raise ZeroDivisionError("the Dirichlet inverse only exists if the " + "coefficient with index 1 is non-zero") + self._true_order = True + return 1 + @lazy_attribute def _ainv(self): """ @@ -1665,7 +1721,7 @@ def _ainv(self): sage: g._ainv 1/3 - sage: f = Stream_exact([Zmod(6)(5)], False, constant=2) + sage: f = Stream_exact([Zmod(6)(5)], False, constant=2, order=1) sage: g = Stream_dirichlet_invert(f) sage: g._ainv 5 @@ -1740,17 +1796,30 @@ def __init__(self, f, g): """ if g._true_order and g._approximate_order <= 0: raise ValueError("can only compose with a series of positive valuation") - if f._approximate_order < 0: - ginv = Stream_cauchy_invert(g) + super().__init__(f, g, f._is_sparse) + + @lazy_attribute + def _approximate_order(self): + """ + .. TODO:: + + check similarities with :class:`Stream_plethysm` + """ + # this is very likely not the true order + if self._right._approximate_order <= 0: + raise ValueError("can only compose with a series of positive valuation") + + if self._left._approximate_order < 0: + ginv = Stream_cauchy_invert(self._right) # The constant part makes no contribution to the negative. # We need this for the case so self._neg_powers[0][n] => 0. - self._neg_powers = [Stream_zero(f._is_sparse), ginv] - for i in range(1, -f._approximate_order): + self._neg_powers = [Stream_zero(self._left._is_sparse), ginv] + for i in range(1, -self._left._approximate_order): self._neg_powers.append(Stream_cauchy_mul(self._neg_powers[-1], ginv)) # placeholder None to make this 1-based. - self._pos_powers = [None, g] - val = f._approximate_order * g._approximate_order - super().__init__(f, g, f._is_sparse, val) + self._pos_powers = [None, self._right] + + return self._left._approximate_order * self._right._approximate_order def get_coefficient(self, n): """ @@ -1773,6 +1842,7 @@ def get_coefficient(self, n): """ fv = self._left._approximate_order gv = self._right._approximate_order + _ = self._approximate_order # this is only to trigger the initialization if n < 0: return sum(self._left[i] * self._neg_powers[-i][n] for i in range(fv, n // gv + 1)) @@ -1889,10 +1959,10 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): self._degree_f = f._degree else: self._degree_f = None + if g._true_order and g._approximate_order == 0 and self._degree_f is None: raise ValueError("can only compute plethysm with a series of valuation 0 for symmetric functions of finite support") - val = f._approximate_order * g._approximate_order if ring is None: self._basis = p else: @@ -1910,7 +1980,17 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): else: self._tensor_power = None f = Stream_map_coefficients(f, lambda x: p(x)) - super().__init__(f, g, f._is_sparse, val) + super().__init__(f, g, f._is_sparse) + + @lazy_attribute + def _approximate_order(self): + # this is very likely not the true order +# if self._right._approximate_order == 0 and self._degree_f is None: +# raise ValueError("can only compute plethysm with a series of " +# " valuation 0 for symmetric functions of finite " +# " support") + return self._left._approximate_order * self._right._approximate_order + def get_coefficient(self, n): r""" @@ -2064,7 +2144,16 @@ def stretched_power_restrict_degree(self, i, m, d): class Stream_scalar(Stream_inexact): """ - Base class for operators multiplying a coefficient stream by a scalar. + Base class for operators multiplying a coefficient stream by a + scalar. + + .. TODO:: + + This does not inherit from :class:`Stream_unary`, because of + the extra argument ``scalar``. However, we could also + override :meth:`Stream_unary.hash`, + :meth:`Stream_unary.__eq__`. Would this be any better? + """ def __init__(self, series, scalar): """ @@ -2079,7 +2168,12 @@ def __init__(self, series, scalar): self._series = series self._scalar = scalar assert scalar, "the scalar must not be equal to 0" - super().__init__(series._is_sparse, series._approximate_order) + super().__init__(series._is_sparse, series._true_order) + + @lazy_attribute + def _approximate_order(self): + # this is not the true order, unless we have an integral domain + return self._series._approximate_order def __hash__(self): """ @@ -2253,7 +2347,13 @@ def __init__(self, series): sage: f = Stream_function(lambda n: -1, True, 0) sage: g = Stream_neg(f) """ - super().__init__(series, series._is_sparse, series._approximate_order) + super().__init__(series, series._is_sparse) + self._true_order = self._series._true_order + + @lazy_attribute + def _approximate_order(self): + # this is the true order + return self._series._approximate_order def get_coefficient(self, n): """ @@ -2305,7 +2405,7 @@ class Stream_cauchy_invert(Stream_unary): - ``series`` -- a :class:`Stream` - - ``approximate_order`` -- ``None``, or an upper (!) bound on the + - ``approximate_order_upper_bound`` -- ``None``, or an upper bound on the order of ``series`` EXAMPLES:: @@ -2316,7 +2416,7 @@ class Stream_cauchy_invert(Stream_unary): sage: [g[i] for i in range(10)] [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0] """ - def __init__(self, series, approximate_order=None): + def __init__(self, series, approximate_order_upper_bound=None): """ Initialize ``self``. @@ -2326,16 +2426,17 @@ def __init__(self, series, approximate_order=None): sage: f = Stream_exact([1, -1], False) sage: g = Stream_cauchy_invert(f) """ - if series._true_order: - v = -series._approximate_order - self._true_order = True - elif approximate_order is None: - v = -series._approximate_order - else: - v = -approximate_order - super().__init__(series, series._is_sparse, v) + self._approximate_order_upper_bound = approximate_order_upper_bound + super().__init__(series, series._is_sparse) self._zero = ZZ.zero() + @lazy_attribute + def _approximate_order(self): + if self._approximate_order_upper_bound is None: + return -self._series.order() + # this is not the true order + return -self._approximate_order_upper_bound + @lazy_attribute def _ainv(self): r""" @@ -2354,9 +2455,7 @@ def _ainv(self): sage: g._ainv 5 """ - v = -self._series.order() - self._approximate_order = v - self._true_order = True + v = self._series.order() try: return ~self._series[v] except TypeError: @@ -2467,7 +2566,7 @@ class Stream_map_coefficients(Stream_inexact): [0, -1, -1, -1, -1, -1, -1, -1, -1, -1] """ - def __init__(self, series, function): + def __init__(self, series, function, approximate_order=None, true_order=False): """ Initialize ``self``. @@ -2480,7 +2579,14 @@ def __init__(self, series, function): """ self._function = function self._series = series - super().__init__(series._is_sparse, series._approximate_order) + super().__init__(series._is_sparse, true_order) + if approximate_order is not None: + self._approximate_order = approximate_order + + @lazy_attribute + def _approximate_order(self): + # this is not the true order + return self._series._approximate_order def get_coefficient(self, n): """ @@ -2572,7 +2678,12 @@ def __init__(self, series, shift): """ self._series = series self._shift = shift - super().__init__(series._is_sparse, series._approximate_order + shift) + super().__init__(series._is_sparse, series._true_order) + + @lazy_attribute + def _approximate_order(self): + # this is the true order + return self._series._approximate_order + self._shift def __getitem__(self, n): """ @@ -2669,11 +2780,15 @@ def __init__(self, series, shift): """ self._series = series self._shift = shift - if 0 <= series._approximate_order <= shift: - aorder = 0 - else: - aorder = series._approximate_order - shift - super().__init__(series._is_sparse, aorder) + super().__init__(series._is_sparse, False) + + @lazy_attribute + def _approximate_order(self): + # this is not the true order, unless multiplying by an + # integer cannot give 0 + if 0 <= self._series._approximate_order <= self._shift: + return 0 + return self._series._approximate_order - self._shift def __getitem__(self, n): """ diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index c4972aec939..c36d6b4f172 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -694,7 +694,9 @@ def shift(self, n): P = self.parent() # If we shift it too much, then it needs to go into the fraction field # FIXME? This is different than the polynomial rings, which truncates the terms - if coeff_stream._true_order and coeff_stream._approximate_order < P._minimal_valuation: + if (coeff_stream._true_order + and P._minimal_valuation is not None + and coeff_stream._approximate_order < P._minimal_valuation): P = P.fraction_field() return P.element_class(P, coeff_stream) @@ -1144,6 +1146,14 @@ def define(self, s): sage: oeis(f[:30]) # optional, internet 0: A122698: a(1)=a(2)=1 then a(n) = Sum_{d|n, 1 = LazyPowerSeriesRing(QQ) + sage: f = L.undefined() + sage: f.define(1+(t*f).revert()) + sage: f + 1 + t - t^2 + 3*t^3 - 13*t^4 + 69*t^5 - 419*t^6 + O(t^7) + """ if not isinstance(self._coeff_stream, Stream_uninitialized) or self._coeff_stream._target is not None: raise ValueError("series already defined") @@ -2819,8 +2829,11 @@ def __invert__(self): if isinstance(coeff_stream, Stream_cauchy_invert): return P.element_class(P, coeff_stream._series) - return P.element_class(P, Stream_cauchy_invert(coeff_stream, - approximate_order=P._minimal_valuation)) + # if P._minimal_valuation == 0, then this is the true order + # of coeff_stream, otherwise P._minimal_valuation is None + coeff_stream_inverse = Stream_cauchy_invert(coeff_stream, + approximate_order_upper_bound=P._minimal_valuation) + return P.element_class(P, coeff_stream_inverse) def _div_(self, other): r""" @@ -2979,6 +2992,10 @@ def _div_(self, other): degree=v, constant=constant)) + # if P._minimal_valuation == 0, then this is the true order + # of coeff_stream, otherwise P._minimal_valuation is None + # right_inverse = Stream_cauchy_invert(right, + # approximate_order=P._minimal_valuation) right_inverse = Stream_cauchy_invert(right) return P.element_class(P, Stream_cauchy_mul(left, right_inverse)) @@ -3717,9 +3734,9 @@ def revert(self): z = P.gen() g = P.undefined(valuation=1) - # The following is mathematically equivalent to - # z / ((self / z)(g)) - # but more efficient and more lazy. + # the following is mathematically equivalent to + # z / ((self / z)(g)) + # but more efficient and more lazy g.define((~self.shift(-1)(g)).shift(1)) return g @@ -4392,7 +4409,7 @@ def revert(self): - `val(f) = 1`, or - - `f = a + b z` with `a, b \neq 0`, or + - `f = a + b z` with `a, b \neq 0` EXAMPLES:: @@ -4516,16 +4533,17 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! - if not coeff_stream[1]: - raise ValueError("compositional inverse does not exist") - - if coeff_stream[0]: - raise ValueError("cannot determine whether the compositional inverse exists") - +# if not coeff_stream[1]: +# raise ValueError("compositional inverse does not exist") +# +# if coeff_stream[0]: +# raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() g = P.undefined(valuation=1) - # TODO: shift instead of (self / z) should be more efficient - g.define(z / ((self / z)(g))) + # the following is mathematically equivalent to + # z / ((self / z)(g)) + # but more efficient and more lazy + g.define((~self.shift(-1)(g)).shift(1)) return g compositional_inverse = revert @@ -6057,14 +6075,12 @@ def __invert__(self): Trying to invert a non-invertible 'exact' series raises a ``ZeroDivisionError``:: - sage: _ = ~L([0,1], constant=1) + sage: f = ~L([0,1], constant=1) + sage: f[1] Traceback (most recent call last): ... ZeroDivisionError: the Dirichlet inverse only exists if the coefficient with index 1 is non-zero - If the series is not 'exact', we cannot do this without - actually computing a term:: - sage: f = ~L(lambda n: n-1) sage: f[1] Traceback (most recent call last): diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 8ab786a60a3..ed7292bf1e7 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -932,6 +932,8 @@ def _test_revert(self, **options): y = x.revert() vy = y.valuation() m = y[vy] + except NotImplementedError: + pass except (ValueError, TypeError): tester.assertFalse(vx == 1 and x[vx].is_unit(), ("the series %s should be reversible " @@ -2058,10 +2060,6 @@ def __init__(self, basis, sparse=True, category=None): sage: LazySymmetricFunctions.options.halting_precision(6) - sage: s = SymmetricFunctions(ZZ).s() - sage: L = LazySymmetricFunctions(s) - sage: TestSuite(L).run() - sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() @@ -2072,9 +2070,9 @@ def __init__(self, basis, sparse=True, category=None): Reversion will only work when the base ring is a field:: - sage: TestSuite(L).run(skip=['_test_revert']) sage: s = SymmetricFunctions(ZZ).s() sage: L = LazySymmetricFunctions(s) + sage: TestSuite(L).run(skip=['_test_revert']) sage: s = SymmetricFunctions(QQ["q"]).s() sage: L = LazySymmetricFunctions(s) From 3ad48d0f3428b5263bf831e23f6d6fd7ece09204 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 21 Sep 2022 12:51:36 -0700 Subject: [PATCH 136/350] build/pkgs/gsl: Update to 2.7.1 --- build/pkgs/gsl/checksums.ini | 6 +++--- build/pkgs/gsl/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/gsl/checksums.ini b/build/pkgs/gsl/checksums.ini index affe99b550f..8bef7d5f43c 100644 --- a/build/pkgs/gsl/checksums.ini +++ b/build/pkgs/gsl/checksums.ini @@ -1,5 +1,5 @@ tarball=gsl-VERSION.tar.gz -sha1=29179db0d746f422bb0ceca2cbda4de107a2c651 -md5=9e47e81caaebcd92b7aca27a5348df74 -cksum=2494121348 +sha1=549e1105cd1198537be9707257161531e109bd94 +md5=36aee97e67f64dbdab7afae197e3483b +cksum=171022903 upstream_url=https://ftp.gnu.org/gnu/gsl/gsl-VERSION.tar.gz diff --git a/build/pkgs/gsl/package-version.txt b/build/pkgs/gsl/package-version.txt index 1effb003408..860487ca19c 100644 --- a/build/pkgs/gsl/package-version.txt +++ b/build/pkgs/gsl/package-version.txt @@ -1 +1 @@ -2.7 +2.7.1 From 6f10ccb315d36d1828694c248b534d875e7dc0b1 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 21 Sep 2022 22:18:02 +0200 Subject: [PATCH 137/350] add a (currently failing) test for an implicit definition of a symmetric function involving reversion --- src/sage/rings/lazy_series.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index c36d6b4f172..f83fd91141a 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1154,6 +1154,17 @@ def define(self, s): sage: f 1 + t - t^2 + 3*t^3 - 13*t^4 + 69*t^5 - 419*t^6 + O(t^7) + sage: L. = LazyLaurentSeriesRing(QQ) + sage: f = L.undefined(valuation=0) + sage: f.define(1+(t*f).revert()) + sage: f + 1 + t - t^2 + 3*t^3 - 13*t^4 + 69*t^5 - 419*t^6 + O(t^7) + + sage: s = SymmetricFunctions(QQ).s() + sage: L = LazySymmetricFunctions(s) + sage: f = L.undefined() + sage: f.define(1+(s[1]*f).revert()) + """ if not isinstance(self._coeff_stream, Stream_uninitialized) or self._coeff_stream._target is not None: raise ValueError("series already defined") @@ -5364,11 +5375,11 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! - if not coeff_stream[1]: - raise ValueError("compositional inverse does not exist") - - if coeff_stream[0]: - raise ValueError("cannot determine whether the compositional inverse exists") +# if not coeff_stream[1]: +# raise ValueError("compositional inverse does not exist") +# +# if coeff_stream[0]: +# raise ValueError("cannot determine whether the compositional inverse exists") X = R(Partition([1])) b = coeff_stream[1][Partition([1])] From 7f0728b0bc59c9b90556c626c7d8e77756eb1b87 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 21 Sep 2022 22:21:46 +0200 Subject: [PATCH 138/350] remove useless line - _approximate_order is called by __getitem__. --- src/sage/data_structures/stream.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index adb58515cb6..a80f606961d 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1842,7 +1842,6 @@ def get_coefficient(self, n): """ fv = self._left._approximate_order gv = self._right._approximate_order - _ = self._approximate_order # this is only to trigger the initialization if n < 0: return sum(self._left[i] * self._neg_powers[-i][n] for i in range(fv, n // gv + 1)) From 1e24d43c0371b3285ad508cd95f2f3e31e66dd58 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 21 Sep 2022 17:48:25 -0700 Subject: [PATCH 139/350] build/pkgs/gsl/patches: Import https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-big_sur.diff --- .../pkgs/gsl/patches/configure-big_sur.patch | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 build/pkgs/gsl/patches/configure-big_sur.patch diff --git a/build/pkgs/gsl/patches/configure-big_sur.patch b/build/pkgs/gsl/patches/configure-big_sur.patch new file mode 100644 index 00000000000..aba05df4d8a --- /dev/null +++ b/build/pkgs/gsl/patches/configure-big_sur.patch @@ -0,0 +1,23 @@ +--- a/configure.orig 2021-10-01 08:15:08.000000000 -0700 ++++ b/configure 2021-10-20 12:44:47.000000000 -0700 +@@ -8733,16 +8733,11 @@ + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; +- darwin*) # darwin 5.x on +- # if running on 10.5 or later, the deployment target defaults +- # to the OS version, if on x86, and 10.4, the deployment +- # target defaults to 10.4. Don't you love it? +- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in +- 10.0,*86*-darwin8*|10.0,*-darwin[91]*) +- _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; +- 10.[012][,.]*) ++ darwin*) ++ case ${MACOSX_DEPLOYMENT_TARGET},$host in ++ 10.[012],*|,*powerpc*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; +- 10.*) ++ *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; From 07d2dcbc22cb66741c8fcb69a1104c93b28e08d8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 21 Sep 2022 18:09:05 -0700 Subject: [PATCH 140/350] .github/workflows/docker.yml: Use ubuntu-bionic-i386 with gcc_8, remove manylinux-2_24-i686 (based on dropped debian-stretch) --- .github/workflows/docker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8eff13405f8..5d0ec8129ca 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -51,8 +51,7 @@ on: "opensuse-15.4-gcc_11", "opensuse-tumbleweed", "conda-forge", - "ubuntu-bionic-i386", - "manylinux-2_24-i686", + "ubuntu-bionic-gcc_8-i386", "debian-buster-i386", ] tox_packages_factors: From 560cbc786fe3f0638836a4e52d8762b2ca568147 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 10 Aug 2022 22:48:43 +0800 Subject: [PATCH 141/350] 34212: clean version --- src/sage/rings/number_field/number_field.py | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 58463d570d4..3b1bb23205b 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -153,6 +153,10 @@ from collections import Counter from builtins import zip +from sage.categories.homset import Hom +from sage.categories.sets_cat import Sets +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector _NumberFields = NumberFields() @@ -9297,6 +9301,69 @@ def minkowski_embedding(self, B=None, prec=None): return sage.matrix.all.matrix(d) + def logarithmic_embedding(self, prec=53): + """ + Return the morphism of ``self`` under the logarithmic embedding + in the category Set. + + The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`. + + It is defined under Definition 4.9.6 in [Cohen1993]_. + + INPUT: + + - ``prec`` -- desired floating point precision. + + OUTPUT: + + - a tuple of real numbers. + + EXAMPLES:: + + sage: CF. = CyclotomicField(97) + sage: f = CF.logarithmic_embedding() + sage: f(0) + (-1) + sage: f(7) + (1.94591014905531) + + :: + + sage: K. = NumberField(x^3 + 5) + sage: f = K.logarithmic_embedding() + sage: f(0) + (-1) + sage: f(7) + (1.94591014905531) + """ + def closure_map(x, prec=53): + """ + The function closure of the logarithmic embedding. + """ + K = self.base_ring() + K_embeddings = K.places(prec) + r1, r2 = K.signature() + r = r1 + r2 - 1 + + from sage.rings.all import RealField + Reals = RealField(prec) + + if x == 0: + return vector([-1 for _ in range(r + 1)]) + + x_logs = [] + for i in range(r1): + sigma = K_embeddings[i] + x_logs.append(Reals(abs(sigma(x))).log()) + for i in range(r1, r + 1): + tau = K_embeddings[i] + x_logs.append(2 * Reals(abs(tau(x))).log()) + + return vector(x_logs) + + log_map = closure_map(self(0), prec) + return Hom(self, VectorSpace(QQ, len(log_map)), Sets()) + def places(self, all_complex=False, prec=None): r""" Return the collection of all infinite places of self. From 2ad46295eef275961547bc0e68a8cae5abb25df5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 11 Aug 2022 14:00:41 +0800 Subject: [PATCH 142/350] 34212: fix doc --- src/sage/rings/number_field/number_field.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 3b1bb23205b..c5a591de1ff 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -157,6 +157,7 @@ from sage.categories.sets_cat import Sets from sage.modules.free_module import VectorSpace from sage.modules.free_module_element import vector +from sage.rings.real_mpfr import RR _NumberFields = NumberFields() @@ -9302,7 +9303,7 @@ def minkowski_embedding(self, B=None, prec=None): return sage.matrix.all.matrix(d) def logarithmic_embedding(self, prec=53): - """ + r""" Return the morphism of ``self`` under the logarithmic embedding in the category Set. @@ -9362,7 +9363,8 @@ def closure_map(x, prec=53): return vector(x_logs) log_map = closure_map(self(0), prec) - return Hom(self, VectorSpace(QQ, len(log_map)), Sets()) + hom = Hom(self, VectorSpace(RR, len(log_map)), Sets()) + return hom(log_map) def places(self, all_complex=False, prec=None): r""" From 6bff6a6e28b8ee186fc6bc800acb692a6c7eb967 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 11 Aug 2022 16:43:53 +0800 Subject: [PATCH 143/350] 34212: fix doc and code --- src/sage/rings/number_field/number_field.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index c5a591de1ff..0d2f56a1dc7 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9317,31 +9317,31 @@ def logarithmic_embedding(self, prec=53): OUTPUT: - - a tuple of real numbers. + - the morphism of ``self`` under the logarithmic embedding in the category Set. EXAMPLES:: - sage: CF. = CyclotomicField(97) + sage: CF. = CyclotomicField(5) sage: f = CF.logarithmic_embedding() sage: f(0) - (-1) + (-1, -1) sage: f(7) - (1.94591014905531) + (3.89182029811063, 3.89182029811063) :: sage: K. = NumberField(x^3 + 5) sage: f = K.logarithmic_embedding() sage: f(0) - (-1) + (-1, -1) sage: f(7) - (1.94591014905531) + (1.94591014905531, 3.89182029811063) """ def closure_map(x, prec=53): """ The function closure of the logarithmic embedding. """ - K = self.base_ring() + K = self K_embeddings = K.places(prec) r1, r2 = K.signature() r = r1 + r2 - 1 @@ -9362,9 +9362,8 @@ def closure_map(x, prec=53): return vector(x_logs) - log_map = closure_map(self(0), prec) - hom = Hom(self, VectorSpace(RR, len(log_map)), Sets()) - return hom(log_map) + hom = Hom(self, VectorSpace(RR, len(closure_map(self(0), prec))), Sets()) + return hom(closure_map) def places(self, all_complex=False, prec=None): r""" From 15cb0846b3348e3fc7baf3175deea6fc9e625691 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:35:39 +0800 Subject: [PATCH 144/350] 34212: Correct doc and add an example --- src/sage/rings/number_field/number_field.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 0d2f56a1dc7..edfa01cd232 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9309,7 +9309,7 @@ def logarithmic_embedding(self, prec=53): The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`. - It is defined under Definition 4.9.6 in [Cohen1993]_. + It is defined under Definition 4.9.6 in [Coh1993]_. INPUT: @@ -9336,6 +9336,15 @@ def logarithmic_embedding(self, prec=53): (-1, -1) sage: f(7) (1.94591014905531, 3.89182029811063) + + :: + + sage: K. = NumberField(x^4 - 8*x^2 + 3) + sage: f = logarithmic_embedding(K) + sage: f(0) + (-1, -1, -1, -1) + sage: f(7) + (3.89182029811063, 3.89182029811063, 3.89182029811063, 3.89182029811063) """ def closure_map(x, prec=53): """ From 89d2c29e89e8cacd90d85bab0b7cbe9556e8614d Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:42:27 +0800 Subject: [PATCH 145/350] 34212: log embedding for relative number field --- .../rings/number_field/number_field_rel.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index d33980c4b10..499a89161a6 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -2062,6 +2062,75 @@ def automorphisms(self): check=False, universe=self.Hom(self)) return self.__automorphisms + def logarithmic_embedding(self, prec=53): + r""" + Return the morphism of ``self`` under the logarithmic embedding + in the category Set. + + The logarithmic embedding is defined as a map from the relative number field ``self`` to `\RR^n`. + + It is defined under Definition 4.9.6 in [Coh1993]_. + + INPUT: + + - ``prec`` -- desired floating point precision. + + OUTPUT: + + - the morphism of ``self`` under the logarithmic embedding in the category Set. + + EXAMPLES:: + + sage: K. = CyclotomicField(3) + sage: R. = K[] + sage: L. = K.extension(x^5 + 5) + sage: f = logarithmic_embedding(L) + sage: f(0) + (-1, -1, -1, -1, -1) + sage: f(5) + (3.21887582486820, 3.21887582486820, 3.21887582486820, + 3.21887582486820, 3.21887582486820) + + :: + + sage: K. = NumberField(x^2 + 1) + sage: t = K['t'].gen() + sage: L. = K.extension(t^4 - i) + sage: f = logarithmic_embedding(L) + sage: f(0) + (-1, -1, -1, -1, -1, -1, -1, -1) + sage: f(3) + (2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622, + 2.19722457733622, 2.19722457733622, 2.19722457733622, 2.19722457733622) + """ + def closure_map(x, prec=53): + """ + The function closure of the logarithmic embedding. + """ + K = self + K_embeddings = K.places(prec) + r1, r2 = K.signature() + r = r1 + r2 - 1 + + from sage.rings.all import RealField + Reals = RealField(prec) + + if x == 0: + return vector([-1 for _ in range(r + 1)]) + + x_logs = [] + for i in range(r1): + sigma = K_embeddings[i] + x_logs.append(Reals(abs(sigma(x))).log()) + for i in range(r1, r + 1): + tau = K_embeddings[i] + x_logs.append(2 * Reals(abs(tau(x))).log()) + + return vector(x_logs) + + hom = Hom(self, VectorSpace(RR, len(closure_map(self(0), prec))), Sets()) + return hom(closure_map) + def places(self, all_complex=False, prec=None): """ Return the collection of all infinite places of self. From 2fd483097aaa8d2a849bcb6785fc7f967ef73909 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 14:51:33 +0800 Subject: [PATCH 146/350] 34212: correct examples --- src/sage/rings/number_field/number_field.py | 6 +++--- src/sage/rings/number_field/number_field_rel.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index edfa01cd232..118386623c3 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -9339,12 +9339,12 @@ def logarithmic_embedding(self, prec=53): :: - sage: K. = NumberField(x^4 - 8*x^2 + 3) - sage: f = logarithmic_embedding(K) + sage: F. = NumberField(x^4 - 8*x^2 + 3) + sage: f = F.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1) sage: f(7) - (3.89182029811063, 3.89182029811063, 3.89182029811063, 3.89182029811063) + (1.94591014905531, 1.94591014905531, 1.94591014905531, 1.94591014905531) """ def closure_map(x, prec=53): """ diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 499a89161a6..9e80ef1e3c1 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -99,8 +99,12 @@ from sage.rings.number_field.morphism import RelativeNumberFieldHomomorphism_from_abs from sage.libs.pari.all import pari_gen -from sage.rings.rational_field import QQ -from sage.rings.integer_ring import ZZ +from sage.categories.homset import Hom +from sage.categories.sets_cat import Sets +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector + +from sage.rings.all import RR, QQ, ZZ def is_RelativeNumberField(x): @@ -2084,7 +2088,7 @@ def logarithmic_embedding(self, prec=53): sage: K. = CyclotomicField(3) sage: R. = K[] sage: L. = K.extension(x^5 + 5) - sage: f = logarithmic_embedding(L) + sage: f = L.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1, -1) sage: f(5) @@ -2096,7 +2100,7 @@ def logarithmic_embedding(self, prec=53): sage: K. = NumberField(x^2 + 1) sage: t = K['t'].gen() sage: L. = K.extension(t^4 - i) - sage: f = logarithmic_embedding(L) + sage: f = L.logarithmic_embedding() sage: f(0) (-1, -1, -1, -1, -1, -1, -1, -1) sage: f(3) From 7a12ff3327a209bc6065fb0d8ea9b939f1d91c5f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 13:28:09 +0800 Subject: [PATCH 147/350] points --- src/doc/en/reference/references/index.rst | 4 + .../schemes/projective/proj_bdd_height.py | 189 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/sage/schemes/projective/proj_bdd_height.py diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 1dbd6f036e7..010654f683a 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -3668,6 +3668,10 @@ REFERENCES: and its use for certified homotopy continuation of systems of plane algebraic curves, :arxiv:`1505.03432` +.. [Krumm2016] Daid Krumm, *Computing Points of Bounded Height in Projective Space over a Number Field*, + MATHEMATICS OF COMPUTATION, Volume 85, Number 297, January 2016, Pages 423–447. + http://dx.doi.org/10.1090/mcom/2984 + .. [KR2001] \J. Kahane and A. Ryba. *The hexad game*, Electronic Journal of Combinatorics, **8** (2001). http://www.combinatorics.org/Volume_8/Abstracts/v8i2r11.html diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py new file mode 100644 index 00000000000..8da3d90297f --- /dev/null +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -0,0 +1,189 @@ +r""" +Points of bounded height in projective spaces + +This module defines sunctions to compute points of bounded height of a given +number field with height less than a specified bound in projective spaces. + +Sage functions to list all elements of a given number field with height less +than a specified bound. + +AUTHORS: + +- Jing Guo (2022): initial version based on David Krumm's code + +REFERENCES: + +- [Krumm2016] + +""" + +import itertools + +def QQ_points_of_bounded_height(dim, bound): + r""" + ... + """ + if bound < 1: + return + PN = ProjectiveSpace(QQ, dim) + unit_tuples = list(itertools.product([-1, 1], repeat=dim)) + increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) + for t in increasing_tuples: + if gcd(t) == 1: + for p in itertools.permutations(t): + for u in unit_tuples: + new_point = [a*b for a, b in zip(u, p)] + [p[dim]] + yield PN(new_point) + +def points_of_bounded_height(K, dim, bound, prec=53): + r""" + ... + """ + if bound < 1: + return + + r1, r2 = K.signature() + r = r1 + r2 - 1 + K_degree = K.degree() + K_embeddings = K.places(prec=prec) + roots_of_unity = K.roots_of_unity() + unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) + + PN = ProjectiveSpace(K, dim) + + Reals = RealField(prec) + logB = Reals(bound).log() + + class_group_ideals = [c.ideal() for c in K.class_group()] + class_number = len(class_group_ideals) + class_group_ideal_norms = [a.norm() for a in class_group_ideals] + norm_bound = bound*max(class_group_ideal_norms) + fundamental_units = UnitGroup(K).fundamental_units() + fund_unit_logs = map(log_map, fundamental_units) # TODO log map + + test_matrix = column_matrix(fund_unit_logs) + try: + test_matrix.change_ring(QQ) + except ValueError: + raise ValueError('prec too low.') + + cut_fund_unit_logs = column_matrix(fund_unit_logs).delete_rows([r]) + lll_fund_units = [] + for c in pari(cut_fund_unit_logs).qflll().python().columns(): + new_unit = 1 + for i in range(r): + new_unit *= fundamental_units[i]**c[i] + lll_fund_units.append(new_unit) + fundamental_units = lll_fund_units + fund_unit_logs = map(log_map, fundamental_units) + + possible_norm_set = set([]) + for i in range(class_number): + for k in range(1, bound + 1): + possible_norm_set.add(k*class_group_ideal_norms[i]) + + principal_ideal_gens = dict() + negative_norm_units = K.elements_of_norm(-1) + if len(negative_norm_units) == 0: + for m in possible_norm_set: + principal_ideal_gens[m] = K.elements_of_norm(m) + K.elements_of_norm(-m) + else: + for m in possible_norm_set: + principal_ideal_gens[m] = K.elements_of_norm(m) + + pr_ideal_gen_logs = dict() + for key in principal_ideal_gens: + for y in principal_ideal_gens[key]: + pr_ideal_gen_logs[y] = log_map(y) + + fund_parallelotope_vertices = [] + for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): + vertex = sum([coefficient_tuple[i]*fund_unit_logs[i] for i in range(r)]) + fund_parallelotope_vertices.append(vertex) + + D_numbers = [] + for v in range(r + 1): + D_numbers.append(max([vertex[v] for vertex in fund_parallelotope_vertices])) + + A_numbers = [] + for v in range(r + 1): + A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) + + aux_constant = (1/K_degree)*Reals(norm_bound).log() + + L_numbers = [] + for v in range(r1): + L_numbers.append(aux_constant + D_numbers[v] - A_numbers[v]) + for v in range(r1, r + 1): + L_numbers.append(2*aux_constant + D_numbers[v] - A_numbers[v]) + L_numbers = vector(L_numbers).change_ring(QQ) + + T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) + + M = ((-1)*matrix.identity(r)).insert_row(r, [1 for i in range(r)]) + M = M.transpose().insert_row(0, [0 for i in range(r + 1)]).transpose() + M = M.change_ring(QQ) + M.set_column(0, L_numbers) + vertices = map(vector, Polyhedron(ieqs=list(M)).vertices()) + + T_it = T.inverse().transpose() + unit_polytope = Polyhedron([v*T_it for v in vertices]) + + coordinate_space = dict() + coordinate_space[0] = [[K(0), log_map(0)]] + int_points = unit_polytope.integral_points() + + units_with_logs = dict() + for n in int_points: + new_unit = 1 + for j in range(r): + new_unit *= fundamental_units[j]**n[j] + new_unit_log = sum([n[j]*fund_unit_logs[j] for j in range(r)]) + units_with_logs[n] = [new_unit, new_unit_log] + + for norm in principal_ideal_gens: + coordinate_list = [] + for y in principal_ideal_gens[norm]: + for n in int_points: + unit, unit_log = units_with_logs[n] + y_log = pr_ideal_gen_logs[y] + g_log = unit_log + y_log + bool1 = all(g_log[i] <= aux_constant + D_numbers[i] for i in range(r1)) + bool2 = all(g_log[j] <= 2*aux_constant + D_numbers[j] for j in range(r1, r + 1)) + if bool1 and bool2: + g = unit*y + coordinate_list.append([g, g_log]) + if len(coordinate_list) > 0: + coordinate_space[norm] = coordinate_list + + for m in range(class_number): + a = class_group_ideals[m] + a_norm = class_group_ideal_norms[m] + log_a_norm = Reals(a_norm).log() + a_const = (logB + log_a_norm)/K_degree + a_coordinates = [] + + for k in range(bound + 1): + norm = k*a_norm + if coordinate_space.has_key(norm): + for pair in coordinate_space[norm]: + g, g_log = pair + if g in a: + bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) + bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) + if bool1 and bool2: + a_coordinates.append(pair) + + t = len(a_coordinates) - 1 + points_in_class_a = set([]) + increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) + log_arch_height_bound = logB + log_a_norm + for index_tuple in increasing_tuples: + point_coordinates = [a_coordinates[i][0] for i in index_tuple] + point_coordinate_logs = [a_coordinates[i][1] for i in index_tuple] + log_arch_height = sum([max([x[i] for x in point_coordinate_logs]) for i in range(r + 1)]) + if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): + for p in itertools.permutations(point_coordinates): + for u in unit_tuples: + new_point = [i*j for i, j in zip(u, p)] + [p[dim]] + yield PN(new_point) From 2ed790e656bfe439dd7cdfe49c4c5ad45488b5f5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 15:50:20 +0800 Subject: [PATCH 148/350] clean --- .../schemes/projective/projective_space.py | 74 ++++++------------- 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index ed44ebcd6aa..55a2f7e6a5b 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1852,18 +1852,12 @@ def _morphism(self, *args, **kwds): def points_of_bounded_height(self, **kwds): r""" - Returns an iterator of the points in self of absolute height of at most the given bound. + Return an iterator of the points in ``self`` of absolute height of + at most the given bound. - Bound check is strict for the rational field. Requires self to be projective space - over a number field. Uses the - Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for - computing algebraic numbers up to a given height [DK2013]_. + ALGORITHM: - The algorithm requires floating point arithmetic, so the user is - allowed to specify the precision for such calculations. - Additionally, due to floating point issues, points - slightly larger than the bound may be returned. This can be controlled - by lowering the tolerance. + This is an implementation of Algorithm 6 in [Krumm2016]_. INPUT: @@ -1871,13 +1865,11 @@ def points_of_bounded_height(self, **kwds): - ``bound`` - a real number - - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4 - - - ``precision`` - the precision to use for computing the elements of bounded height of number fields. + - ``precision`` - (default: 53) a positive integer OUTPUT: - - an iterator of points in this space + - an iterator of points of bounded height EXAMPLES:: @@ -1897,48 +1889,30 @@ def points_of_bounded_height(self, **kwds): sage: len(list(P.points_of_bounded_height(bound=1.5, tolerance=0.1))) 57 """ - if is_RationalField(self.base_ring()): - ftype = False # stores whether the field is a number field or the rational field - elif self.base_ring() in NumberFields(): # true for rational field as well, so check is_RationalField first - ftype = True + from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height + + R = self.base_ring() + + # whether the field is a number field or the rational field + if is_RationalField(R): + field_type = False + elif R in NumberFields(): + # true for rational field as well, so check is_RationalField first + field_type = True else: raise NotImplementedError("self must be projective space over a number field") bound = kwds.pop('bound') B = bound**(self.base_ring().absolute_degree()) # convert to relative height - n = self.dimension_relative() - R = self.base_ring() - if ftype: - zero = R.zero() - i = n - while not i < 0: - P = [zero for _ in range(i)] + [R.one()] - P += [zero for _ in range(n - i)] - yield self(P) - tol = kwds.pop('tolerance', 1e-2) - prec = kwds.pop('precision', 53) - iters = [R.elements_of_bounded_height(bound=B, tolerance=tol, precision=prec) for _ in range(i)] - for x in iters: - next(x) # put at zero - j = 0 - while j < i: - try: - P[j] = next(iters[j]) - yield self(P) - j = 0 - except StopIteration: - iters[j] = R.elements_of_bounded_height(bound=B, tolerance=tol, precision=prec) # reset - next(iters[j]) # put at zero - P[j] = zero - j += 1 - i -= 1 - else: # base ring QQ - zero = (0,) * (n + 1) - for c in cartesian_product_iterator([srange(-B, B + 1) - for _ in range(n + 1)]): - if gcd(c) == 1 and c > zero: - yield self.point(c, check=False) + prec = kwds.pop('precision', 53) + + dim = self.dimension_relative() + + if field_type: + return points_of_bounded_height(dim, B) + else: + return QQ_points_of_bounded_height(R, dim, B, prec) def subscheme_from_Chow_form(self, Ch, dim): r""" From b1b8a28be151beff6455102b2fb0e0f4b564bde8 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 16:10:09 +0800 Subject: [PATCH 149/350] clean --- .../schemes/projective/proj_bdd_height.py | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8da3d90297f..866453ba2a7 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -18,10 +18,23 @@ """ import itertools +from sage.schemes.projective.projective_space import ProjectiveSpace + def QQ_points_of_bounded_height(dim, bound): r""" - ... + Return an iterator of the points in ``self`` of absolute height of + at most the given bound in the rational field. + + INPUT: + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + OUTPUT: + + - an iterator of points of bounded height """ if bound < 1: return @@ -37,7 +50,26 @@ def QQ_points_of_bounded_height(dim, bound): def points_of_bounded_height(K, dim, bound, prec=53): r""" - ... + Return an iterator of the points in ``self`` of absolute height of + at most the given bound. + + ALGORITHM: + + This is an implementation of Algorithm 6 in [Krumm2016]_. + + INPUT: + + - ``K`` -- a number field + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + - ``prec`` -- (default: 53) a positive integer + + OUTPUT: + + - an iterator of points of bounded height """ if bound < 1: return From 76dab1c5ae1a007e5fd4e02301269ea6c46d237a Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 17:25:07 +0800 Subject: [PATCH 150/350] rational --- .../schemes/projective/proj_bdd_height.py | 27 +++++++++++++++---- .../schemes/projective/projective_space.py | 23 +++++----------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 866453ba2a7..1b37bb9724b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -19,34 +19,51 @@ import itertools from sage.schemes.projective.projective_space import ProjectiveSpace - +from sage.rings.rational_field import QQ +from sage.arith.all import gcd def QQ_points_of_bounded_height(dim, bound): r""" Return an iterator of the points in ``self`` of absolute height of - at most the given bound in the rational field. + at most ``bound`` in the rational field. INPUT: - - ``dim`` -- a positive interger + - ``dim`` -- a positive integer - ``bound`` -- a real number OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height + sage: list(QQ_points_of_bounded_height(1, 1)) + [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] + sage: len(list(QQ_points_of_bounded_height(1, 5))) + 40 + + There are no points of negative height:: + + sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height + sage: list(QQ_points_of_bounded_height(1, -3)) + [] """ if bound < 1: - return + return iter(set([])) PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) + points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) for t in increasing_tuples: if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: new_point = [a*b for a, b in zip(u, p)] + [p[dim]] - yield PN(new_point) + points_of_bounded_height.add(PN(new_point)) + return iter(points_of_bounded_height) def points_of_bounded_height(K, dim, bound, prec=53): r""" diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 55a2f7e6a5b..93b8d8c7b8a 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1874,20 +1874,11 @@ def points_of_bounded_height(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: sorted(list(P.points_of_bounded_height(bound=5))) - [(0 : 1), (1 : -5), (1 : -4), (1 : -3), (1 : -2), (1 : -1), (1 : 0), - (1 : 1), (1 : 2), (1 : 3), (1 : 4), (1 : 5), (2 : -5), (2 : -3), - (2 : -1), (2 : 1), (2 : 3), (2 : 5), (3 : -5), (3 : -4), (3 : -2), - (3 : -1), (3 : 1), (3 : 2), (3 : 4), (3 : 5), (4 : -5), (4 : -3), - (4 : -1), (4 : 1), (4 : 3), (4 : 5), (5 : -4), (5 : -3), (5 : -2), - (5 : -1), (5 : 1), (5 : 2), (5 : 3), (5 : 4)] - - :: - - sage: u = QQ['u'].0 - sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) - sage: len(list(P.points_of_bounded_height(bound=1.5, tolerance=0.1))) - 57 + sage: sorted(list(P.points_of_bounded_height(bound=3))) + [(-3 : 1), (-2 : 1), (-3/2 : 1), (-1 : 1), + (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), + (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), + (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height @@ -1910,9 +1901,9 @@ def points_of_bounded_height(self, **kwds): dim = self.dimension_relative() if field_type: - return points_of_bounded_height(dim, B) + return points_of_bounded_height(R, dim, B, prec) else: - return QQ_points_of_bounded_height(R, dim, B, prec) + return QQ_points_of_bounded_height(dim, B) def subscheme_from_Chow_form(self, Ch, dim): r""" From 706e514ae198f296bf29808785cbc2add3b89c5b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 17:43:39 +0800 Subject: [PATCH 151/350] import --- src/sage/schemes/projective/proj_bdd_height.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 1b37bb9724b..5f637d98f9b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -20,6 +20,8 @@ import itertools from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ +from sage.rings.all import RealField +from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd def QQ_points_of_bounded_height(dim, bound): From 3e5f25f3015a452b6da3669753b5336457e4b8b7 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 18:05:42 +0800 Subject: [PATCH 152/350] number fields --- src/sage/schemes/projective/proj_bdd_height.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 5f637d98f9b..07ce8d5f959 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,6 +23,7 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd +from sage.rings.number_field.number_field import logarithmic_embedding def QQ_points_of_bounded_height(dim, bound): r""" @@ -110,7 +111,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(log_map, fundamental_units) # TODO log map + fund_unit_logs = map(logarithmic_embedding, fundamental_units) test_matrix = column_matrix(fund_unit_logs) try: @@ -126,7 +127,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(log_map, fundamental_units) + fund_unit_logs = map(logarithmic_embedding, fundamental_units) possible_norm_set = set([]) for i in range(class_number): @@ -145,7 +146,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): pr_ideal_gen_logs = dict() for key in principal_ideal_gens: for y in principal_ideal_gens[key]: - pr_ideal_gen_logs[y] = log_map(y) + pr_ideal_gen_logs[y] = logarithmic_embedding(y) fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): @@ -181,7 +182,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_polytope = Polyhedron([v*T_it for v in vertices]) coordinate_space = dict() - coordinate_space[0] = [[K(0), log_map(0)]] + coordinate_space[0] = [[K(0), logarithmic_embedding(0)]] int_points = unit_polytope.integral_points() units_with_logs = dict() From 4d10b14e3ddbdaef3d1e2306b4e34a4255242f81 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 28 Aug 2022 19:28:41 +0800 Subject: [PATCH 153/350] log embed --- src/sage/schemes/projective/proj_bdd_height.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 07ce8d5f959..8b2713e19da 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,7 +23,7 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd -from sage.rings.number_field.number_field import logarithmic_embedding +from sage.matrix.constructor import column_matrix def QQ_points_of_bounded_height(dim, bound): r""" @@ -102,6 +102,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) PN = ProjectiveSpace(K, dim) + #R = K.base_ring() + log_embed = K.logarithmic_embedding() Reals = RealField(prec) logB = Reals(bound).log() @@ -111,7 +113,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(logarithmic_embedding, fundamental_units) + fund_unit_logs = map(log_embed, fundamental_units) test_matrix = column_matrix(fund_unit_logs) try: @@ -127,7 +129,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(logarithmic_embedding, fundamental_units) + fund_unit_logs = map(log_embed, fundamental_units) possible_norm_set = set([]) for i in range(class_number): @@ -146,7 +148,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): pr_ideal_gen_logs = dict() for key in principal_ideal_gens: for y in principal_ideal_gens[key]: - pr_ideal_gen_logs[y] = logarithmic_embedding(y) + pr_ideal_gen_logs[y] = log_embed(y) fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): @@ -182,7 +184,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_polytope = Polyhedron([v*T_it for v in vertices]) coordinate_space = dict() - coordinate_space[0] = [[K(0), logarithmic_embedding(0)]] + coordinate_space[0] = [[K(0), log_embed(0)]] int_points = unit_polytope.integral_points() units_with_logs = dict() From 21c8ec68f09eb6e375c1a16a6bdbcc0507dd6fda Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 11:25:55 +0800 Subject: [PATCH 154/350] doc --- src/sage/schemes/projective/proj_bdd_height.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8b2713e19da..602dd056bf1 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -70,8 +70,8 @@ def QQ_points_of_bounded_height(dim, bound): def points_of_bounded_height(K, dim, bound, prec=53): r""" - Return an iterator of the points in ``self`` of absolute height of - at most the given bound. + Return an iterator of the points in ``K`` with dimension ``dim`` of + absolute height of at most ``bound``. ALGORITHM: @@ -102,7 +102,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) PN = ProjectiveSpace(K, dim) - #R = K.base_ring() log_embed = K.logarithmic_embedding() Reals = RealField(prec) From 2711a1d38a637cf42e1cf0a12f09a2f4f42f4a9e Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 12:10:32 +0800 Subject: [PATCH 155/350] indent --- .../schemes/projective/proj_bdd_height.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 602dd056bf1..8ad4fb6f101 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -92,11 +92,11 @@ def points_of_bounded_height(K, dim, bound, prec=53): - an iterator of points of bounded height """ if bound < 1: - return + return [] r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -134,7 +134,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for i in range(class_number): for k in range(1, bound + 1): possible_norm_set.add(k*class_group_ideal_norms[i]) - + principal_ideal_gens = dict() negative_norm_units = K.elements_of_norm(-1) if len(negative_norm_units) == 0: @@ -148,22 +148,22 @@ def points_of_bounded_height(K, dim, bound, prec=53): for key in principal_ideal_gens: for y in principal_ideal_gens[key]: pr_ideal_gen_logs[y] = log_embed(y) - + fund_parallelotope_vertices = [] for coefficient_tuple in itertools.product([-1/2, 1/2], repeat=r): vertex = sum([coefficient_tuple[i]*fund_unit_logs[i] for i in range(r)]) fund_parallelotope_vertices.append(vertex) - + D_numbers = [] for v in range(r + 1): D_numbers.append(max([vertex[v] for vertex in fund_parallelotope_vertices])) - + A_numbers = [] for v in range(r + 1): A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) - + aux_constant = (1/K_degree)*Reals(norm_bound).log() - + L_numbers = [] for v in range(r1): L_numbers.append(aux_constant + D_numbers[v] - A_numbers[v]) @@ -225,7 +225,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: - a_coordinates.append(pair) + a_coordinates.append(pair) t = len(a_coordinates) - 1 points_in_class_a = set([]) @@ -239,4 +239,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): for p in itertools.permutations(point_coordinates): for u in unit_tuples: new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - yield PN(new_point) + points_in_class_a.add(PN(new_point)) + points_of_bdd_height += list(points_in_class_a) + return points_of_bdd_height From 394bf27029bee8d0326999795c8cc06dc860e5bd Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Mon, 29 Aug 2022 13:33:38 +0800 Subject: [PATCH 156/350] python 2 to python 3 --- .../schemes/projective/proj_bdd_height.py | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8ad4fb6f101..d814371de08 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -23,7 +23,12 @@ from sage.rings.all import RealField from sage.rings.number_field.unit_group import UnitGroup from sage.arith.all import gcd -from sage.matrix.constructor import column_matrix +from sage.matrix.constructor import matrix, column_matrix +from sage.libs.pari.all import pari +from sage.modules.free_module_element import vector +from sage.rings.integer import Integer +from sage.geometry.polyhedron.constructor import Polyhedron + def QQ_points_of_bounded_height(dim, bound): r""" @@ -107,28 +112,33 @@ def points_of_bounded_height(K, dim, bound, prec=53): Reals = RealField(prec) logB = Reals(bound).log() + points_of_bdd_height = [] + class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) class_group_ideal_norms = [a.norm() for a in class_group_ideals] norm_bound = bound*max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() - fund_unit_logs = map(log_embed, fundamental_units) + fund_unit_logs = list(map(log_embed, fundamental_units)) test_matrix = column_matrix(fund_unit_logs) - try: - test_matrix.change_ring(QQ) - except ValueError: - raise ValueError('prec too low.') + #try: + # test_matrix.change_ring(QQ) + #except ValueError: + # raise ValueError('prec too low.') - cut_fund_unit_logs = column_matrix(fund_unit_logs).delete_rows([r]) + cut_fund_unit_logs = test_matrix.delete_rows([r]) lll_fund_units = [] - for c in pari(cut_fund_unit_logs).qflll().python().columns(): + for c in cut_fund_unit_logs.columns(): + #for c in pari(cut_fund_unit_logs).qflll().python().columns(): new_unit = 1 for i in range(r): + print(fundamental_units[i]) + print(c[i]) new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units - fund_unit_logs = map(log_embed, fundamental_units) + fund_unit_logs = list(map(log_embed, fundamental_units)) possible_norm_set = set([]) for i in range(class_number): @@ -173,8 +183,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) - M = ((-1)*matrix.identity(r)).insert_row(r, [1 for i in range(r)]) - M = M.transpose().insert_row(0, [0 for i in range(r + 1)]).transpose() + M = ((-1)*matrix.identity(r)).insert_row(r, [Integer(1) for i in range(r)]) + M = M.transpose().insert_row(0, [Integer(0) for i in range(r + 1)]).transpose() M = M.change_ring(QQ) M.set_column(0, L_numbers) vertices = map(vector, Polyhedron(ieqs=list(M)).vertices()) @@ -218,7 +228,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for k in range(bound + 1): norm = k*a_norm - if coordinate_space.has_key(norm): + if norm in coordinate_space: for pair in coordinate_space[norm]: g, g_log = pair if g in a: From 2e9df04ae57717bc61f2aff97f1d83490833886f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 30 Aug 2022 20:30:33 +0800 Subject: [PATCH 157/350] some small changes --- .../schemes/projective/proj_bdd_height.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index d814371de08..e20bf297962 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -116,21 +116,22 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [a.norm() for a in class_group_ideals] - norm_bound = bound*max(class_group_ideal_norms) + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) + mat = column_matrix(fund_unit_logs) - test_matrix = column_matrix(fund_unit_logs) - #try: - # test_matrix.change_ring(QQ) - #except ValueError: - # raise ValueError('prec too low.') + test_matrix = mat + try: + test_matrix.change_ring(QQ) + except ValueError: + raise ValueError('prec too low.') - cut_fund_unit_logs = test_matrix.delete_rows([r]) + cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = [] - for c in cut_fund_unit_logs.columns(): #for c in pari(cut_fund_unit_logs).qflll().python().columns(): + for c in cut_fund_unit_logs.columns(): new_unit = 1 for i in range(r): print(fundamental_units[i]) @@ -172,7 +173,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): for v in range(r + 1): A_numbers.append(min([pr_ideal_gen_logs[y][v] for y in pr_ideal_gen_logs])) - aux_constant = (1/K_degree)*Reals(norm_bound).log() + aux_constant = (1/K_degree) * Reals(norm_bound).log() L_numbers = [] for v in range(r1): @@ -212,9 +213,9 @@ def points_of_bounded_height(K, dim, bound, prec=53): y_log = pr_ideal_gen_logs[y] g_log = unit_log + y_log bool1 = all(g_log[i] <= aux_constant + D_numbers[i] for i in range(r1)) - bool2 = all(g_log[j] <= 2*aux_constant + D_numbers[j] for j in range(r1, r + 1)) + bool2 = all(g_log[j] <= 2 * aux_constant + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: - g = unit*y + g = unit * y coordinate_list.append([g, g_log]) if len(coordinate_list) > 0: coordinate_space[norm] = coordinate_list @@ -227,13 +228,13 @@ def points_of_bounded_height(K, dim, bound, prec=53): a_coordinates = [] for k in range(bound + 1): - norm = k*a_norm + norm = k * a_norm if norm in coordinate_space: for pair in coordinate_space[norm]: g, g_log = pair if g in a: bool1 = all(g_log[i] <= a_const + D_numbers[i] for i in range(r1)) - bool2 = all(g_log[j] <= 2*a_const + D_numbers[j] for j in range(r1, r + 1)) + bool2 = all(g_log[j] <= 2 * a_const + D_numbers[j] for j in range(r1, r + 1)) if bool1 and bool2: a_coordinates.append(pair) From fc09436787030034d389e1e458a5212d9a170c41 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 31 Aug 2022 14:02:10 +0800 Subject: [PATCH 158/350] restore commented line --- src/sage/schemes/projective/proj_bdd_height.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index e20bf297962..b624038cd28 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -130,12 +130,9 @@ def points_of_bounded_height(K, dim, bound, prec=53): cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = [] - #for c in pari(cut_fund_unit_logs).qflll().python().columns(): - for c in cut_fund_unit_logs.columns(): + for c in pari(cut_fund_unit_logs).qflll().python(): new_unit = 1 for i in range(r): - print(fundamental_units[i]) - print(c[i]) new_unit *= fundamental_units[i]**c[i] lll_fund_units.append(new_unit) fundamental_units = lll_fund_units From e150af850836823d0c733ab16d345818149b67a5 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 31 Aug 2022 21:29:28 +0800 Subject: [PATCH 159/350] examples --- .../schemes/projective/proj_bdd_height.py | 26 +++++++++++++++++-- .../schemes/projective/projective_space.py | 7 +++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b624038cd28..01b0a7986e4 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -95,9 +95,29 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(x^3 + 5) + sage: list(points_of_bounded_height(K, 2, -3)) + [] + sage: list(points_of_bounded_height(K, 2, 2)) + [(1 : 0 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), + (1 : 1 : 0), (-1 : 1 : 1), (1 : -1 : 1), (-1 : -1 : 1), + (1 : 0 : 0), (-1 : 1 : 0), (0 : 0 : 1), (1 : 1 : 1), + (0 : 1 : 1)] + + :: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: K. = QuadraticField(3) + sage: list(points_of_bounded_height(K, 1, 1)) + [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] """ if bound < 1: - return [] + return iter([]) r1, r2 = K.signature() r = r1 + r2 - 1 @@ -249,4 +269,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - return points_of_bdd_height + + return iter(points_of_bdd_height) + diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 93b8d8c7b8a..2adfaafe764 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1879,6 +1879,13 @@ def points_of_bounded_height(self, **kwds): (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] + + :: + + sage: u = QQ['u'].0 + sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) + sage: len(list(P.points_of_bounded_height(bound=2))) + 265 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height From 1cc7b79098ebff1254eac1eb48e2892ef81e98e6 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 13:03:12 +0800 Subject: [PATCH 160/350] more examples and rel degree --- .../schemes/projective/proj_bdd_height.py | 6 +++- .../schemes/projective/projective_space.py | 28 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 01b0a7986e4..0a033719c6b 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -121,7 +121,11 @@ def points_of_bounded_height(K, dim, bound, prec=53): r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + + if K.is_relative: + K_degree = K.relative_degree() + else: + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 2adfaafe764..3374298ceb8 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1863,7 +1863,7 @@ def points_of_bounded_height(self, **kwds): kwds: - - ``bound`` - a real number + - ``bound`` - an integer - ``precision`` - (default: 53) a positive integer @@ -1885,7 +1885,25 @@ def points_of_bounded_height(self, **kwds): sage: u = QQ['u'].0 sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) sage: len(list(P.points_of_bounded_height(bound=2))) - 265 + 13 + + :: + + sage: CF. = CyclotomicField(5) + sage: R. = CF[] + sage: L. = CF.extension(x^5 + 5) + sage: Q. = ProjectiveSpace(L, 1) + sage: list(Q.points_of_bounded_height(bound=2)) + + :: + + sage: R. = QQ[] + sage: F. = NumberField(x^4 - 8*x^2 + 3) + sage: P. = ProjectiveSpace(F, 2) + sage: all([exp(p.global_height()) <= 1 for p in P.points_of_bounded_height(bound=1)]) + True + sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) + True """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height @@ -1901,16 +1919,14 @@ def points_of_bounded_height(self, **kwds): raise NotImplementedError("self must be projective space over a number field") bound = kwds.pop('bound') - B = bound**(self.base_ring().absolute_degree()) # convert to relative height - prec = kwds.pop('precision', 53) dim = self.dimension_relative() if field_type: - return points_of_bounded_height(R, dim, B, prec) + return points_of_bounded_height(R, dim, bound, prec) else: - return QQ_points_of_bounded_height(dim, B) + return QQ_points_of_bounded_height(dim, bound) def subscheme_from_Chow_form(self, Ch, dim): r""" From 26885489d3ebf9650467b7f0d2499c5d3d102b5f Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 1 Sep 2022 15:35:33 +0800 Subject: [PATCH 161/350] 34686: Support for relative number field --- src/sage/schemes/projective/proj_bdd_height.py | 7 +++++-- src/sage/schemes/projective/projective_space.py | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 0a033719c6b..b8f8c472be1 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -122,7 +122,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): r1, r2 = K.signature() r = r1 + r2 - 1 - if K.is_relative: + if K.is_relative(): K_degree = K.relative_degree() else: K_degree = K.degree() @@ -140,7 +140,10 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + if K.is_relative(): + class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] + else: + class_group_ideal_norms = [i.norm() for i in class_group_ideals] norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 3374298ceb8..7c559eef1af 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1889,11 +1889,13 @@ def points_of_bounded_height(self, **kwds): :: - sage: CF. = CyclotomicField(5) + sage: CF. = CyclotomicField(3) sage: R. = CF[] - sage: L. = CF.extension(x^5 + 5) + sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) sage: list(Q.points_of_bounded_height(bound=2)) + [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), + (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] :: From 83f385fc31a129c36389ac91cfd3c66d2d15c920 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 12:52:07 +0800 Subject: [PATCH 162/350] 32686: points_of_bounded_height for imaginary quadraitc field --- .../schemes/projective/proj_bdd_height.py | 104 ++++++++++++------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b8f8c472be1..b5b1cf865d9 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -18,6 +18,7 @@ """ import itertools + from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ from sage.rings.all import RealField @@ -61,6 +62,7 @@ def QQ_points_of_bounded_height(dim, bound): """ if bound < 1: return iter(set([])) + PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) @@ -71,6 +73,71 @@ def QQ_points_of_bounded_height(dim, bound): for u in unit_tuples: new_point = [a*b for a, b in zip(u, p)] + [p[dim]] points_of_bounded_height.add(PN(new_point)) + + return iter(points_of_bounded_height) + +def IQ_points_of_bounded_height(K, dim, bound): + r""" + Return an iterator of the points in ``self`` of absolute height of + at most ``bound`` in the imaginary quadratic field ``K``. + + INPUT: + + - ``K`` -- a number field + + - ``dim`` -- a positive interger + + - ``bound`` -- a real number + + OUTPUT: + + - an iterator of points of bounded height + """ + if bound < 1: + return iter(set([])) + + PN = ProjectiveSpace(K, dim) + unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) + points_of_bounded_height = [] + + class_group_ideals = [c.ideal() for c in K.class_group()] + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + class_number = len(class_group_ideals) + + possible_norm_set = set([]) + for i in range(class_number): + for k in range(1, bound + 1): + possible_norm_set.add(k*class_group_ideal_norms[i]) + + coordinate_space = dict() + coordinate_space[0] = [K(0)] + for m in possible_norm_set: + coordinate_space[m] = K.elements_of_norm(m) + + for i in range(class_number): + a = class_group_ideals[i] + a_norm = class_group_ideal_norms[i] + a_norm_bound = bound * a_norm + a_coordinates = [] + + for m in coordinate_space: + if m <= a_norm_bound: + for x in coordinate_space[m]: + if x in a: + a_coordinates.append(x) + + points_in_class_a = set([]) + t = len(a_coordinates) - 1 + increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) + for index_tuple in increasing_tuples: + point_coordinates = [a_coordinates[i] for i in index_tuple] + if a == K.ideal(point_coordinates): + for p in itertools.permutations(point_coordinates): + for u in unit_tuples: + new_point = [i*j for i, j in zip(u, p)] + [p[dim]] + points_in_class_a.add(PN(new_point)) + points_of_bounded_height += list(points_in_class_a) + return iter(points_of_bounded_height) def points_of_bounded_height(K, dim, bound, prec=53): @@ -95,37 +162,13 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height - - EXAMPLES: - - sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height - sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3 + 5) - sage: list(points_of_bounded_height(K, 2, -3)) - [] - sage: list(points_of_bounded_height(K, 2, 2)) - [(1 : 0 : 1), (-1 : 0 : 1), (0 : -1 : 1), (0 : 1 : 0), - (1 : 1 : 0), (-1 : 1 : 1), (1 : -1 : 1), (-1 : -1 : 1), - (1 : 0 : 0), (-1 : 1 : 0), (0 : 0 : 1), (1 : 1 : 1), - (0 : 1 : 1)] - - :: - - sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height - sage: K. = QuadraticField(3) - sage: list(points_of_bounded_height(K, 1, 1)) - [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] """ if bound < 1: - return iter([]) + return [] r1, r2 = K.signature() r = r1 + r2 - 1 - - if K.is_relative(): - K_degree = K.relative_degree() - else: - K_degree = K.degree() + K_degree = K.degree() K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -140,10 +183,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - if K.is_relative(): - class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] - else: - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + class_group_ideal_norms = [i.norm() for i in class_group_ideals] norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) @@ -276,6 +316,4 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - - return iter(points_of_bdd_height) - + return points_of_bdd_height From 2a67e06550a8d0b271c879194ee1d9b2010c0ab1 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 14:11:19 +0800 Subject: [PATCH 163/350] 32686: Support for imaginary quadratic field --- .../schemes/projective/proj_bdd_height.py | 38 ++++++++++++++++--- .../schemes/projective/projective_space.py | 21 +++++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b5b1cf865d9..f4f7a831db7 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -92,9 +92,18 @@ def IQ_points_of_bounded_height(K, dim, bound): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import IQ_points_of_bounded_height + sage: CF. = CyclotomicField(3) + sage: len(list(IQ_points_of_bounded_height(CF, 2, -1))) + 0 + sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) + 57 """ if bound < 1: - return iter(set([])) + return iter([]) PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) @@ -162,13 +171,25 @@ def points_of_bounded_height(K, dim, bound, prec=53): OUTPUT: - an iterator of points of bounded height + + EXAMPLES: + + sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height + sage: K. = NumberField(x^3 - 7) + sage: len(list(points_of_bounded_height(K, 2, 1))) + 13 """ if bound < 1: - return [] + return iter([]) r1, r2 = K.signature() r = r1 + r2 - 1 - K_degree = K.degree() + + if K.is_relative(): + K_degree = K.relative_degree() + else: + K_degree = K.degree() + K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -183,7 +204,12 @@ def points_of_bounded_height(K, dim, bound, prec=53): class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) - class_group_ideal_norms = [i.norm() for i in class_group_ideals] + + if K.is_relative(): + class_group_ideal_norms = [i.absolute_norm() for i in class_group_ideals] + else: + class_group_ideal_norms = [i.norm() for i in class_group_ideals] + norm_bound = bound * max(class_group_ideal_norms) fundamental_units = UnitGroup(K).fundamental_units() fund_unit_logs = list(map(log_embed, fundamental_units)) @@ -316,4 +342,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): new_point = [i*j for i, j in zip(u, p)] + [p[dim]] points_in_class_a.add(PN(new_point)) points_of_bdd_height += list(points_in_class_a) - return points_of_bdd_height + + return iter(points_of_bdd_height) + diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 7c559eef1af..03158bb1627 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1906,8 +1906,15 @@ def points_of_bounded_height(self, **kwds): True sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) True + + :: + + sage: K. = CyclotomicField(3) + sage: P. = ProjectiveSpace(K, 2) + sage: len(list(P.points_of_bounded_height(bound=1))) + 57 """ - from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, points_of_bounded_height + from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height R = self.base_ring() @@ -1926,6 +1933,18 @@ def points_of_bounded_height(self, **kwds): dim = self.dimension_relative() if field_type: + # for imaginary quadratic field + r1, r2 = R.signature() + r = r1 + r2 - 1 + + if R.is_relative(): + deg = R.relative_degree() + else: + deg = R.degree() + + if deg == 2 and r == 0: + return IQ_points_of_bounded_height(R, dim, bound) + return points_of_bounded_height(R, dim, bound, prec) else: return QQ_points_of_bounded_height(dim, bound) From f4e99ee347bd6ac2aec981e281aab08873b38230 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 3 Sep 2022 15:04:56 +0800 Subject: [PATCH 164/350] 32686: Raise degree to absolute degree --- .../schemes/projective/projective_space.py | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 03158bb1627..15d319b8f57 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1874,18 +1874,16 @@ def points_of_bounded_height(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: sorted(list(P.points_of_bounded_height(bound=3))) - [(-3 : 1), (-2 : 1), (-3/2 : 1), (-1 : 1), - (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (0 : 1), - (1/3 : 1), (1/2 : 1), (2/3 : 1), (1 : 0), - (1 : 1), (3/2 : 1), (2 : 1), (3 : 1)] + sage: sorted(list(P.points_of_bounded_height(bound=2))) + [(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1), + (1/2 : 1), (1 : 0), (1 : 1), (2 : 1)] :: sage: u = QQ['u'].0 sage: P. = ProjectiveSpace(NumberField(u^2 - 2, 'v'), 2) sage: len(list(P.points_of_bounded_height(bound=2))) - 13 + 265 :: @@ -1893,9 +1891,9 @@ def points_of_bounded_height(self, **kwds): sage: R. = CF[] sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) - sage: list(Q.points_of_bounded_height(bound=2)) + sage: sorted(list(Q.points_of_bounded_height(bound=1))) [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), - (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] + (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] :: @@ -1913,6 +1911,22 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(K, 2) sage: len(list(P.points_of_bounded_height(bound=1))) 57 + + :: + + sage: u = QQ['u'].0 + sage: K. = NumberField(u^2 - 2) + sage: P. = ProjectiveSpace(K, 1) + sage: len(list(P.points_of_bounded_height(bound=2))) + 24 + + :: + + sage: R. = QQ[] + sage: K. = NumberField(x^4 - 8*x^2 + 3) + sage: P. = ProjectiveSpace(K, 1) + sage: len(list(P.points_of_bounded_height(bound=2))) + 108 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height @@ -1930,6 +1944,8 @@ def points_of_bounded_height(self, **kwds): bound = kwds.pop('bound') prec = kwds.pop('precision', 53) + bound = bound**R.absolute_degree() + dim = self.dimension_relative() if field_type: From 34f1439986bcd5acccb2809d0a14e62d2173c7b3 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 12:21:22 +0800 Subject: [PATCH 165/350] 32686: Correct typo, add doc, and remove an unnecessary example --- src/sage/schemes/projective/proj_bdd_height.py | 6 +++--- src/sage/schemes/projective/projective_space.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index f4f7a831db7..a3a213246dc 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -1,7 +1,7 @@ r""" Points of bounded height in projective spaces -This module defines sunctions to compute points of bounded height of a given +This module defines functions to compute points of bounded height of a given number field with height less than a specified bound in projective spaces. Sage functions to list all elements of a given number field with height less @@ -108,7 +108,7 @@ def IQ_points_of_bounded_height(K, dim, bound): PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) points_of_bounded_height = [] - + class_group_ideals = [c.ideal() for c in K.class_group()] class_group_ideal_norms = [i.norm() for i in class_group_ideals] class_number = len(class_group_ideals) @@ -117,7 +117,7 @@ def IQ_points_of_bounded_height(K, dim, bound): for i in range(class_number): for k in range(1, bound + 1): possible_norm_set.add(k*class_group_ideal_norms[i]) - + coordinate_space = dict() coordinate_space[0] = [K(0)] for m in possible_norm_set: diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 15d319b8f57..acaf6683143 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1902,8 +1902,6 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(F, 2) sage: all([exp(p.global_height()) <= 1 for p in P.points_of_bounded_height(bound=1)]) True - sage: all([exp(p.global_height()) <= 3 for p in P.points_of_bounded_height(bound=3)]) - True :: @@ -1944,6 +1942,7 @@ def points_of_bounded_height(self, **kwds): bound = kwds.pop('bound') prec = kwds.pop('precision', 53) + # Convert between absolute and relative height for calling Krumm's algorithm bound = bound**R.absolute_degree() dim = self.dimension_relative() From 10c681c87c0de40448777a11dfc5c9e62774591c Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 12:58:50 +0800 Subject: [PATCH 166/350] 32686: Correct some examples in hyperplane_transformation_matrix --- .../schemes/projective/projective_space.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index acaf6683143..06da4cc06e0 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1547,8 +1547,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x) sage: plane2 = P.subscheme(y) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [-1 -1] - [ 1 0] + [0 1] + [1 0] sage: plane2(m*P((0,1))) (1 : 0) @@ -1558,10 +1558,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 2*y + z) sage: plane2 = P.subscheme(2*x + y + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -3 0 0 0] - [ 9 6 0 0] - [-3/2 -3 3/2 0] - [-1/2 -1 -1/2 1] + [ 1/2 0 0 0] + [-1/2 1 0 0] + [ 0 0 1/2 0] + [ 0 0 0 1] :: @@ -1569,8 +1569,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y) sage: plane2 = P.subscheme(y) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ 1 0] - [-1 -1] + [1 0] + [1 1] :: @@ -1580,9 +1580,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane2 = P.subscheme(x + v*y + v*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2) sage: m - [ -6/7*v - 2/7 0 0] - [ 2/7*v + 10/7 -4/7*v + 8/7 0] - [ -4/7*v + 1/7 -10/7*v - 8/7 1] + [-4/21*v + 23/21 10/21*v + 16/21 8/21*v + 1/7] + [ 8/21*v + 8/7 -8/21*v - 8/7 -8/21*v - 8/7] + [ 4/21*v + 5/21 -2/21*v + 8/21 1] :: @@ -1592,10 +1592,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(k*x + 2*k*y + z) sage: plane2 = P.subscheme(7*k*x + y + 9*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [ 297/410*k + 279/410 0 0 0] - [-3609/410*k + 4437/410 -1656/205*k + 2358/205 0 0] - [ 511/410*k - 24/205 511/205*k - 48/205 -107/205*k + 327/410 0] - [ 83/410*k - 107/205 83/205*k - 214/205 107/205*k + 83/410 1] + [ -4/65*k - 1/130 0 0 0] + [ -25/52*k - 21/52 -139/130*k + 7/130 137/260*k - 121/260 0] + [ 0 0 -4/65*k - 1/130 0] + [ 139/260*k + 123/260 139/130*k + 123/130 -123/260*k + 139/260 1] :: @@ -1627,9 +1627,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 9*t*y + z) sage: plane2 = P.subscheme(x + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -1/9*t -t^2 0] - [ -t^2 + 1/9*t 0 0] - [ 1/81 1/9*t -1/9*t + 1/81] + [ -1/81 -1/9*t -1/9*t] + [-1/9*t - 1/81 t^2 + 1/9*t 1/9*t + 1/81] + [ -1/9*t -t^2 -1/81] TESTS:: From 2c4d407b911c42fdc26377ad9b418ecc4af40cfc Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sun, 4 Sep 2022 13:15:28 +0800 Subject: [PATCH 167/350] 32686: mention Trac ticket 11328 for insert_row --- src/sage/schemes/projective/proj_bdd_height.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index a3a213246dc..31b376f96bb 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -274,6 +274,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): T = column_matrix(fund_unit_logs).delete_rows([r]).change_ring(QQ) + # insert_row only takes integers, see https://trac.sagemath.org/ticket/11328 M = ((-1)*matrix.identity(r)).insert_row(r, [Integer(1) for i in range(r)]) M = M.transpose().insert_row(0, [Integer(0) for i in range(r + 1)]).transpose() M = M.change_ring(QQ) From ac41c06e9e163d3e6ae1fd51b19f393289c779f3 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 9 Sep 2022 23:09:44 +0800 Subject: [PATCH 168/350] 32686: `bound` allows real numbers and `yield` instead of returning a list for points_of_bounded_height --- .../schemes/projective/proj_bdd_height.py | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 31b376f96bb..1f1ca0e5e1e 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -19,6 +19,8 @@ import itertools +from math import floor + from sage.schemes.projective.projective_space import ProjectiveSpace from sage.rings.rational_field import QQ from sage.rings.all import RealField @@ -66,15 +68,15 @@ def QQ_points_of_bounded_height(dim, bound): PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) - increasing_tuples = itertools.combinations_with_replacement(range(bound + 1), dim + 1) + increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) for t in increasing_tuples: if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - new_point = [a*b for a, b in zip(u, p)] + [p[dim]] - points_of_bounded_height.add(PN(new_point)) - - return iter(points_of_bounded_height) + PN_point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) + if PN_point not in points_of_bounded_height: + points_of_bounded_height.add(PN_point) + yield PN_point def IQ_points_of_bounded_height(K, dim, bound): r""" @@ -107,7 +109,6 @@ def IQ_points_of_bounded_height(K, dim, bound): PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) - points_of_bounded_height = [] class_group_ideals = [c.ideal() for c in K.class_group()] class_group_ideal_norms = [i.norm() for i in class_group_ideals] @@ -115,7 +116,7 @@ def IQ_points_of_bounded_height(K, dim, bound): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, bound + 1): + for k in range(1, ): possible_norm_set.add(k*class_group_ideal_norms[i]) coordinate_space = dict() @@ -142,12 +143,10 @@ def IQ_points_of_bounded_height(K, dim, bound): point_coordinates = [a_coordinates[i] for i in index_tuple] if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): - for u in unit_tuples: - new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - points_in_class_a.add(PN(new_point)) - points_of_bounded_height += list(points_in_class_a) - - return iter(points_of_bounded_height) + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point def points_of_bounded_height(K, dim, bound, prec=53): r""" @@ -233,7 +232,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, bound + 1): + for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) principal_ideal_gens = dict() @@ -318,7 +317,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): a_const = (logB + log_a_norm)/K_degree a_coordinates = [] - for k in range(bound + 1): + for k in range(floor(bound + 1)): norm = k * a_norm if norm in coordinate_space: for pair in coordinate_space[norm]: @@ -340,9 +339,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - new_point = [i*j for i, j in zip(u, p)] + [p[dim]] - points_in_class_a.add(PN(new_point)) - points_of_bdd_height += list(points_in_class_a) - - return iter(points_of_bdd_height) - + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point From 37f2d72672a9ce36772ab583fb6684ac0ea775d9 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Tue, 6 Sep 2022 10:33:15 +0800 Subject: [PATCH 169/350] 32686: Change ring when no common parent --- src/sage/schemes/projective/projective_space.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 06da4cc06e0..4d7c55e5fdd 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1616,8 +1616,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y + z) sage: plane2 = P.subscheme(z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [1 0 0] - [1 1 0] + [0 1 1] + [0 0 1] [1 1 1] :: @@ -1698,7 +1698,7 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): source_points.append(self(point)) base_list = [list(s) for s in source_points] elif len(source_points) == N + 1: - Ms = matrix(base_list + [point]) + Ms = matrix(base_list + [point.change_ring(self.base_ring())]) if not any([m == 0 for m in Ms.minors(N + 1)]): source_points.append(self(point)) break From 31d0587e058db1053850c52c8dc76be59159a9a2 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 00:14:14 +0800 Subject: [PATCH 170/350] 32686: Change some example outputs --- src/sage/schemes/projective/proj_bdd_height.py | 4 ++-- src/sage/schemes/projective/projective_space.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 1f1ca0e5e1e..fcd8557f459 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -51,8 +51,8 @@ def QQ_points_of_bounded_height(dim, bound): EXAMPLES: sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height - sage: list(QQ_points_of_bounded_height(1, 1)) - [(0 : 1), (1 : 0), (1 : 1), (-1 : 1)] + sage: sorted(list(QQ_points_of_bounded_height(1, 1))) + [(-1 : 1), (0 : 1), (1 : 0), (1 : 1)] sage: len(list(QQ_points_of_bounded_height(1, 5))) 40 diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 4d7c55e5fdd..806386b7151 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1892,8 +1892,8 @@ def points_of_bounded_height(self, **kwds): sage: L. = CF.extension(x^3 + 2) sage: Q. = ProjectiveSpace(L, 1) sage: sorted(list(Q.points_of_bounded_height(bound=1))) - [(0 : 1), (a : 1), (a + 1 : 1), (-a - 1 : 1), - (-a : 1), (-1 : 1), (1 : 1), (1 : 0)] + [(0 : 1), (1 : 0), (a + 1 : 1), (a : 1), + (-1 : 1), (-a - 1 : 1), (-a : 1), (1 : 1)] :: From 8afc292bef6d28bba6bd2fc6d6347ef0f3565f7b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 12:36:46 +0800 Subject: [PATCH 171/350] 32686: Debug `IQ_points_of_bounded_height` --- src/sage/schemes/projective/proj_bdd_height.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index fcd8557f459..8b0f04aaaa8 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -116,7 +116,7 @@ def IQ_points_of_bounded_height(K, dim, bound): possible_norm_set = set([]) for i in range(class_number): - for k in range(1, ): + for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) coordinate_space = dict() @@ -143,10 +143,11 @@ def IQ_points_of_bounded_height(K, dim, bound): point_coordinates = [a_coordinates[i] for i in index_tuple] if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + for u in unit_tuples: + PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) + if PN_point not in points_in_class_a: + points_in_class_a.add(PN_point) + yield PN_point def points_of_bounded_height(K, dim, bound, prec=53): r""" From b3b05c8d3a852ab14fbb01a092002eacf225d0bd Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Sat, 10 Sep 2022 12:51:51 +0800 Subject: [PATCH 172/350] 32686: Change example outputs --- .../schemes/projective/projective_space.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 806386b7151..9d60f748799 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1558,10 +1558,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 2*y + z) sage: plane2 = P.subscheme(2*x + y + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ 1/2 0 0 0] - [-1/2 1 0 0] - [ 0 0 1/2 0] - [ 0 0 0 1] + [1 0 0 0] + [0 4 0 0] + [0 0 2 0] + [0 0 0 1] :: @@ -1569,8 +1569,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y) sage: plane2 = P.subscheme(y) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [1 0] - [1 1] + [-1 0] + [ 1 1] :: @@ -1580,9 +1580,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane2 = P.subscheme(x + v*y + v*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2) sage: m - [-4/21*v + 23/21 10/21*v + 16/21 8/21*v + 1/7] - [ 8/21*v + 8/7 -8/21*v - 8/7 -8/21*v - 8/7] - [ 4/21*v + 5/21 -2/21*v + 8/21 1] + [ v 0 0] + [ 0 -2*v 0] + [ 0 0 1] :: @@ -1592,10 +1592,10 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(k*x + 2*k*y + z) sage: plane2 = P.subscheme(7*k*x + y + 9*z) sage: m = P.hyperplane_transformation_matrix(plane1, plane2); m - [ -4/65*k - 1/130 0 0 0] - [ -25/52*k - 21/52 -139/130*k + 7/130 137/260*k - 121/260 0] - [ 0 0 -4/65*k - 1/130 0] - [ 139/260*k + 123/260 139/130*k + 123/130 -123/260*k + 139/260 1] + [ 1 0 0 0] + [ 0 14*k 0 0] + [ 0 0 7/9 0] + [ 0 0 0 1] :: @@ -1616,8 +1616,8 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + y + z) sage: plane2 = P.subscheme(z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [0 1 1] - [0 0 1] + [1 0 0] + [1 1 0] [1 1 1] :: @@ -1627,9 +1627,9 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): sage: plane1 = P.subscheme(x + 9*t*y + z) sage: plane2 = P.subscheme(x + z) sage: P.hyperplane_transformation_matrix(plane1, plane2) - [ -1/81 -1/9*t -1/9*t] - [-1/9*t - 1/81 t^2 + 1/9*t 1/9*t + 1/81] - [ -1/9*t -t^2 -1/81] + [ 1 9*t 0] + [ 1 0 0] + [ 0 0 1] TESTS:: From 5958fc6c65d31535b9580837ef4e614d3432a0cb Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 11:35:59 +0800 Subject: [PATCH 173/350] 32686: Improve doc and return points in `self` --- .../schemes/projective/proj_bdd_height.py | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 8b0f04aaaa8..421fe48381a 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -35,8 +35,8 @@ def QQ_points_of_bounded_height(dim, bound): r""" - Return an iterator of the points in ``self`` of absolute height of - at most ``bound`` in the rational field. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most ``bound`` in the rational field. INPUT: @@ -65,7 +65,6 @@ def QQ_points_of_bounded_height(dim, bound): if bound < 1: return iter(set([])) - PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) @@ -73,15 +72,15 @@ def QQ_points_of_bounded_height(dim, bound): if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - PN_point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) - if PN_point not in points_of_bounded_height: - points_of_bounded_height.add(PN_point) - yield PN_point + point = self([a*b for a, b in zip(u, p)] + [p[dim]]) + if point not in points_of_bounded_height: + points_of_bounded_height.add(point) + yield point def IQ_points_of_bounded_height(K, dim, bound): r""" - Return an iterator of the points in ``self`` of absolute height of - at most ``bound`` in the imaginary quadratic field ``K``. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most ``bound`` in the imaginary quadratic field ``K``. INPUT: @@ -107,7 +106,6 @@ def IQ_points_of_bounded_height(K, dim, bound): if bound < 1: return iter([]) - PN = ProjectiveSpace(K, dim) unit_tuples = list(itertools.product(K.roots_of_unity(), repeat=dim)) class_group_ideals = [c.ideal() for c in K.class_group()] @@ -144,15 +142,15 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + if point not in points_in_class_a: + points_in_class_a.add(point) + yield point def points_of_bounded_height(K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of - absolute height of at most ``bound``. + absolute multiplicative height of at most ``bound``. ALGORITHM: @@ -194,7 +192,6 @@ def points_of_bounded_height(K, dim, bound, prec=53): roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) - PN = ProjectiveSpace(K, dim) log_embed = K.logarithmic_embedding() Reals = RealField(prec) @@ -340,7 +337,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - PN_point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) - if PN_point not in points_in_class_a: - points_in_class_a.add(PN_point) - yield PN_point + point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + if point not in points_in_class_a: + points_in_class_a.add(point) + yield point From 1c80864f268e410aa7dfcc3598a9036579b0be7b Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 11:52:40 +0800 Subject: [PATCH 174/350] 32686: Change `self` to `K` in non-rational points_of_bounded_height --- src/sage/schemes/projective/proj_bdd_height.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 421fe48381a..b48625b58e3 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -65,6 +65,7 @@ def QQ_points_of_bounded_height(dim, bound): if bound < 1: return iter(set([])) + PN = ProjectiveSpace(QQ, dim) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) points_of_bounded_height = set([]) increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) @@ -72,7 +73,7 @@ def QQ_points_of_bounded_height(dim, bound): if gcd(t) == 1: for p in itertools.permutations(t): for u in unit_tuples: - point = self([a*b for a, b in zip(u, p)] + [p[dim]]) + point = PN([a*b for a, b in zip(u, p)] + [p[dim]]) if point not in points_of_bounded_height: points_of_bounded_height.add(point) yield point @@ -142,7 +143,7 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + point = K([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point @@ -337,7 +338,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = self([i*j for i, j in zip(u, p)] + [p[dim]]) + point = K([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point From 5ec496e2a408c0d59f935252b32e4f91d6992740 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:03:27 +0800 Subject: [PATCH 175/350] 32686: Add `PN` to args of non-rational points_bdd --- src/sage/schemes/projective/proj_bdd_height.py | 16 +++++++++++----- src/sage/schemes/projective/projective_space.py | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index b48625b58e3..5f0bac1d35f 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -78,13 +78,15 @@ def QQ_points_of_bounded_height(dim, bound): points_of_bounded_height.add(point) yield point -def IQ_points_of_bounded_height(K, dim, bound): +def IQ_points_of_bounded_height(PN, K, dim, bound): r""" Return an iterator of the points in ``self`` of absolute multiplicative height of at most ``bound`` in the imaginary quadratic field ``K``. INPUT: + - ``PN`` -- a projective space + - ``K`` -- a number field - ``dim`` -- a positive interger @@ -99,7 +101,8 @@ def IQ_points_of_bounded_height(K, dim, bound): sage: from sage.schemes.projective.proj_bdd_height import IQ_points_of_bounded_height sage: CF. = CyclotomicField(3) - sage: len(list(IQ_points_of_bounded_height(CF, 2, -1))) + sage: P. = ProjectiveSpace(CF, 2) + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) 0 sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) 57 @@ -143,12 +146,12 @@ def IQ_points_of_bounded_height(K, dim, bound): if a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = K([i*j for i, j in zip(u, p)] + [p[dim]]) + point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point -def points_of_bounded_height(K, dim, bound, prec=53): +def points_of_bounded_height(PN, K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of absolute multiplicative height of at most ``bound``. @@ -159,6 +162,8 @@ def points_of_bounded_height(K, dim, bound, prec=53): INPUT: + - ``PN`` -- a projective space + - ``K`` -- a number field - ``dim`` -- a positive interger @@ -175,6 +180,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height sage: K. = NumberField(x^3 - 7) + sage: P. = ProjectiveSpace(K, 2) sage: len(list(points_of_bounded_height(K, 2, 1))) 13 """ @@ -338,7 +344,7 @@ def points_of_bounded_height(K, dim, bound, prec=53): if log_arch_height <= log_arch_height_bound and a == K.ideal(point_coordinates): for p in itertools.permutations(point_coordinates): for u in unit_tuples: - point = K([i*j for i, j in zip(u, p)] + [p[dim]]) + point = PN([i*j for i, j in zip(u, p)] + [p[dim]]) if point not in points_in_class_a: points_in_class_a.add(point) yield point diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 9d60f748799..b882767edbe 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1958,9 +1958,9 @@ def points_of_bounded_height(self, **kwds): deg = R.degree() if deg == 2 and r == 0: - return IQ_points_of_bounded_height(R, dim, bound) + return IQ_points_of_bounded_height(self, R, dim, bound) - return points_of_bounded_height(R, dim, bound, prec) + return points_of_bounded_height(self, R, dim, bound, prec) else: return QQ_points_of_bounded_height(dim, bound) From 2adb101bc163c52a029181a7df3ad91acc0c41ed Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:10:26 +0800 Subject: [PATCH 176/350] 32686: Correct tests --- src/sage/schemes/projective/proj_bdd_height.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 5f0bac1d35f..0cc57507158 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -104,7 +104,7 @@ def IQ_points_of_bounded_height(PN, K, dim, bound): sage: P. = ProjectiveSpace(CF, 2) sage: len(list(IQ_points_of_bounded_height(P, CF, 2, -1))) 0 - sage: len(list(IQ_points_of_bounded_height(CF, 2, 1))) + sage: len(list(IQ_points_of_bounded_height(P, CF, 2, 1))) 57 """ if bound < 1: @@ -181,7 +181,7 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): sage: from sage.schemes.projective.proj_bdd_height import points_of_bounded_height sage: K. = NumberField(x^3 - 7) sage: P. = ProjectiveSpace(K, 2) - sage: len(list(points_of_bounded_height(K, 2, 1))) + sage: len(list(points_of_bounded_height(P, K, 2, 1))) 13 """ if bound < 1: From a23735269b76390cc7dde97c500d0d9974510ff7 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Wed, 14 Sep 2022 12:17:04 +0800 Subject: [PATCH 177/350] 32686: Improve doc --- src/sage/schemes/projective/projective_space.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index b882767edbe..c68157714eb 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1852,8 +1852,8 @@ def _morphism(self, *args, **kwds): def points_of_bounded_height(self, **kwds): r""" - Return an iterator of the points in ``self`` of absolute height of - at most the given bound. + Return an iterator of the points in ``self`` of absolute multiplicative + height of at most the given bound. ALGORITHM: From 00af5c7d5f07ce95060549ef74ac1a2439f1cc13 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 22 Sep 2022 14:37:48 +0800 Subject: [PATCH 178/350] 32686: Correct doc and add an example --- src/sage/schemes/projective/projective_space.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index c68157714eb..7facb20875f 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1863,7 +1863,7 @@ def points_of_bounded_height(self, **kwds): kwds: - - ``bound`` - an integer + - ``bound`` - a real number - ``precision`` - (default: 53) a positive integer @@ -1925,6 +1925,14 @@ def points_of_bounded_height(self, **kwds): sage: P. = ProjectiveSpace(K, 1) sage: len(list(P.points_of_bounded_height(bound=2))) 108 + + :: + + R. = QQ[] + K. = NumberField(x^5 + x^3 + 1) + P. = ProjectiveSpace(K, 2) + L = P.points_of_bounded_height(bound=1.2) + 0 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height From 98a467602c4f4959cb847963ad08ade3334841b9 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 22 Sep 2022 15:16:57 +0800 Subject: [PATCH 179/350] 32686: Correct example --- src/sage/schemes/projective/projective_space.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 7facb20875f..117e071a67b 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -1928,11 +1928,12 @@ def points_of_bounded_height(self, **kwds): :: - R. = QQ[] - K. = NumberField(x^5 + x^3 + 1) - P. = ProjectiveSpace(K, 2) - L = P.points_of_bounded_height(bound=1.2) - 0 + sage: R. = QQ[] + sage: K. = NumberField(x^5 + x^3 + 1) + sage: P. = ProjectiveSpace(K, 2) + sage: L = P.points_of_bounded_height(bound=1.2) + sage: len(list(L)) + 109 """ from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height, IQ_points_of_bounded_height, points_of_bounded_height From e89ba553fa43eea1539f39cc423fd0174d371b64 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 22 Sep 2022 12:16:08 -0700 Subject: [PATCH 180/350] .github/workflows/ci-linux.yml: Fix typo which prevented 'minimal-*' from starting --- .github/workflows/ci-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index d5935789219..f1b387bd230 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -89,7 +89,7 @@ jobs: targets: build doc-html targets_optional: ptest tox_packages_factors: >- - ["minimal] + ["minimal"] docker_push_repository: ghcr.io/${{ github.repository }}/ maximal-pre: From 43a78040cb126b088bdc2b9767dc4f3482e56820 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 13:27:39 +0200 Subject: [PATCH 181/350] make revert lazy enough --- src/sage/data_structures/stream.py | 3 ++- src/sage/rings/lazy_series.py | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index a80f606961d..c0e373bf000 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1275,7 +1275,8 @@ class Stream_zero(Stream): """ def __init__(self, is_sparse): - """Initialize ``self``. + """ + Initialize ``self``. TESTS:: diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index f83fd91141a..9bf0ade9493 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -962,7 +962,8 @@ def __bool__(self): return any(self[i] for i in range(v, v + prec)) def define(self, s): - r"""Define an equation by ``self = s``. + r""" + Define an equation by ``self = s``. INPUT: @@ -1164,6 +1165,16 @@ def define(self, s): sage: L = LazySymmetricFunctions(s) sage: f = L.undefined() sage: f.define(1+(s[1]*f).revert()) + sage: f + s[] + s[1] + (-s[1,1]-s[2]) + + (3*s[1,1,1]+6*s[2,1]+3*s[3]) + + (-13*s[1,1,1,1]-39*s[2,1,1]-26*s[2,2]-39*s[3,1]-13*s[4]) + + (69*s[1,1,1,1,1]+276*s[2,1,1,1]+345*s[2,2,1]+414*s[3,1,1]+345*s[3,2]+276*s[4,1]+69*s[5]) + + (-419*s[1,1,1,1,1,1]-2095*s[2,1,1,1,1]-3771*s[2,2,1,1]-2095*s[2,2,2]-4190*s[3,1,1,1]-6704*s[3,2,1]-2095*s[3,3]-4190*s[4,1,1]-3771*s[4,2]-2095*s[5,1]-419*s[6]) + + O^7 + + sage: (f*s[1]).revert() + 1 - f + O^7 """ if not isinstance(self._coeff_stream, Stream_uninitialized) or self._coeff_stream._target is not None: @@ -3682,11 +3693,11 @@ def revert(self): sage: f = L([-1, 0, -1], valuation=1, constant=-1) sage: f.revert() - -z + z^3 - z^4 - 2*z^5 + 6*z^6 + z^7 + O(z^8) + (1/(-1))*z + z^3 - z^4 - 2*z^5 + 6*z^6 + z^7 + O(z^8) sage: f = L([-1], valuation=1, degree=3, constant=-1) sage: f.revert() - -z + z^3 - z^4 - 2*z^5 + 6*z^6 + z^7 + O(z^8) + (1/(-1))*z + z^3 - z^4 - 2*z^5 + 6*z^6 + z^7 + O(z^8) """ P = self.parent() coeff_stream = self._coeff_stream @@ -5381,9 +5392,11 @@ def revert(self): # if coeff_stream[0]: # raise ValueError("cannot determine whether the compositional inverse exists") - X = R(Partition([1])) - b = coeff_stream[1][Partition([1])] - b_inv = R.base_ring()(~b) + # TODO: we assume that not coeff_stream[0], can we test it? + la = Partition([1]) + X = R(la) + b = P(lambda n: 0 if n else coeff_stream[1][la]) # TODO: we want a lazy version of Stream_exact + b_inv = P(lambda n: 0 if n else ~coeff_stream[1][la]) # TODO: we want a lazy version of Stream_exact g = P.undefined(valuation=1) g.define(b_inv * (X - (self - b * X)(g))) return g From a3681d7722fb332da9f111e2ca2709550d4b0179 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 17:21:10 +0200 Subject: [PATCH 182/350] fix doctests in Stream_cauchy_compose --- src/sage/data_structures/stream.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index c0e373bf000..edc83520cdf 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -1836,9 +1836,9 @@ def get_coefficient(self, n): sage: f = Stream_function(lambda n: n, True, 1) sage: g = Stream_function(lambda n: n^2, True, 1) sage: h = Stream_cauchy_compose(f, g) - sage: h.get_coefficient(5) + sage: h[5] # indirect doctest 527 - sage: [h.get_coefficient(i) for i in range(10)] + sage: [h[i] for i in range(10)] # indirect doctest [0, 1, 6, 28, 124, 527, 2172, 8755, 34704, 135772] """ fv = self._left._approximate_order From 498c0436a0b6aebb1760a2860484f3aa39105910 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 18:21:29 +0200 Subject: [PATCH 183/350] fix division by 1 and by itself --- src/sage/rings/lazy_series.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 9bf0ade9493..e332f8cf033 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -2858,8 +2858,7 @@ def __invert__(self): return P.element_class(P, coeff_stream_inverse) def _div_(self, other): - r""" - Return ``self`` divided by ``other``. + r"""Return ``self`` divided by ``other``. INPUT: @@ -2935,15 +2934,41 @@ def _div_(self, other): sage: L(lambda n: n) / (t + t^2) 1 + t + 2*t^2 + 2*t^3 + 3*t^4 + 3*t^5 + O(t^6) + + Check that division by one does nothing, and division by + itself gives one:: + + sage: s = SymmetricFunctions(ZZ).s() + sage: S = LazySymmetricFunctions(s) + sage: f = S(lambda n: s(Partitions(n).random_element())) + sage: f / S.one() is f + True + + sage: f / f + s[] + """ if isinstance(other._coeff_stream, Stream_zero): raise ZeroDivisionError("cannot divide by 0") P = self.parent() left = self._coeff_stream + # self == 0 if isinstance(left, Stream_zero): return P.zero() right = other._coeff_stream + + # right == 1 + if (isinstance(right, Stream_exact) + and right._initial_coefficients == (P._internal_poly_ring.base_ring().one(),) + and right.order() == 0 + and not right._constant): + return self + + # self is right + if left is right: + return P.one() + if (P._minimal_valuation is not None and left._true_order and left._approximate_order < right._approximate_order): From e6ae2366fc508188703fd2aa4b7a3595409a55fd Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 19:22:11 +0200 Subject: [PATCH 184/350] fix and slightly simplify _element_constructor_ --- src/sage/combinat/sf/classical.py | 134 +++++++++++++++++------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/src/sage/combinat/sf/classical.py b/src/sage/combinat/sf/classical.py index ea77ed7c8a3..0477629f3d1 100644 --- a/src/sage/combinat/sf/classical.py +++ b/src/sage/combinat/sf/classical.py @@ -119,6 +119,24 @@ def _element_constructor_(self, x): Traceback (most recent call last): ... TypeError: do not know how to make x (= [[2, 1], [1]]) an element of self + + Check that :trac:`34576` is fixed:: + + sage: s = SymmetricFunctions(ZZ).s() + sage: f = s(0/2); f + 0 + sage: f == 0 + True + sage: f._monomial_coefficients + {} + + sage: s2 = SymmetricFunctions(GF(2)).s() + sage: f = s2(2*s[2,1]); f + 0 + sage: f == 0 + True + sage: f._monomial_coefficients + {} """ R = self.base_ring() @@ -126,7 +144,6 @@ def _element_constructor_(self, x): if isinstance(x, int): x = Integer(x) - ############## # Partitions # ############## @@ -140,9 +157,9 @@ def _element_constructor_(self, x): # Dual bases # ############## elif sfa.is_SymmetricFunction(x) and hasattr(x, 'dual'): - #Check to see if it is the dual of some other basis - #If it is, try to coerce its corresponding element - #in the other basis + # Check to see if it is the dual of some other basis + # If it is, try to coerce its corresponding element + # in the other basis return self(x.dual()) ################################################################## @@ -161,105 +178,97 @@ def _element_constructor_(self, x): elif isinstance(x, self.Element): P = x.parent() - #same base ring + # same base ring if P is self: return x - #different base ring + # different base ring else: - return eclass(self, dict([ (e1,R(e2)) for e1,e2 in x._monomial_coefficients.items()])) + return eclass(self, {la: rc for la, c in x._monomial_coefficients.items() + if (rc := R(c))}) ################################################## # Classical Symmetric Functions, different basis # ################################################## elif isinstance(x, SymmetricFunctionAlgebra_classical.Element): + P = x.parent() + m = x.monomial_coefficients() - R = self.base_ring() - xP = x.parent() - xm = x.monomial_coefficients() - - #determine the conversion function. + # determine the conversion function. try: - t = conversion_functions[(xP.basis_name(),self.basis_name())] + t = conversion_functions[(P.basis_name(), self.basis_name())] except AttributeError: - raise TypeError("do not know how to convert from %s to %s"%(xP.basis_name(), self.basis_name())) - - if R == QQ and xP.base_ring() == QQ: - if xm: - return self._from_dict(t(xm)._monomial_coefficients, coerce=True) - else: - return self.zero() + raise TypeError("do not know how to convert from %s to %s" + % (P.basis_name(), self.basis_name())) + + if R == QQ and P.base_ring() == QQ: + if m: + return self._from_dict(t(m)._monomial_coefficients, + coerce=True) + return self.zero() else: - f = lambda part: self._from_dict(t( {part: ZZ.one()} )._monomial_coefficients) + f = lambda part: self._from_dict(t({part: ZZ.one()})._monomial_coefficients) return self._apply_module_endomorphism(x, f) - ############################### # Hall-Littlewood Polynomials # ############################### elif isinstance(x, hall_littlewood.HallLittlewood_generic.Element): # - #Qp: Convert to Schur basis and then convert to self - # - if isinstance(x, hall_littlewood.HallLittlewood_qp.Element): - Qp = x.parent() - sx = Qp._s._from_cache(x, Qp._s_cache, Qp._self_to_s_cache, t=Qp.t) - return self(sx) - # - #P: Convert to Schur basis and then convert to self + # Qp: Convert to Schur basis and then convert to self # - elif isinstance(x, hall_littlewood.HallLittlewood_p.Element): + if isinstance(x, (hall_littlewood.HallLittlewood_qp.Element, + hall_littlewood.HallLittlewood_p.Element)): P = x.parent() sx = P._s._from_cache(x, P._s_cache, P._self_to_s_cache, t=P.t) return self(sx) # - #Q: Convert to P basis and then convert to self + # Q: Convert to P basis and then convert to self # elif isinstance(x, hall_littlewood.HallLittlewood_q.Element): - return self( x.parent()._P( x ) ) + return self(x.parent()._P(x)) ####### # LLT # ####### - #Convert to m and then to self. + # Convert to m and then to self. elif isinstance(x, llt.LLT_generic.Element): P = x.parent() - BR = self.base_ring() - zero = BR.zero() - PBR = P.base_ring() - if not BR.has_coerce_map_from(PBR): - raise TypeError("no coerce map from x's parent's base ring (= %s) to self's base ring (= %s)"%(PBR, self.base_ring())) + Rx = P.base_ring() + zero = R.zero() + if not R.has_coerce_map_from(Rx): + raise TypeError("no coerce map from x's parent's base ring (= %s) to self's base ring (= %s)" + % (Rx, R)) z_elt = {} for m, c in x._monomial_coefficients.items(): n = sum(m) P._m_cache(n) for part in P._self_to_m_cache[n][m]: - z_elt[part] = z_elt.get(part, zero) + BR(c*P._self_to_m_cache[n][m][part].subs(t=P.t)) + z_elt[part] = z_elt.get(part, zero) + R(c*P._self_to_m_cache[n][m][part].subs(t=P.t)) m = P._sym.monomial() - return self( m._from_dict(z_elt) ) + return self(m._from_dict(z_elt)) ######################### # Macdonald Polynomials # ######################### elif isinstance(x, macdonald.MacdonaldPolynomials_generic.Element): - if isinstance(x, macdonald.MacdonaldPolynomials_j.Element): - J = x.parent() - sx = J._s._from_cache(x, J._s_cache, J._self_to_s_cache, q=J.q, t=J.t) + if isinstance(x, (macdonald.MacdonaldPolynomials_j.Element, + macdonald.MacdonaldPolynomials_s.Element)): + P = x.parent() + sx = P._s._from_cache(x, P._s_cache, P._self_to_s_cache, q=P.q, t=P.t) return self(sx) - elif isinstance(x, (macdonald.MacdonaldPolynomials_q.Element, macdonald.MacdonaldPolynomials_p.Element)): + elif isinstance(x, (macdonald.MacdonaldPolynomials_q.Element, + macdonald.MacdonaldPolynomials_p.Element)): J = x.parent()._J jx = J(x) sx = J._s._from_cache(jx, J._s_cache, J._self_to_s_cache, q=J.q, t=J.t) return self(sx) - elif isinstance(x, (macdonald.MacdonaldPolynomials_h.Element,macdonald.MacdonaldPolynomials_ht.Element)): - H = x.parent() - sx = H._self_to_s(x) - return self(sx) - elif isinstance(x, macdonald.MacdonaldPolynomials_s.Element): - S = x.parent() - sx = S._s._from_cache(x, S._s_cache, S._self_to_s_cache, q=S.q, t=S.t) + elif isinstance(x, (macdonald.MacdonaldPolynomials_h.Element, + macdonald.MacdonaldPolynomials_ht.Element)): + P = x.parent() + sx = P._self_to_s(x) return self(sx) else: raise TypeError @@ -272,8 +281,9 @@ def _element_constructor_(self, x): P = x.parent() mx = P._m._from_cache(x, P._m_cache, P._self_to_m_cache, t=P.t) return self(mx) - if isinstance(x, (jack.JackPolynomials_j.Element, jack.JackPolynomials_q.Element)): - return self( x.parent()._P(x) ) + if isinstance(x, (jack.JackPolynomials_j.Element, + jack.JackPolynomials_q.Element)): + return self(x.parent()._P(x)) else: raise TypeError @@ -281,21 +291,25 @@ def _element_constructor_(self, x): # Bases defined by orthogonality and triangularity # #################################################### elif isinstance(x, orthotriang.SymmetricFunctionAlgebra_orthotriang.Element): - #Convert to its base and then to self - xp = x.parent() - if self is xp._sf_base: - return xp._sf_base._from_cache(x, xp._base_cache, xp._self_to_base_cache) + # Convert to its base and then to self + P = x.parent() + if self is P._sf_base: + return P._sf_base._from_cache(x, P._base_cache, P._self_to_base_cache) else: - return self( xp._sf_base(x) ) + return self( P._sf_base(x) ) ################################# # Last shot -- try calling R(x) # ################################# else: try: - return eclass(self, {_Partitions([]): R(x)}) + c = R(x) except Exception: raise TypeError("do not know how to make x (= {}) an element of self".format(x)) + else: + if not c: + return self.zero() + return eclass(self, {_Partitions([]): c}) # This subclass is currently needed for the test above: # isinstance(x, SymmetricFunctionAlgebra_classical.Element): From 291316946bf628b46830e3cf80922d8e3c8ef73d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 23:03:25 +0200 Subject: [PATCH 185/350] include _test_div --- src/sage/rings/lazy_series_ring.py | 41 +++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ed7292bf1e7..258157dcf2b 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -897,9 +897,44 @@ def _test_invert(self, **options): continue y = ~x e = y * x - tester.assertFalse(x.is_zero()) - tester.assertTrue(e.is_one()) - tester.assertEqual(y.valuation(), -x.valuation()) + tester.assertFalse(x.is_zero(), "zero should not be invertible") + tester.assertTrue(e.is_one(), "an element (%s) times its inverse should be 1" % x) + tester.assertEqual(y.valuation(), -x.valuation(), "the valuation of the inverse should be the negative of the valuation of the element (%s)" % x) + + def _test_div(self, **options): + r""" + Test division of elements of this ring. + + INPUT: + + - ``options`` -- any keyword arguments accepted by :meth:`_tester` + + EXAMPLES:: + + sage: LazyLaurentSeriesRing.options.halting_precision(5) + sage: L = LazyLaurentSeriesRing(QQ, 'z') + sage: L._test_div() + sage: LazyLaurentSeriesRing.options._reset() # reset the options + + .. SEEALSO:: + + :class:`TestSuite` + """ + from sage.misc.misc import some_tuples + tester = self._tester(**options) + + elements = list(tester.some_elements()) + for x, y in some_tuples(elements, 2, tester._max_runs): + try: + z = x / y + except (ZeroDivisionError, ValueError): + tester.assertFalse(y.is_unit(), "it should be possible to divide an element (%s) by a unit (%s)" % (x, y)) + else: + xx = z * y + tester.assertFalse(y.is_zero(), "it should not be possible to divide by zero") + if not x.is_zero(): + tester.assertEqual(z.valuation(), x.valuation() - y.valuation(), "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y)) + tester.assertEqual(xx, x, "the element (%s) should be the quotient times the divisor (%s)" % (x, y)) def _test_revert(self, **options): """ From d578d8b9b55979e9b9d31464674be2d5aed7f688 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 23 Sep 2022 23:45:53 +0200 Subject: [PATCH 186/350] better error handling in _test_div --- src/sage/rings/lazy_series_ring.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 258157dcf2b..5017b2c2940 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -929,11 +929,21 @@ def _test_div(self, **options): z = x / y except (ZeroDivisionError, ValueError): tester.assertFalse(y.is_unit(), "it should be possible to divide an element (%s) by a unit (%s)" % (x, y)) + except Exception as error: + raise ValueError("could not compute (%s)/(%s): %s" % (x, y, error)) else: xx = z * y tester.assertFalse(y.is_zero(), "it should not be possible to divide by zero") if not x.is_zero(): - tester.assertEqual(z.valuation(), x.valuation() - y.valuation(), "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y)) + try: + v_z = z.valuation() + except Exception as error: + raise ValueError("could not compute the valuation of the quotient (%s)/(%s): %s" % (x, y, error)) + else: + v_x = x.valuation() + v_y = y.valuation() + tester.assertEqual(v_z, v_x - v_y, "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y)) + tester.assertEqual(xx, x, "the element (%s) should be the quotient times the divisor (%s)" % (x, y)) def _test_revert(self, **options): From 4ce10c7f4810180964e2925596aaae6448186de3 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 24 Sep 2022 01:04:48 +0200 Subject: [PATCH 187/350] make TestSuite.run pass --- src/sage/rings/lazy_series_ring.py | 48 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index 5017b2c2940..c78c723f968 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -891,8 +891,8 @@ def _test_invert(self, **options): elements = tester.some_elements() for x in elements: - # because of laziness, we cannot try to invert x, because - # this will always succeed, except if the series is 'exact' + # because of laziness, creating the inverse of x should + # always succeed except if the series is 'exact' if not x.is_unit(): continue y = ~x @@ -925,25 +925,20 @@ def _test_div(self, **options): elements = list(tester.some_elements()) for x, y in some_tuples(elements, 2, tester._max_runs): + # because of laziness, creating the inverse of x should + # always succeed except if the series is 'exact' + if not y.is_unit(): + continue + z = x / y + xx = z * y try: - z = x / y - except (ZeroDivisionError, ValueError): - tester.assertFalse(y.is_unit(), "it should be possible to divide an element (%s) by a unit (%s)" % (x, y)) + v_z = z.valuation() except Exception as error: - raise ValueError("could not compute (%s)/(%s): %s" % (x, y, error)) + raise ValueError("could not compute the valuation of the quotient (%s)/(%s): %s" % (x, y, error)) else: - xx = z * y - tester.assertFalse(y.is_zero(), "it should not be possible to divide by zero") - if not x.is_zero(): - try: - v_z = z.valuation() - except Exception as error: - raise ValueError("could not compute the valuation of the quotient (%s)/(%s): %s" % (x, y, error)) - else: - v_x = x.valuation() - v_y = y.valuation() - tester.assertEqual(v_z, v_x - v_y, "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y)) - + v_x = x.valuation() + v_y = y.valuation() + tester.assertEqual(v_z, v_x - v_y, "the valuation of the quotient should be the difference of the valuations of the elements (%s and %s)" % (x, y)) tester.assertEqual(xx, x, "the element (%s) should be the quotient times the divisor (%s)" % (x, y)) def _test_revert(self, **options): @@ -972,9 +967,24 @@ def _test_revert(self, **options): elements = tester.some_elements() count = 0 for x in elements: + # because of laziness, creating the compositional inverse + # of x should always succeed, except if the series is + # 'exact' or if it has negative valuation vx = x.valuation() + if (vx != 1 + and not (isinstance(x._coeff_stream, Stream_exact) + and ((vx == 0 + and x._coeff_stream._degree == 2 + and not x._coeff_stream._constant) + or (vx == -1 + and x._coeff_stream._degree == 0 + and not x._coeff_stream._constant)))): + continue try: y = x.revert() + except Exception as error: + raise AssertionError("compositional inverse of %s should exist: %s" % (x, error)) + try: vy = y.valuation() m = y[vy] except NotImplementedError: @@ -1524,7 +1534,7 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: TestSuite(L).run() sage: L = LazyPowerSeriesRing(GF(5), 's, t') - sage: TestSuite(L).run() + sage: TestSuite(L).run(skip=['_test_fraction_field']) sage: L = LazyPowerSeriesRing(Zmod(6), 't') sage: TestSuite(L).run(skip=['_test_revert']) From af1c0cb96649310235774ba7ad9f270b7b85abcd Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 24 Sep 2022 01:41:08 +0200 Subject: [PATCH 188/350] make remaining doctests pass --- src/sage/rings/lazy_series.py | 47 +++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index e332f8cf033..20a4733c630 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -3596,6 +3596,7 @@ def __call__(self, g, *, check=True): def coefficient(n): return sum(self[i] * (g**i)[n] for i in range(n+1)) + R = P._internal_poly_ring.base_ring() coeff_stream = Stream_function(coefficient, P._sparse, 1) return P.element_class(P, coeff_stream) @@ -3773,11 +3774,11 @@ def revert(self): if coeff_stream._approximate_order > 1: raise ValueError("compositional inverse does not exist") - #if not coeff_stream[1]: - # raise ValueError("compositional inverse does not exist") + # if not coeff_stream[1]: + # raise ValueError("compositional inverse does not exist") - #if coeff_stream[0]: - # raise ValueError("cannot determine whether the compositional inverse exists") + if coeff_stream[0]: + raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() g = P.undefined(valuation=1) @@ -4424,6 +4425,7 @@ def __call__(self, *g, check=True): # we assume that the valuation of self[i](g) is at least i def coefficient(n): return sum(self[i] * (g0**i)[n] for i in range(n+1)) + coeff_stream = Stream_function(coefficient, P._sparse, 1) return P.element_class(P, coeff_stream) @@ -4435,7 +4437,7 @@ def coefficient(n): def coefficient(n): r = R.zero() - for i in range(n//gv+1): + for i in range(n // gv + 1): # Make sure the element returned from the composition is in P r += P(self[i](g))[n] return r @@ -4580,11 +4582,12 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! -# if not coeff_stream[1]: -# raise ValueError("compositional inverse does not exist") -# -# if coeff_stream[0]: -# raise ValueError("cannot determine whether the compositional inverse exists") + # if not coeff_stream[1]: + # raise ValueError("compositional inverse does not exist") + + if coeff_stream[0]: + raise ValueError("cannot determine whether the compositional inverse exists") + z = P.gen() g = P.undefined(valuation=1) # the following is mathematically equivalent to @@ -5339,7 +5342,8 @@ def revert(self): TESTS:: sage: f = L(lambda n: h[n]) - 1 - h[1] - sage: f.compositional_inverse() + sage: g = f.revert() + sage: g[1] Traceback (most recent call last): ... ValueError: compositional inverse does not exist @@ -5411,17 +5415,24 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! -# if not coeff_stream[1]: -# raise ValueError("compositional inverse does not exist") -# -# if coeff_stream[0]: -# raise ValueError("cannot determine whether the compositional inverse exists") + # if not coeff_stream[1]: + # raise ValueError("compositional inverse does not exist") + + if coeff_stream[0]: + raise ValueError("cannot determine whether the compositional inverse exists") - # TODO: we assume that not coeff_stream[0], can we test it? la = Partition([1]) X = R(la) + def coefficient(n): + if n: + return 0 + c = coeff_stream[1][la] + if c.is_unit(): + return ~c + raise ValueError("compositional inverse does not exist") + b = P(lambda n: 0 if n else coeff_stream[1][la]) # TODO: we want a lazy version of Stream_exact - b_inv = P(lambda n: 0 if n else ~coeff_stream[1][la]) # TODO: we want a lazy version of Stream_exact + b_inv = P(coefficient) # TODO: we want a lazy version of Stream_exact g = P.undefined(valuation=1) g.define(b_inv * (X - (self - b * X)(g))) return g From b8443aa31535487f03e56574b4ec60b5bab63961 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 24 Sep 2022 11:43:06 +0200 Subject: [PATCH 189/350] add test, remove bad checks that prevent test from passing --- src/sage/rings/lazy_series.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 20a4733c630..310ec388f4d 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1161,6 +1161,14 @@ def define(self, s): sage: f 1 + t - t^2 + 3*t^3 - 13*t^4 + 69*t^5 - 419*t^6 + O(t^7) + sage: f = L.undefined(valuation=0) + sage: f.define(1+(t*~f).revert()) + sage: f + 1 + t + t^2 + 2*t^3 + 6*t^4 + 23*t^5 + 104*t^6 + O(t^7) + sage: oeis(f[:20]) # optional, internet + 0: A030266: Shifts left under COMPOSE transform with itself. + 1: A110447: Permutations containing 3241 patterns only as part of 35241 patterns. + sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(s) sage: f = L.undefined() @@ -3763,22 +3771,22 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! - if any(coeff_stream[i] for i in range(coeff_stream._approximate_order, -1)): - raise ValueError("compositional inverse does not exist") - - if coeff_stream[-1]: - if coeff_stream[0] or coeff_stream[1]: - raise ValueError("compositional inverse does not exist") - raise ValueError("cannot determine whether the compositional inverse exists") + # if any(coeff_stream[i] for i in range(coeff_stream._approximate_order, -1)): + # raise ValueError("compositional inverse does not exist") + # + # if coeff_stream[-1]: + # if coeff_stream[0] or coeff_stream[1]: + # raise ValueError("compositional inverse does not exist") + # raise ValueError("cannot determine whether the compositional inverse exists") - if coeff_stream._approximate_order > 1: - raise ValueError("compositional inverse does not exist") + # if coeff_stream._approximate_order > 1: + # raise ValueError("compositional inverse does not exist") # if not coeff_stream[1]: # raise ValueError("compositional inverse does not exist") - if coeff_stream[0]: - raise ValueError("cannot determine whether the compositional inverse exists") + # if coeff_stream[0]: + # raise ValueError("cannot determine whether the compositional inverse exists") z = P.gen() g = P.undefined(valuation=1) From aa646eb8567e68a4328cafdd007786895472384a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 24 Sep 2022 12:17:22 +0200 Subject: [PATCH 190/350] add currently failing test --- src/sage/rings/lazy_series.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 310ec388f4d..985fab47f41 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1165,10 +1165,25 @@ def define(self, s): sage: f.define(1+(t*~f).revert()) sage: f 1 + t + t^2 + 2*t^3 + 6*t^4 + 23*t^5 + 104*t^6 + O(t^7) - sage: oeis(f[:20]) # optional, internet + sage: oeis(f[1:20]) # optional, internet 0: A030266: Shifts left under COMPOSE transform with itself. 1: A110447: Permutations containing 3241 patterns only as part of 35241 patterns. + The following should work, but doesn't:: + + sage: f = L.undefined(valuation=0) + sage: f.define(1 + t*~f + (t*f).revert()) + sage: f + + sage: a = var(["a%s" % n for n in range(10)]) + sage: L. = LazyLaurentSeriesRing(SR) + sage: f = sum(a[k] * t^k for k in range(10)) + sage: g = -f + 1 + t*~f + (t*f).revert() + sage: g[5].subs(a0=1, a1=2, a2=-4, a3=20, a4=-144, a5=1296) + 0 + sage: f.map_coefficients(lambda c: c.subs(a0=1, a1=2, a2=-4, a3=20, a4=-144, a5=1296)) + 1 + 2*t - 4*t^2 + 20*t^3 - 144*t^4 + 1296*t^5 + sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(s) sage: f = L.undefined() From 912d5b28c6dca27235caa013f0289e54b9fd605e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 24 Sep 2022 12:26:44 +0200 Subject: [PATCH 191/350] correct bad test --- src/sage/rings/lazy_series.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 985fab47f41..5a21dbe7425 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -962,8 +962,7 @@ def __bool__(self): return any(self[i] for i in range(v, v + prec)) def define(self, s): - r""" - Define an equation by ``self = s``. + r"""Define an equation by ``self = s``. INPUT: @@ -1169,20 +1168,14 @@ def define(self, s): 0: A030266: Shifts left under COMPOSE transform with itself. 1: A110447: Permutations containing 3241 patterns only as part of 35241 patterns. - The following should work, but doesn't:: + The following can only work for power series, where we have a + minimal valuation of `0`:: + sage: L. = LazyPowerSeriesRing(QQ) sage: f = L.undefined(valuation=0) - sage: f.define(1 + t*~f + (t*f).revert()) + sage: f.define(1 - t*~(-f) - (-t*f).revert()) sage: f - - sage: a = var(["a%s" % n for n in range(10)]) - sage: L. = LazyLaurentSeriesRing(SR) - sage: f = sum(a[k] * t^k for k in range(10)) - sage: g = -f + 1 + t*~f + (t*f).revert() - sage: g[5].subs(a0=1, a1=2, a2=-4, a3=20, a4=-144, a5=1296) - 0 - sage: f.map_coefficients(lambda c: c.subs(a0=1, a1=2, a2=-4, a3=20, a4=-144, a5=1296)) - 1 + 2*t - 4*t^2 + 20*t^3 - 144*t^4 + 1296*t^5 + 1 + 2*t + 12*t^3 + 32*t^4 + 368*t^5 + 2192*t^6 + O(t^7) sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(s) From 22d8a70139dd7e80dfd801eae83e1b9dbfe5dd55 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 24 Sep 2022 22:42:11 +0900 Subject: [PATCH 192/350] Implement recursive algorithm for computing all planar partitions. --- src/sage/combinat/diagram_algebras.py | 146 +++++++++++++++++++------- 1 file changed, 106 insertions(+), 40 deletions(-) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index a59d6b0fb9b..d9144a80539 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -166,11 +166,13 @@ def planar_diagrams(k): EXAMPLES:: sage: import sage.combinat.diagram_algebras as da - sage: all_diagrams = da.partition_diagrams(2) - sage: [SetPartition(p) for p in all_diagrams if p not in da.planar_diagrams(2)] + sage: all_diagrams = [SetPartition(p) for p in da.partition_diagrams(2)] + sage: da2 = [SetPartition(p) for p in da.planar_diagrams(2)] + sage: [p for p in all_diagrams if p not in da2] [{{-2, 1}, {-1, 2}}] - sage: all_diagrams = da.partition_diagrams(5/2) - sage: [SetPartition(p) for p in all_diagrams if p not in da.planar_diagrams(5/2)] + sage: all_diagrams = [SetPartition(p) for p in da.partition_diagrams(5/2)] + sage: da5o2 = [SetPartition(p) for p in da.planar_diagrams(5/2)] + sage: [p for p in all_diagrams if p not in da5o2] [{{-3, -1, 3}, {-2, 1, 2}}, {{-3, -2, 1, 3}, {-1, 2}}, {{-3, -1, 1, 3}, {-2, 2}}, @@ -182,9 +184,73 @@ def planar_diagrams(k): {{-3, -1, 3}, {-2, 1}, {2}}, {{-3, -1, 3}, {-2, 2}, {1}}] """ - for i in partition_diagrams(k): - if is_planar(i): - yield i + if k in ZZ: + X = list(range(1,k+1)) + list(range(-k,0)) + yield from planar_partitions_rec(X) + elif k + ZZ(1)/ZZ(2) in ZZ: # Else k in 1/2 ZZ + k = ZZ(k + ZZ(1) / ZZ(2)) + X = list(range(1,k+1)) + list(range(-k+1,0)) + for Y in planar_partitions_rec(X): + Y = list(Y) + for part in Y: + if k in part: + part.append(-k) + break + yield Y + else: + raise ValueError("argument %s must be a half-integer" % k) + +def planar_partitions_rec(X): + r""" + Iterate over all planar set partitions of ``X`` by using a + recursive algorithm. + + ALGORITHM: + + To construct the set partition `\rho = \{\rho_1, \ldots, \rho_k\}` of + `[n]`, we remove the part of the set partition containing the last + element of ``X``, which, we consider to be `\rho_k = \{i_1, \ldots, i_m\}` + without loss of generality. The remaining parts come from the planar set + partitions of `\{1, \ldots, i_1-1\}, \{i_1+1, \ldots, i_2-1\}, \ldots, + \{i_m+1, \ldots, n\}`. + + EXAMPLES:: + + sage: import sage.combinat.diagram_algebras as da + sage: list(da.planar_partitions_rec([1,2,3])) + [([1, 2], [3]), ([1], [2], [3]), ([2], [1, 3]), ([1], [2, 3]), ([1, 2, 3],)] + """ + if not X: + return + if len(X) <= 2: + # Direct implementation of small cases + yield (X,) + if len(X) > 1: + yield ([X[0]], [X[1]]) + return + from sage.misc.misc import powerset + from itertools import product + for S in powerset(range(len(X)-1)): + if not S: + for Y in planar_partitions_rec(X[:-1]): + yield Y + ([X[-1]],) + continue + last = [X[i] for i in S] + last.append(X[-1]) + pt = [] + if S[0] != 0: + pt += [X[:S[0]]] + pt = [X[S[i]+1:S[i+1]] for i in range(len(S)-1) if S[i]+1 != S[i+1]] + if S[-1] + 1 != len(X) - 1: + pt += [X[S[-1]+1:-1]] + parts = [planar_partitions_rec(X[S[i]+1:S[i+1]]) for i in range(len(S)-1) + if S[i] + 1 != S[i+1]] + if S[0] != 0: + parts.append(planar_partitions_rec(X[:S[0]])) + if S[-1] + 1 != len(X) - 1: + parts.append(planar_partitions_rec(X[S[-1]+1:-1])) + for Y in product(*parts): + yield sum(Y, ()) + (last,) def ideal_diagrams(k): r""" @@ -606,20 +672,20 @@ class PlanarDiagram(AbstractPartitionDiagram): sage: PlanarDiagrams(2) Planar diagrams of order 2 sage: PlanarDiagrams(2).list() - [{{-2, -1, 1, 2}}, - {{-2, 1, 2}, {-1}}, - {{-2}, {-1, 1, 2}}, - {{-2, -1}, {1, 2}}, - {{-2}, {-1}, {1, 2}}, - {{-2, -1, 1}, {2}}, + [{{-2}, {-1}, {1, 2}}, + {{-2}, {-1}, {1}, {2}}, {{-2, 1}, {-1}, {2}}, - {{-2, 2}, {-1, 1}}, - {{-2, -1, 2}, {1}}, {{-2, 2}, {-1}, {1}}, + {{-2, 1, 2}, {-1}}, + {{-2, 2}, {-1, 1}}, {{-2}, {-1, 1}, {2}}, {{-2}, {-1, 2}, {1}}, + {{-2}, {-1, 1, 2}}, + {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}}, - {{-2}, {-1}, {1}, {2}}] + {{-2, -1, 1}, {2}}, + {{-2, -1, 2}, {1}}, + {{-2, -1, 1, 2}}] """ @staticmethod def __classcall_private__(cls, diag): @@ -1183,27 +1249,27 @@ def __iter__(self): [{{-2, -1}, {1, 2}}, {{-2, 2}, {-1, 1}}] sage: list(da.PlanarDiagrams(3/2)) - [{{-2, -1, 1, 2}}, - {{-2, 1, 2}, {-1}}, + [{{-2, 1, 2}, {-1}}, + {{-2, 2}, {-1}, {1}}, {{-2, 2}, {-1, 1}}, {{-2, -1, 2}, {1}}, - {{-2, 2}, {-1}, {1}}] + {{-2, -1, 1, 2}}] sage: list(da.PlanarDiagrams(2)) - [{{-2, -1, 1, 2}}, - {{-2, 1, 2}, {-1}}, - {{-2}, {-1, 1, 2}}, - {{-2, -1}, {1, 2}}, - {{-2}, {-1}, {1, 2}}, - {{-2, -1, 1}, {2}}, + [{{-2}, {-1}, {1, 2}}, + {{-2}, {-1}, {1}, {2}}, {{-2, 1}, {-1}, {2}}, - {{-2, 2}, {-1, 1}}, - {{-2, -1, 2}, {1}}, {{-2, 2}, {-1}, {1}}, + {{-2, 1, 2}, {-1}}, + {{-2, 2}, {-1, 1}}, {{-2}, {-1, 1}, {2}}, {{-2}, {-1, 2}, {1}}, + {{-2}, {-1, 1, 2}}, + {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}}, - {{-2}, {-1}, {1}, {2}}] + {{-2, -1, 1}, {2}}, + {{-2, -1, 2}, {1}}, + {{-2, -1, 1, 2}}] sage: list(da.IdealDiagrams(3/2)) [{{-2, -1, 1, 2}}, @@ -1654,11 +1720,11 @@ class PlanarDiagrams(AbstractPartitionDiagrams): sage: pld = da.PlanarDiagrams(3/2); pld Planar diagrams of order 3/2 sage: pld.list() - [{{-2, -1, 1, 2}}, - {{-2, 1, 2}, {-1}}, + [{{-2, 1, 2}, {-1}}, + {{-2, 2}, {-1}, {1}}, {{-2, 2}, {-1, 1}}, {{-2, -1, 2}, {1}}, - {{-2, 2}, {-1}, {1}}] + {{-2, -1, 1, 2}}] TESTS:: @@ -3967,20 +4033,20 @@ class PlanarAlgebra(SubPartitionAlgebra, UnitDiagramMixin): sage: Pl.basis().keys()([[-1, 1], [2, -2]]) {{-2, 2}, {-1, 1}} sage: Pl.basis().list() - [Pl{{-2, -1, 1, 2}}, - Pl{{-2, 1, 2}, {-1}}, - Pl{{-2}, {-1, 1, 2}}, - Pl{{-2, -1}, {1, 2}}, - Pl{{-2}, {-1}, {1, 2}}, - Pl{{-2, -1, 1}, {2}}, + [Pl{{-2}, {-1}, {1, 2}}, + Pl{{-2}, {-1}, {1}, {2}}, Pl{{-2, 1}, {-1}, {2}}, - Pl{{-2, 2}, {-1, 1}}, - Pl{{-2, -1, 2}, {1}}, Pl{{-2, 2}, {-1}, {1}}, + Pl{{-2, 1, 2}, {-1}}, + Pl{{-2, 2}, {-1, 1}}, Pl{{-2}, {-1, 1}, {2}}, Pl{{-2}, {-1, 2}, {1}}, + Pl{{-2}, {-1, 1, 2}}, + Pl{{-2, -1}, {1, 2}}, Pl{{-2, -1}, {1}, {2}}, - Pl{{-2}, {-1}, {1}, {2}}] + Pl{{-2, -1, 1}, {2}}, + Pl{{-2, -1, 2}, {1}}, + Pl{{-2, -1, 1, 2}}] sage: E = Pl([[1,2],[-1,-2]]) sage: E^2 == x*E True From 3d31d02c4eaab77599c3b89ff0541ee24c32547e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Sep 2022 16:35:10 -0700 Subject: [PATCH 193/350] build/pkgs/pynormaliz: Update to 2.17 --- build/pkgs/pynormaliz/checksums.ini | 6 +++--- build/pkgs/pynormaliz/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pynormaliz/checksums.ini b/build/pkgs/pynormaliz/checksums.ini index 9de8075164f..d9f614efaf9 100644 --- a/build/pkgs/pynormaliz/checksums.ini +++ b/build/pkgs/pynormaliz/checksums.ini @@ -1,5 +1,5 @@ tarball=PyNormaliz-VERSION.tar.gz -sha1=e383bde810a9337900d9e69f0683b6b387535508 -md5=e581e8ce0da928b1bf9dcc923165c940 -cksum=2627754172 +sha1=de8771b0339c4567665331df221c880bfe2b69a2 +md5=e8a571bdc3a8fcad16fdfabf9a6874d3 +cksum=2734845416 upstream_url=https://pypi.io/packages/source/p/pynormaliz/PyNormaliz-VERSION.tar.gz diff --git a/build/pkgs/pynormaliz/package-version.txt b/build/pkgs/pynormaliz/package-version.txt index 6d28a11dd0e..5c6fb54899b 100644 --- a/build/pkgs/pynormaliz/package-version.txt +++ b/build/pkgs/pynormaliz/package-version.txt @@ -1 +1 @@ -2.16 +2.17 From 0ff7b2c107ef1b4b5f5b904ad2a58007a5a182cb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Sep 2022 16:36:19 -0700 Subject: [PATCH 194/350] build/pkgs/normaliz: Update to 3.9.4 --- build/pkgs/normaliz/checksums.ini | 6 +++--- build/pkgs/normaliz/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/normaliz/checksums.ini b/build/pkgs/normaliz/checksums.ini index 4d50e8ef39a..f7d47180ceb 100644 --- a/build/pkgs/normaliz/checksums.ini +++ b/build/pkgs/normaliz/checksums.ini @@ -1,5 +1,5 @@ tarball=normaliz-VERSION.tar.gz -sha1=9436353151c2c2ad7703dcf66d713ecb6cc729ca -md5=e3c18ea44026c8c1dc3dd0093418d23e -cksum=2977572867 +sha1=6382fcb14b0e602f5bf7d5abd53b421d0e3a0a3d +md5=1c6bdd4da166da1718b08a3b9ee40949 +cksum=2272467212 upstream_url=https://github.com/Normaliz/Normaliz/releases/download/vVERSION/normaliz-VERSION.tar.gz diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt index 820476af941..e0d61b5b062 100644 --- a/build/pkgs/normaliz/package-version.txt +++ b/build/pkgs/normaliz/package-version.txt @@ -1 +1 @@ -3.9.3 +3.9.4 From 0f46ffca2c3b040ee41f9af6d17205ed3dedfd1a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Sep 2022 16:36:45 -0700 Subject: [PATCH 195/350] build/pkgs/antic: Update to 0.2.5 --- build/pkgs/antic/checksums.ini | 6 +++--- build/pkgs/antic/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/antic/checksums.ini b/build/pkgs/antic/checksums.ini index c09176c7177..fc8711ecd13 100644 --- a/build/pkgs/antic/checksums.ini +++ b/build/pkgs/antic/checksums.ini @@ -1,5 +1,5 @@ tarball=antic-VERSION.tar.gz -sha1=4a377a3679310e5530a4c7effc5247d523e243ee -md5=278efbf95645a43e81651605bc4e02dd -cksum=2671916781 +sha1=940d8ea2c3512b9d49ee3101cf043f777764bd8f +md5=4e896420dd6344b53b307871efb2cbb4 +cksum=1938565125 upstream_url=https://github.com/wbhart/antic/archive/refs/tags/vVERSION.tar.gz diff --git a/build/pkgs/antic/package-version.txt b/build/pkgs/antic/package-version.txt index abd410582de..3a4036fb450 100644 --- a/build/pkgs/antic/package-version.txt +++ b/build/pkgs/antic/package-version.txt @@ -1 +1 @@ -0.2.4 +0.2.5 From 92017f610472ca5351389003225695a690f8ea5b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Sep 2022 16:37:26 -0700 Subject: [PATCH 196/350] build/pkgs/e_antic: Update to 1.2.1 --- build/pkgs/e_antic/checksums.ini | 6 +++--- build/pkgs/e_antic/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/e_antic/checksums.ini b/build/pkgs/e_antic/checksums.ini index beeb8780bcd..82757976c54 100644 --- a/build/pkgs/e_antic/checksums.ini +++ b/build/pkgs/e_antic/checksums.ini @@ -1,5 +1,5 @@ tarball=e-antic-VERSION.tar.gz -sha1=c22e7b4306d1a53e4dba514cc53fb26654ee1cc6 -md5=1e56c1de2bb535b746601494978987fa -cksum=2460371789 +sha1=0fa6ba4a1f13e881f369f9185fe42c7f4bc10a18 +md5=5d77933d78dd08109b0a2c8403892eb6 +cksum=3304746077 upstream_url=https://github.com/flatsurf/e-antic/releases/download/VERSION/e-antic-VERSION.tar.gz diff --git a/build/pkgs/e_antic/package-version.txt b/build/pkgs/e_antic/package-version.txt index 26aaba0e866..6085e946503 100644 --- a/build/pkgs/e_antic/package-version.txt +++ b/build/pkgs/e_antic/package-version.txt @@ -1 +1 @@ -1.2.0 +1.2.1 From 9ed612aa5ea5204b603b2a4863eaaae84137fd7c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 25 Sep 2022 08:51:48 +0200 Subject: [PATCH 197/350] trac #34123: discard loops and set correct upper bound --- src/sage/graphs/edge_connectivity.pyx | 32 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 3462df9e14b..8638b203662 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -221,9 +221,6 @@ cdef class GabowEdgeConnectivity: self.F.clear() return - # Set upper bound on the edge connectivity - self.max_ec = min(min(G.out_degree_iterator()), min(G.in_degree_iterator())) - # # Initialize some data structures # @@ -236,6 +233,17 @@ cdef class GabowEdgeConnectivity: self.build_graph_data_structure() # From now on, vertices are numbered in [0..n-1] and edges in [0..m-1] + # Set upper bound on the edge connectivity + cdef int i, d + self.max_ec = INT_MAX + for i in range(self.n): + d = self.g_out[i].size() + if d < self.max_ec: + self.max_ec = d + d = self.g_in[i].size() + if d < self.max_ec: + self.max_ec = d + self.labels = self.mem.calloc(self.m, sizeof(int)) self.tree_flag = self.mem.calloc(self.max_ec, sizeof(bint)) self.forests = self.mem.calloc(self.n, sizeof(bint)) @@ -262,7 +270,6 @@ cdef class GabowEdgeConnectivity: self.UNUSED = INT_MAX self.FIRSTEDGE = INT_MAX - 1 - cdef int i for i in range(self.m): self.edge_state_1[i] = self.UNUSED # edge i is unused self.edge_state_2[i] = self.UNUSED @@ -303,11 +310,14 @@ cdef class GabowEdgeConnectivity: for x, u in enumerate(self.int_to_vertex): for v in self.G.neighbor_out_iterator(u): y = vertex_to_int[v] - self.g_out[x].push_back(e_id) - self.g_in[y].push_back(e_id) - self.tail[e_id] = x - self.head[e_id] = y - e_id += 1 + if x != y: + self.g_out[x].push_back(e_id) + self.g_in[y].push_back(e_id) + self.tail[e_id] = x + self.head[e_id] = y + e_id += 1 + # Loops have been removed, so we update the number of edges + self.m = e_id cdef bint compute_edge_connectivity(self) except -1: """ @@ -501,7 +511,7 @@ cdef class GabowEdgeConnectivity: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D, dfs=True, use_rec=False).edge_connectivity() + sage: GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=False).edge_connectivity() 4 """ cdef int u, v, e_id @@ -545,7 +555,7 @@ cdef class GabowEdgeConnectivity: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D, dfs=True, use_rec=True).edge_connectivity() + sage: GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() 4 """ # Mark vertex u as visited to avoid visiting it multiple times From 41e006e8340f69d8f88c1454059f1c662de34847 Mon Sep 17 00:00:00 2001 From: Enjeck Cleopatra Date: Sun, 25 Sep 2022 17:12:11 +0100 Subject: [PATCH 198/350] Add random graph example --- src/sage/graphs/edge_connectivity.pyx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 8638b203662..83f1111c2bf 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -51,7 +51,7 @@ cdef class GabowEdgeConnectivity: - ``D`` -- a :class:`~sage.graphs.digraph.DiGraph` - EXAMPLES: + EXAMPLES:: A random `d`-regular digraph is `d`-edge-connected:: @@ -68,6 +68,17 @@ cdef class GabowEdgeConnectivity: sage: D = DiGraph(digraphs.Complete(10)) sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() 9 + + :: + + sage: G = graphs.RandomBarabasiAlbert(100, 2) + sage: D = DiGraph(G) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 2 + sage: GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() + 2 + sage: GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() + 2 TESTS: From 0574b095d08c571f6c509bf0a6f4cd5e85f896f1 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 00:45:22 +0200 Subject: [PATCH 199/350] fix _div_ --- src/sage/rings/lazy_series.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 7d60b928711..4dee69517fe 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -964,7 +964,8 @@ def __bool__(self): return any(self[i] for i in range(v, v + prec)) def define(self, s): - r"""Define an equation by ``self = s``. + r""" + Define an equation by ``self = s``. INPUT: @@ -1138,6 +1139,13 @@ def define(self, s): sage: f 1 - x - x^2 - 2*x^3 - 5*x^4 - 14*x^5 - 42*x^6 + O(x^7) + Check that this also works using division:: + + sage: f = P.undefined() + sage: f.define(1 - x / f) + sage: f + 1 - x - x^2 - 2*x^3 - 5*x^4 - 14*x^5 - 42*x^6 + O(x^7) + sage: D = LazyDirichletSeriesRing(QQ, "s") sage: g = D([0, 1]) sage: f = D.undefined() @@ -3083,9 +3091,8 @@ def _div_(self, other): # if P._minimal_valuation == 0, then this is the true order # of coeff_stream, otherwise P._minimal_valuation is None - # right_inverse = Stream_cauchy_invert(right, - # approximate_order=P._minimal_valuation) - right_inverse = Stream_cauchy_invert(right) + right_inverse = Stream_cauchy_invert(right, + approximate_order_upper_bound=P._minimal_valuation) return P.element_class(P, Stream_cauchy_mul(left, right_inverse)) From 88e71906ccada7850f9f7566fb0ae7bbc2fea5b0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 14:21:36 -0700 Subject: [PATCH 200/350] ConvexRationalPolyhedralCone: Make __and__ an alias for intersection --- src/sage/geometry/cone.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index e3d84cac696..3256623ef9c 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -3017,6 +3017,13 @@ def intersection(self, other): N( 2, 5) in 2-d lattice N + The intersection can also be expressed using the operator ``&``:: + + sage: (cone1 & cone2).rays() + N(-1, 3), + N( 2, 5) + in 2-d lattice N + It is OK to intersect cones living in sublattices of the same ambient lattice:: @@ -3058,6 +3065,8 @@ def intersection(self, other): p.add_constraints(other._PPL_cone().constraints()) return _Cone_from_PPL(p, self.lattice().intersection(other.lattice())) + __and__ = intersection + def is_equivalent(self, other): r""" Check if ``self`` is "mathematically" the same as ``other``. From 40d4965ddf76ed74f70ce88543e2a1d52f01ff82 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 16:05:30 -0700 Subject: [PATCH 201/350] RationalPolyhedralCone.intersection: Delegate to Polyhedron if other is not a RationalPolyhedralCone --- src/sage/geometry/cone.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 3256623ef9c..da93aa5f2dc 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -3049,7 +3049,16 @@ def intersection(self, other): N(3, 1), N(0, 1) in 2-d lattice N + + An intersection with a polyhedron returns a polyhedron:: + + sage: cone = Cone([(1,0), (-1,0), (0,1)]) + sage: p = polytopes.hypercube(2) + sage: cone & p + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices """ + if not isinstance(other, ConvexRationalPolyhedralCone): + return self.polyhedron().intersection(other) if self._ambient is other._ambient: # Cones of the same ambient cone or fan intersect nicely/quickly. # Can we maybe even return an element of the cone lattice?.. From fccf3071f427125c80fe42ea5090d82b024e070b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 16:11:11 -0700 Subject: [PATCH 202/350] PolyhedronFace.as_polyhedron, {ConvexRationalPolyhedralCone,LatticePolytopeClass,Hyperplane}.polyhedron: Accept and pass on kwds --- src/sage/geometry/cone.py | 4 ++-- src/sage/geometry/hyperplane_arrangement/hyperplane.py | 8 +++++--- src/sage/geometry/lattice_polytope.py | 4 ++-- src/sage/geometry/polyhedron/face.py | 9 +++++++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index da93aa5f2dc..70a273c3d79 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -3513,7 +3513,7 @@ def plot(self, **options): result += tp.plot_walls(walls) return result - def polyhedron(self): + def polyhedron(self, **kwds): r""" Return the polyhedron associated to ``self``. @@ -3541,7 +3541,7 @@ def polyhedron(self): A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex """ - return Polyhedron(rays=self.rays(), vertices=[self.lattice()(0)]) + return Polyhedron(rays=self.rays(), vertices=[self.lattice()(0)], **kwds) def an_affine_basis(self): r""" diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index 491c88d176d..c431291a3a6 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -282,7 +282,7 @@ def __contains__(self, q): return self.A() * q + self._const == 0 @cached_method - def polyhedron(self): + def polyhedron(self, **kwds): """ Return the hyperplane as a polyhedron. @@ -304,8 +304,10 @@ def polyhedron(self): A vertex at (0, 0, 4/3)) """ from sage.geometry.polyhedron.constructor import Polyhedron - R = self.parent().base_ring() - return Polyhedron(eqns=[self.coefficients()], base_ring=R) + R = kwds.pop('base_ring', None) + if R is None: + R = self.parent().base_ring() + return Polyhedron(eqns=[self.coefficients()], base_ring=R, **kwds) @cached_method def linear_part(self): diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index ff85c1724d8..083f817693e 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3649,7 +3649,7 @@ def plot3d(self, pplot += text3d(i+self.nvertices(), bc+index_shift*(p-bc), rgbcolor=pindex_color) return pplot - def polyhedron(self): + def polyhedron(self, **kwds): r""" Return the Polyhedron object determined by this polytope's vertices. @@ -3660,7 +3660,7 @@ def polyhedron(self): A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices """ from sage.geometry.polyhedron.constructor import Polyhedron - return Polyhedron(vertices=[list(v) for v in self._vertices]) + return Polyhedron(vertices=[list(v) for v in self._vertices], **kwds) def show3d(self): """ diff --git a/src/sage/geometry/polyhedron/face.py b/src/sage/geometry/polyhedron/face.py index d9dd5a6c4d6..0d60961c8b9 100644 --- a/src/sage/geometry/polyhedron/face.py +++ b/src/sage/geometry/polyhedron/face.py @@ -750,7 +750,7 @@ def is_compact(self): for V in self.ambient_Vrepresentation()) @cached_method - def as_polyhedron(self): + def as_polyhedron(self, **kwds): """ Return the face as an independent polyhedron. @@ -774,7 +774,12 @@ def as_polyhedron(self): P = self._polyhedron parent = P.parent() Vrep = (self.vertices(), self.rays(), self.lines()) - return P.__class__(parent, Vrep, None) + result = P.__class__(parent, Vrep, None) + if any(kwds.get(kwd) is not None + for kwd in ('base_ring', 'backend')): + from .constructor import Polyhedron + return Polyhedron(result, **kwds) + return result def _some_elements_(self): r""" From 3624fcef764facd605ccf2c7e462cebe51e2424f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 16:12:22 -0700 Subject: [PATCH 203/350] Polyhedron: If first arg is an object with an 'as_polyhedron' or 'polyhedron' method, call it --- src/sage/geometry/polyhedron/constructor.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index dbe00570c85..ba32d72a053 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -573,6 +573,23 @@ def Polyhedron(vertices=None, rays=None, lines=None, :mod:`Library of polytopes ` """ + # Special handling for first argument, for coercion-like uses + constructor = None + try: + # PolyhedronFace.as_polyhedron (it also has a "polyhedron" method with a different purpose) + constructor = vertices.as_polyhedron + except AttributeError: + try: + # ConvexRationalPolyhedralCone, LatticePolytopeClass, MixedIntegerLinearProgram, Hyperplane + constructor = vertices.polyhedron + except AttributeError: + pass + if constructor: + if not all(x is None for x in (rays, lines, ieqs, eqns, ambient_dim)): + raise ValueError('if a polyhedron is given, cannot provide H- and V-representations objects') + return constructor(base_ring=base_ring, minimize=minimize, + verbose=verbose, backend=backend, mutable=False) + got_Vrep = not ((vertices is None) and (rays is None) and (lines is None)) got_Hrep = not ((ieqs is None) and (eqns is None)) From 8b3cd6aea744d569ed7041df2418e2c75e91c6ef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 16:35:31 -0700 Subject: [PATCH 204/350] Polyhedron: Add examples for conversions --- src/sage/geometry/polyhedron/constructor.py | 71 ++++++++++++++++----- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index ba32d72a053..0b555f9f89b 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -313,11 +313,16 @@ def Polyhedron(vertices=None, rays=None, lines=None, INPUT: - - ``vertices`` -- list of points. Each point can be specified as + - ``vertices`` -- iterable of points. Each point can be specified as any iterable container of ``base_ring`` elements. If ``rays`` or ``lines`` are specified but no ``vertices``, the origin is taken to be the single vertex. + Instead of vertices, the first argument can also be an object + that can be converted to a :func:`Polyhedron` via an :meth:`as_polyhedron` + or :meth:`polyhedron` method. In this case, the following 5 arguments + cannot be provided. + - ``rays`` -- list of rays. Each ray can be specified as any iterable container of ``base_ring`` elements. @@ -332,6 +337,10 @@ def Polyhedron(vertices=None, rays=None, lines=None, any iterable container of ``base_ring`` elements. An entry equal to ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`. + - ``ambient_dim`` -- integer. The ambient space dimension. Usually + can be figured out automatically from the H/Vrepresentation + dimensions. + - ``base_ring`` -- a sub-field of the reals implemented in Sage. The field over which the polyhedron will be defined. For ``QQ`` and algebraic extensions, exact arithmetic will be @@ -339,10 +348,6 @@ def Polyhedron(vertices=None, rays=None, lines=None, point arithmetic is faster but might give the wrong result for degenerate input. - - ``ambient_dim`` -- integer. The ambient space dimension. Usually - can be figured out automatically from the H/Vrepresentation - dimensions. - - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are * ``'cdd'``: use cdd @@ -465,17 +470,38 @@ def Polyhedron(vertices=None, rays=None, lines=None, ... ValueError: invalid base ring - Create a mutable polyhedron:: - - sage: P = Polyhedron(vertices=[[0, 1], [1, 0]], mutable=True) - sage: P.is_mutable() - True - sage: hasattr(P, "_Vrepresentation") - False - sage: P.Vrepresentation() - (A vertex at (0, 1), A vertex at (1, 0)) - sage: hasattr(P, "_Vrepresentation") - True + Converting from other objects to a polyhedron:: + + sage: quadrant = Cone([(1,0), (0,1)]) + sage: Polyhedron(quadrant) + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 rays + sage: Polyhedron(quadrant, base_ring=QQ) + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays + + sage: o = lattice_polytope.cross_polytope(2) + sage: Polyhedron(o) + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices + sage: Polyhedron(o, base_ring=QQ) + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices + + sage: p = MixedIntegerLinearProgram(solver='PPL') + sage: x, y = p['x'], p['y'] + sage: p.add_constraint(x <= 1) + sage: p.add_constraint(x >= -1) + sage: p.add_constraint(y <= 1) + sage: p.add_constraint(y >= -1) + sage: Polyhedron(o) + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices + sage: Polyhedron(o, base_ring=QQ) + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices + + sage: H. = HyperplaneArrangements(QQ) + sage: h = x + y - 1; h + Hyperplane x + y - 1 + sage: Polyhedron(h, base_ring=ZZ) + A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 1 line + sage: Polyhedron(h) + A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line .. NOTE:: @@ -486,7 +512,6 @@ def Polyhedron(vertices=None, rays=None, lines=None, input data - the results can depend upon the tolerance setting of cdd. - TESTS: Check that giving ``float`` input gets converted to ``RDF`` (see :trac:`22605`):: @@ -569,6 +594,18 @@ def Polyhedron(vertices=None, rays=None, lines=None, sage: Polyhedron(ambient_dim=2, vertices=[], rays=[], lines=[], base_ring=QQ) The empty polyhedron in QQ^2 + Create a mutable polyhedron:: + + sage: P = Polyhedron(vertices=[[0, 1], [1, 0]], mutable=True) + sage: P.is_mutable() + True + sage: hasattr(P, "_Vrepresentation") + False + sage: P.Vrepresentation() + (A vertex at (0, 1), A vertex at (1, 0)) + sage: hasattr(P, "_Vrepresentation") + True + .. SEEALSO:: :mod:`Library of polytopes ` From 0f837244566368f868594b1177137f675b3209e9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 17:01:36 -0700 Subject: [PATCH 205/350] Polyhedron: Allow converting from a given polyhedron --- src/sage/geometry/polyhedron/constructor.py | 31 ++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index 0b555f9f89b..eac816facb3 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -291,6 +291,8 @@ # https://www.gnu.org/licenses/ ######################################################################## +import sage.geometry.abc + from sage.rings.integer_ring import ZZ from sage.rings.real_double import RDF from sage.rings.real_mpfr import RR @@ -470,6 +472,13 @@ def Polyhedron(vertices=None, rays=None, lines=None, ... ValueError: invalid base ring + Converting from a given polyhedron:: + + sage: cb = polytopes.cube(); cb + A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices + sage: Polyhedron(cb, base_ring=QQ) + A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices + Converting from other objects to a polyhedron:: sage: quadrant = Cone([(1,0), (0,1)]) @@ -612,20 +621,34 @@ def Polyhedron(vertices=None, rays=None, lines=None, """ # Special handling for first argument, for coercion-like uses constructor = None + first_arg = vertices + if isinstance(first_arg, sage.geometry.abc.Polyhedron): + constructor = first_arg.change_ring try: # PolyhedronFace.as_polyhedron (it also has a "polyhedron" method with a different purpose) - constructor = vertices.as_polyhedron + constructor = first_arg.as_polyhedron except AttributeError: try: # ConvexRationalPolyhedralCone, LatticePolytopeClass, MixedIntegerLinearProgram, Hyperplane - constructor = vertices.polyhedron + constructor = first_arg.polyhedron except AttributeError: pass if constructor: if not all(x is None for x in (rays, lines, ieqs, eqns, ambient_dim)): raise ValueError('if a polyhedron is given, cannot provide H- and V-representations objects') - return constructor(base_ring=base_ring, minimize=minimize, - verbose=verbose, backend=backend, mutable=False) + # Only pass non-default arguments + kwds = {} + if base_ring is not None: + kwds['base_ring'] = base_ring + if verbose is not False: + kwds['verbose'] = verbose + if backend is not None: + kwds['backend'] = backend + if minimize is not True: + kwds['minimize'] = minimize + if mutable is not False: + kwds['mutable'] = mutable + return constructor(**kwds) got_Vrep = not ((vertices is None) and (rays is None) and (lines is None)) got_Hrep = not ((ieqs is None) and (eqns is None)) From 576076a50f18b60ef2d9a1626efa5ce3cde7a5bc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 Aug 2022 21:42:47 -0700 Subject: [PATCH 206/350] src/sage/geometry/cone.py: Fix doctest --- src/sage/geometry/cone.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 70a273c3d79..3d9cb0766fc 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -3055,7 +3055,9 @@ def intersection(self, other): sage: cone = Cone([(1,0), (-1,0), (0,1)]) sage: p = polytopes.hypercube(2) sage: cone & p - A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices + sage: sorted(_.vertices_list()) + [[-1, 0], [-1, 1], [1, 0], [1, 1]] """ if not isinstance(other, ConvexRationalPolyhedralCone): return self.polyhedron().intersection(other) From 4517f15f1bab54f08f150ef716be872efdd2a9fb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 25 Sep 2022 18:16:48 -0700 Subject: [PATCH 207/350] Revert "build/pkgs/pynormaliz/install-requires.txt: Fix to 2.14" This reverts commit 5e3f78502102d1659d1cc5379d2c60f75c19475d. --- build/pkgs/pynormaliz/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pynormaliz/install-requires.txt b/build/pkgs/pynormaliz/install-requires.txt index ecc1ec0712b..b1e222ae76c 100644 --- a/build/pkgs/pynormaliz/install-requires.txt +++ b/build/pkgs/pynormaliz/install-requires.txt @@ -1 +1 @@ -pynormaliz ==2.14 +pynormaliz ==2.12 From b814d71dc4d32a27379a7cd754fb026daa40d46d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 25 Sep 2022 18:35:09 -0700 Subject: [PATCH 208/350] build/pkgs/antic/distros: New --- build/pkgs/antic/distros/arch.txt | 1 + build/pkgs/antic/distros/conda.txt | 1 + build/pkgs/antic/distros/debian.txt | 1 + build/pkgs/antic/distros/fedora.txt | 1 + build/pkgs/antic/distros/freebsd.txt | 1 + build/pkgs/antic/distros/opensuse.txt | 1 + build/pkgs/antic/distros/repology.txt | 1 + 7 files changed, 7 insertions(+) create mode 100644 build/pkgs/antic/distros/arch.txt create mode 100644 build/pkgs/antic/distros/conda.txt create mode 100644 build/pkgs/antic/distros/debian.txt create mode 100644 build/pkgs/antic/distros/fedora.txt create mode 100644 build/pkgs/antic/distros/freebsd.txt create mode 100644 build/pkgs/antic/distros/opensuse.txt create mode 100644 build/pkgs/antic/distros/repology.txt diff --git a/build/pkgs/antic/distros/arch.txt b/build/pkgs/antic/distros/arch.txt new file mode 100644 index 00000000000..83c7cab14e4 --- /dev/null +++ b/build/pkgs/antic/distros/arch.txt @@ -0,0 +1 @@ +antic diff --git a/build/pkgs/antic/distros/conda.txt b/build/pkgs/antic/distros/conda.txt new file mode 100644 index 00000000000..83c7cab14e4 --- /dev/null +++ b/build/pkgs/antic/distros/conda.txt @@ -0,0 +1 @@ +antic diff --git a/build/pkgs/antic/distros/debian.txt b/build/pkgs/antic/distros/debian.txt new file mode 100644 index 00000000000..8fdcd3e5721 --- /dev/null +++ b/build/pkgs/antic/distros/debian.txt @@ -0,0 +1 @@ +libantic-dev diff --git a/build/pkgs/antic/distros/fedora.txt b/build/pkgs/antic/distros/fedora.txt new file mode 100644 index 00000000000..1b16da9f64b --- /dev/null +++ b/build/pkgs/antic/distros/fedora.txt @@ -0,0 +1 @@ +antic-devel diff --git a/build/pkgs/antic/distros/freebsd.txt b/build/pkgs/antic/distros/freebsd.txt new file mode 100644 index 00000000000..116ff3a26f3 --- /dev/null +++ b/build/pkgs/antic/distros/freebsd.txt @@ -0,0 +1 @@ +math/antic diff --git a/build/pkgs/antic/distros/opensuse.txt b/build/pkgs/antic/distros/opensuse.txt new file mode 100644 index 00000000000..1b16da9f64b --- /dev/null +++ b/build/pkgs/antic/distros/opensuse.txt @@ -0,0 +1 @@ +antic-devel diff --git a/build/pkgs/antic/distros/repology.txt b/build/pkgs/antic/distros/repology.txt new file mode 100644 index 00000000000..83c7cab14e4 --- /dev/null +++ b/build/pkgs/antic/distros/repology.txt @@ -0,0 +1 @@ +antic From c9f2cfa38d78c3b438099af778db1bc1a8346f47 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 25 Sep 2022 18:40:00 -0700 Subject: [PATCH 209/350] build/pkgs/e_antic/distros: Add more --- build/pkgs/e_antic/distros/arch.txt | 1 + build/pkgs/e_antic/distros/debian.txt | 1 + build/pkgs/e_antic/distros/fedora.txt | 1 + build/pkgs/e_antic/distros/freebsd.txt | 1 + build/pkgs/e_antic/distros/opensuse.txt | 1 + 5 files changed, 5 insertions(+) create mode 100644 build/pkgs/e_antic/distros/arch.txt create mode 100644 build/pkgs/e_antic/distros/debian.txt create mode 100644 build/pkgs/e_antic/distros/fedora.txt create mode 100644 build/pkgs/e_antic/distros/freebsd.txt create mode 100644 build/pkgs/e_antic/distros/opensuse.txt diff --git a/build/pkgs/e_antic/distros/arch.txt b/build/pkgs/e_antic/distros/arch.txt new file mode 100644 index 00000000000..31c9da4b82f --- /dev/null +++ b/build/pkgs/e_antic/distros/arch.txt @@ -0,0 +1 @@ +e-antic diff --git a/build/pkgs/e_antic/distros/debian.txt b/build/pkgs/e_antic/distros/debian.txt new file mode 100644 index 00000000000..43fbfebd54c --- /dev/null +++ b/build/pkgs/e_antic/distros/debian.txt @@ -0,0 +1 @@ +libeantic-dev diff --git a/build/pkgs/e_antic/distros/fedora.txt b/build/pkgs/e_antic/distros/fedora.txt new file mode 100644 index 00000000000..79e976c0953 --- /dev/null +++ b/build/pkgs/e_antic/distros/fedora.txt @@ -0,0 +1 @@ +e-antic-devel diff --git a/build/pkgs/e_antic/distros/freebsd.txt b/build/pkgs/e_antic/distros/freebsd.txt new file mode 100644 index 00000000000..647f5d36fac --- /dev/null +++ b/build/pkgs/e_antic/distros/freebsd.txt @@ -0,0 +1 @@ +math/e-antic diff --git a/build/pkgs/e_antic/distros/opensuse.txt b/build/pkgs/e_antic/distros/opensuse.txt new file mode 100644 index 00000000000..79e976c0953 --- /dev/null +++ b/build/pkgs/e_antic/distros/opensuse.txt @@ -0,0 +1 @@ +e-antic-devel From c6778a7385808839aee5a2fbe06d2eaeb2ae5847 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 25 Sep 2022 18:43:08 -0700 Subject: [PATCH 210/350] build/pkgs/normaliz/distros: Add more --- build/pkgs/normaliz/distros/arch.txt | 1 + build/pkgs/normaliz/distros/debian.txt | 1 + build/pkgs/normaliz/distros/fedora.txt | 1 + build/pkgs/normaliz/distros/gentoo.txt | 1 + 4 files changed, 4 insertions(+) create mode 100644 build/pkgs/normaliz/distros/arch.txt create mode 100644 build/pkgs/normaliz/distros/debian.txt create mode 100644 build/pkgs/normaliz/distros/fedora.txt create mode 100644 build/pkgs/normaliz/distros/gentoo.txt diff --git a/build/pkgs/normaliz/distros/arch.txt b/build/pkgs/normaliz/distros/arch.txt new file mode 100644 index 00000000000..d0991c684ae --- /dev/null +++ b/build/pkgs/normaliz/distros/arch.txt @@ -0,0 +1 @@ +normaliz diff --git a/build/pkgs/normaliz/distros/debian.txt b/build/pkgs/normaliz/distros/debian.txt new file mode 100644 index 00000000000..a3144cefbbb --- /dev/null +++ b/build/pkgs/normaliz/distros/debian.txt @@ -0,0 +1 @@ +libnormaliz-dev diff --git a/build/pkgs/normaliz/distros/fedora.txt b/build/pkgs/normaliz/distros/fedora.txt new file mode 100644 index 00000000000..b48a8dfa158 --- /dev/null +++ b/build/pkgs/normaliz/distros/fedora.txt @@ -0,0 +1 @@ +libnormaliz-devel diff --git a/build/pkgs/normaliz/distros/gentoo.txt b/build/pkgs/normaliz/distros/gentoo.txt new file mode 100644 index 00000000000..4c0fae119ad --- /dev/null +++ b/build/pkgs/normaliz/distros/gentoo.txt @@ -0,0 +1 @@ +sci-mathematics/normaliz From 3789d84c75be0d60d7b6aba59c486fa624accdee Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 11:13:32 +0200 Subject: [PATCH 211/350] slightly simplify logic, explain why f.define(1 - x / f) cannot work --- src/sage/data_structures/stream.py | 15 +++++++------- src/sage/rings/lazy_series.py | 33 ++++++++++++++++-------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index edc83520cdf..2eec9c7a9d6 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -2405,8 +2405,8 @@ class Stream_cauchy_invert(Stream_unary): - ``series`` -- a :class:`Stream` - - ``approximate_order_upper_bound`` -- ``None``, or an upper bound on the - order of ``series`` + - ``approximate_order`` -- ``None``, or a lower bound on the + order of ``Stream_cauchy_invert(series)`` EXAMPLES:: @@ -2415,8 +2415,9 @@ class Stream_cauchy_invert(Stream_unary): sage: g = Stream_cauchy_invert(f) sage: [g[i] for i in range(10)] [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0] + """ - def __init__(self, series, approximate_order_upper_bound=None): + def __init__(self, series, approximate_order=None): """ Initialize ``self``. @@ -2426,16 +2427,14 @@ def __init__(self, series, approximate_order_upper_bound=None): sage: f = Stream_exact([1, -1], False) sage: g = Stream_cauchy_invert(f) """ - self._approximate_order_upper_bound = approximate_order_upper_bound super().__init__(series, series._is_sparse) + if approximate_order is not None: + self._approximate_order = approximate_order self._zero = ZZ.zero() @lazy_attribute def _approximate_order(self): - if self._approximate_order_upper_bound is None: - return -self._series.order() - # this is not the true order - return -self._approximate_order_upper_bound + return -self._series.order() @lazy_attribute def _ainv(self): diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 4dee69517fe..69f92ae7e64 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1139,13 +1139,6 @@ def define(self, s): sage: f 1 - x - x^2 - 2*x^3 - 5*x^4 - 14*x^5 - 42*x^6 + O(x^7) - Check that this also works using division:: - - sage: f = P.undefined() - sage: f.define(1 - x / f) - sage: f - 1 - x - x^2 - 2*x^3 - 5*x^4 - 14*x^5 - 42*x^6 + O(x^7) - sage: D = LazyDirichletSeriesRing(QQ, "s") sage: g = D([0, 1]) sage: f = D.undefined() @@ -1156,6 +1149,17 @@ def define(self, s): sage: oeis(f[:30]) # optional, internet 0: A122698: a(1)=a(2)=1 then a(n) = Sum_{d|n, 1 = LazyPowerSeriesRing(QQ) @@ -2901,14 +2905,13 @@ def __invert__(self): if isinstance(coeff_stream, Stream_cauchy_invert): return P.element_class(P, coeff_stream._series) - # if P._minimal_valuation == 0, then this is the true order - # of coeff_stream, otherwise P._minimal_valuation is None coeff_stream_inverse = Stream_cauchy_invert(coeff_stream, - approximate_order_upper_bound=P._minimal_valuation) + approximate_order=P._minimal_valuation) return P.element_class(P, coeff_stream_inverse) def _div_(self, other): - r"""Return ``self`` divided by ``other``. + r""" + Return ``self`` divided by ``other``. INPUT: @@ -3089,10 +3092,10 @@ def _div_(self, other): degree=v, constant=constant)) - # if P._minimal_valuation == 0, then this is the true order - # of coeff_stream, otherwise P._minimal_valuation is None - right_inverse = Stream_cauchy_invert(right, - approximate_order_upper_bound=P._minimal_valuation) + # we cannot pass the approximate order here, even when + # P._minimal_valuation is zero, because we allow division by + # series of positive valuation + right_inverse = Stream_cauchy_invert(right) return P.element_class(P, Stream_cauchy_mul(left, right_inverse)) From 3ced5ec8328449e51cd48342557dd021d2db73c8 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 13:23:56 +0200 Subject: [PATCH 212/350] attempt a better error message --- src/sage/data_structures/stream.py | 5 ++++- src/sage/rings/lazy_series.py | 12 +++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 2eec9c7a9d6..1d6cb5227c5 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -2434,7 +2434,10 @@ def __init__(self, series, approximate_order=None): @lazy_attribute def _approximate_order(self): - return -self._series.order() + try: + return -self._series.order() + except RecursionError: + raise ValueError("inverse does not exist") @lazy_attribute def _ainv(self): diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 69f92ae7e64..4bdae783d70 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -1158,7 +1158,7 @@ def define(self, s): sage: f[0] Traceback (most recent call last): ... - RecursionError: maximum recursion depth exceeded ... + ValueError: inverse does not exist Check that reversion is lazy enough:: @@ -3705,17 +3705,19 @@ def revert(self): sage: s = L(lambda n: 2 if n == 0 else 3 if n == 1 else 0, valuation=0); s 2 + 3*z + O(z^7) - sage: s.revert() + sage: f = s.revert() + sage: f[1] Traceback (most recent call last): ... - ValueError: cannot determine whether the compositional inverse exists + ValueError: inverse does not exist sage: s = L(lambda n: 1, valuation=-2); s z^-2 + z^-1 + 1 + z + z^2 + z^3 + z^4 + O(z^5) - sage: s.revert() + sage: f = s.revert() + sage: f[1] Traceback (most recent call last): ... - ValueError: compositional inverse does not exist + ValueError: inverse does not exist sage: R. = QQ[] sage: L. = LazyLaurentSeriesRing(R.fraction_field()) From 52ac7af1b63854d9905bbf81e73acbbd854f51d6 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 15:02:44 +0200 Subject: [PATCH 213/350] pyflakes observations --- src/sage/rings/lazy_series.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 4bdae783d70..0b1eba2a6a7 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -217,7 +217,6 @@ from sage.arith.functions import lcm from sage.arith.misc import divisors, moebius from sage.combinat.partition import Partition, Partitions -from sage.misc.misc_c import prod from sage.misc.derivative import derivative_parse from sage.categories.integral_domains import IntegralDomains from sage.rings.infinity import infinity @@ -3815,26 +3814,6 @@ def revert(self): if coeff_stream.order() != 1: raise ValueError("compositional inverse does not exist") - # TODO: coefficients should not be checked here, it prevents - # us from using self.define in some cases! - # if any(coeff_stream[i] for i in range(coeff_stream._approximate_order, -1)): - # raise ValueError("compositional inverse does not exist") - # - # if coeff_stream[-1]: - # if coeff_stream[0] or coeff_stream[1]: - # raise ValueError("compositional inverse does not exist") - # raise ValueError("cannot determine whether the compositional inverse exists") - - # if coeff_stream._approximate_order > 1: - # raise ValueError("compositional inverse does not exist") - - # if not coeff_stream[1]: - # raise ValueError("compositional inverse does not exist") - - # if coeff_stream[0]: - # raise ValueError("cannot determine whether the compositional inverse exists") - - z = P.gen() g = P.undefined(valuation=1) # the following is mathematically equivalent to # z / ((self / z)(g)) @@ -4636,13 +4615,9 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! - # if not coeff_stream[1]: - # raise ValueError("compositional inverse does not exist") - if coeff_stream[0]: raise ValueError("cannot determine whether the compositional inverse exists") - z = P.gen() g = P.undefined(valuation=1) # the following is mathematically equivalent to # z / ((self / z)(g)) @@ -5469,9 +5444,6 @@ def revert(self): # TODO: coefficients should not be checked here, it prevents # us from using self.define in some cases! - # if not coeff_stream[1]: - # raise ValueError("compositional inverse does not exist") - if coeff_stream[0]: raise ValueError("cannot determine whether the compositional inverse exists") From 855d2bf04aaebfc1696e34664b48521bffd6a79f Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 18:58:50 +0200 Subject: [PATCH 214/350] remove unused variable --- src/sage/rings/lazy_series_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index c78c723f968..c0e0d536562 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -986,7 +986,7 @@ def _test_revert(self, **options): raise AssertionError("compositional inverse of %s should exist: %s" % (x, error)) try: vy = y.valuation() - m = y[vy] + _ = y[vy] except NotImplementedError: pass except (ValueError, TypeError): From 75c275cf989059c02bf5bd11ad7ed0ba76b3ca5f Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 26 Sep 2022 19:31:43 +0200 Subject: [PATCH 215/350] add documentation and doctests for _approximate_order --- src/sage/data_structures/stream.py | 200 ++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 2 deletions(-) diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 1d6cb5227c5..d8d780dbca4 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -147,6 +147,16 @@ def __init__(self, sparse, true_order): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_exact + sage: f = Stream_exact([0,3], True) + sage: f._approximate_order + 1 + """ raise NotImplementedError def __ne__(self, other): @@ -207,7 +217,7 @@ class Stream_inexact(Stream): def __init__(self, is_sparse, true_order): """ Initialize the stream class for a stream whose - coefficients are not necessarily eventally constant. + coefficients are not necessarily eventually constant. TESTS:: @@ -227,9 +237,23 @@ def __init__(self, is_sparse, true_order): @lazy_attribute def _offset(self): + """ + Return the offset of a stream with a dense cache. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function + sage: f = Stream_function(lambda n: n, False, -3) + sage: f._offset + -3 + sage: [f[i] for i in range(-3, 5)] + [-3, -2, -1, 0, 1, 2, 3, 4] + sage: f._cache + [-3, -2, -1, 0, 1, 2, 3, 4] + """ # self[n] = self._cache[n-self._offset] if self._is_sparse: - raise ValueError("_offset is only for sparse streams") + raise ValueError("_offset is only for dense streams") return self._approximate_order def is_nonzero(self): @@ -1396,6 +1420,16 @@ def __init__(self, left, right): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_exact + sage: h = Stream_exact([0,3], True) + sage: h._approximate_order + 1 + """ # this is not the true order, because we may have cancellation return min(self._left._approximate_order, self._right._approximate_order) @@ -1459,6 +1493,20 @@ def __init__(self, left, right): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_exact, Stream_function, Stream_add + sage: f = Stream_exact([0,3], True) + sage: g = Stream_function(lambda n: -3*n, True, 1) + sage: h = Stream_add(f, g) + sage: h._approximate_order + 1 + sage: [h[i] for i in range(5)] + [0, 0, -6, -9, -12] + """ # this is not the true order, because we may have cancellation return min(self._left._approximate_order, self._right._approximate_order) @@ -1526,6 +1574,20 @@ def __init__(self, left, right): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_exact, Stream_function, Stream_cauchy_mul + sage: f = Stream_exact([0, Zmod(6)(2)], True) + sage: g = Stream_function(lambda n: Zmod(6)(3*n), True, 1) + sage: h = Stream_cauchy_mul(f, g) + sage: h._approximate_order + 2 + sage: [h[i] for i in range(5)] + [0, 0, 0, 0, 0] + """ # this is not the true order, unless we have an integral domain return self._left._approximate_order + self._right._approximate_order @@ -1628,6 +1690,20 @@ def __init__(self, left, right): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_exact, Stream_function, Stream_dirichlet_convolve + sage: f = Stream_exact([0, 2], True) + sage: g = Stream_function(lambda n: 3*n, True, 1) + sage: h = Stream_dirichlet_convolve(f, g) + sage: h._approximate_order + 1 + sage: [h[i] for i in range(5)] + [0, 6, 12, 18, 24] + """ # this is not the true order, unless we have an integral domain if (self._left._approximate_order <= 0 or self._right._approximate_order <= 0): @@ -1702,6 +1778,19 @@ def __init__(self, series): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_dirichlet_invert + sage: f = Stream_function(lambda n: n, True, 1) + sage: h = Stream_dirichlet_invert(f) + sage: h._approximate_order + 1 + sage: [h[i] for i in range(5)] + [0, -2, -8, -12, -48] + """ # this is the true order, but we want to check first if self._series._approximate_order > 1: raise ZeroDivisionError("the Dirichlet inverse only exists if the " @@ -1802,6 +1891,19 @@ def __init__(self, f, g): @lazy_attribute def _approximate_order(self): """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_cauchy_compose + sage: f = Stream_function(lambda n: n, True, 1) + sage: g = Stream_function(lambda n: n^2, True, 1) + sage: h = Stream_cauchy_compose(f, g) + sage: h._approximate_order + 1 + sage: [h[i] for i in range(5)] + [0, 1, 6, 28, 124] + .. TODO:: check similarities with :class:`Stream_plethysm` @@ -1984,6 +2086,20 @@ def __init__(self, f, g, p, ring=None, include=None, exclude=None): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_plethysm + sage: p = SymmetricFunctions(QQ).p() + sage: f = Stream_function(lambda n: p[n], True, 1) + sage: h = Stream_plethysm(f, f, p) + sage: h._approximate_order + 1 + sage: [h[i] for i in range(5)] + [0, p[1], 2*p[2], 2*p[3], 3*p[4]] + """ # this is very likely not the true order # if self._right._approximate_order == 0 and self._degree_f is None: # raise ValueError("can only compute plethysm with a series of " @@ -2172,6 +2288,19 @@ def __init__(self, series, scalar): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_rmul + sage: f = Stream_function(lambda n: Zmod(6)(n), True, 2) + sage: h = Stream_rmul(f, 3) # indirect doctest + sage: h._approximate_order + 2 + sage: [h[i] for i in range(5)] + [0, 0, 0, 3, 0] + """ # this is not the true order, unless we have an integral domain return self._series._approximate_order @@ -2352,6 +2481,19 @@ def __init__(self, series): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_neg + sage: f = Stream_function(lambda n: Zmod(6)(n), True, 2) + sage: h = Stream_neg(f) + sage: h._approximate_order + 2 + sage: [h[i] for i in range(5)] + [0, 0, 4, 3, 2] + """ # this is the true order return self._series._approximate_order @@ -2434,6 +2576,21 @@ def __init__(self, series, approximate_order=None): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_cauchy_invert + sage: f = Stream_function(lambda n: GF(7)(n), True, 0) + sage: [f[i] for i in range(5)] + [0, 1, 2, 3, 4] + sage: h = Stream_cauchy_invert(f) + sage: h._approximate_order + -1 + sage: [h[i] for i in range(-2, 5)] + [0, 1, 5, 1, 0, 0, 0] + """ try: return -self._series.order() except RecursionError: @@ -2587,6 +2744,19 @@ def __init__(self, series, function, approximate_order=None, true_order=False): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_map_coefficients + sage: f = Stream_function(lambda n: Zmod(6)(n), True, 2) + sage: h = Stream_map_coefficients(f, lambda c: 3*c) + sage: h._approximate_order + 2 + sage: [h[i] for i in range(5)] + [0, 0, 0, 3, 0] + """ # this is not the true order return self._series._approximate_order @@ -2684,6 +2854,19 @@ def __init__(self, series, shift): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_shift + sage: f = Stream_function(lambda n: Zmod(6)(n), True, 2) + sage: h = Stream_shift(f, -2) + sage: h._approximate_order + 0 + sage: [h[i] for i in range(5)] + [2, 3, 4, 5, 0] + """ # this is the true order return self._series._approximate_order + self._shift @@ -2786,6 +2969,19 @@ def __init__(self, series, shift): @lazy_attribute def _approximate_order(self): + """ + Compute and return the approximate order of ``self``. + + EXAMPLES:: + + sage: from sage.data_structures.stream import Stream_function, Stream_derivative + sage: f = Stream_function(lambda n: Zmod(6)(n), True, 2) + sage: h = Stream_derivative(f, 3) + sage: h._approximate_order + 0 + sage: [h[i] for i in range(5)] + [0, 0, 0, 0, 0] + """ # this is not the true order, unless multiplying by an # integer cannot give 0 if 0 <= self._series._approximate_order <= self._shift: From 4b1d7cd04a8bb8a40c7e1dd7cdc9de6d8c0ec014 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Tue, 27 Sep 2022 14:08:24 -0700 Subject: [PATCH 216/350] trac 34594: a doctest in "view" in sage.misc.latex should call _run_latex_(f) instead of _run_latex_(file). --- src/sage/misc/latex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 3ec3a3e9edf..e98f62d70d2 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -1859,7 +1859,7 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, sage: with NamedTemporaryFile(mode="w+t", suffix=".tex") as f: # optional - latex latex_package_tkz_graph ....: _ = f.write(_latex_file_(g)) ....: f.flush() - ....: _run_latex_(file, engine="pdflatex") + ....: _run_latex_(f, engine="pdflatex") 'pdf' sage: view(4, margin=5, debug=True) # not tested From 51cb095bbe891fbaafd5b6aa26a795cd31abb366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 28 Sep 2022 14:30:29 +0200 Subject: [PATCH 217/350] fixes in Hilbert polynomial --- .../polynomial/multi_polynomial_ideal.py | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 4e1937a4645..ee4e632e4b2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2815,37 +2815,43 @@ def hilbert_polynomial(self, algorithm='sage'): sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) sage: I.hilbert_polynomial() 5*t - 5 + + Check for :trac:`33597`:: + + sage: R. = QQ[] + sage: I = R.ideal([X^2*Y^3, X*Z]) + sage: I.hilbert_polynomial() + t + 5 """ if not self.is_homogeneous(): raise TypeError("ideal must be homogeneous") - if algorithm == 'sage': from sage.misc.misc_c import prod hilbert_poincare = self.hilbert_series() - denom = hilbert_poincare.denominator().factor() + denom = hilbert_poincare.denominator() + if denom.degree() == 0: + return denom.parent().zero() + t = denom.parent().gen() + s = denom.valuation(t - 1) second_hilbert = hilbert_poincare.numerator() - t = second_hilbert.parent().gen() - if denom: - s = denom[0][1] # this is the pole order of the Hilbert-Poincaré series at t=1 - else: - return t.parent().zero() - # we assume the denominator of the Hilbert series is of the form (1-t)^s, scale if needed - if hilbert_poincare.denominator().leading_coefficient() == 1: - second_hilbert = second_hilbert*(-1)**s - denom = ZZ(s-1).factorial() - out = sum(c / denom * prod(s - 1 - n - nu + t for nu in range(s-1)) - for n,c in enumerate(second_hilbert)) + t.parent().zero() - return out - elif algorithm == 'singular': + # we assume the denominator of the Hilbert series is of + # the form (1-t)^s, scale if needed + if denom[0] == -1: + second_hilbert = -second_hilbert + denom = (s - 1).factorial() + st = s - 1 + t + out = sum(c / denom * prod(st - n - nu for nu in range(s - 1)) + for n, c in enumerate(second_hilbert)) + return t.parent().zero() + out + if algorithm == 'singular': from sage.libs.singular.function_factory import ff hilbPoly = ff.polylib__lib.hilbPoly hp = hilbPoly(self) t = ZZ['t'].gen() - fp = ZZ(len(hp)-1).factorial() - return sum(ZZ(coeff) * t**i for i,coeff in enumerate(hp)) / fp - else: - raise ValueError("'algorithm' must be 'sage' or 'singular'") + fp = ZZ(len(hp) - 1).factorial() + return sum(ZZ(coeff) * t**i for i, coeff in enumerate(hp)) / fp + raise ValueError("'algorithm' must be 'sage' or 'singular'") @require_field @handle_AA_and_QQbar From a052558ad0ccd5afe3293c7457edaa1f0cb8b414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 28 Sep 2022 21:28:09 +0200 Subject: [PATCH 218/350] add some missing EXAMPLES --- src/sage/categories/magmas.py | 3 +- src/sage/combinat/sf/sf.py | 2 + src/sage/functions/bessel.py | 2 + .../automorphism_group_canonical_label.pyx | 41 ++++++++++--------- src/sage/knots/knotinfo.py | 34 +++++++-------- .../padics/padic_capped_absolute_element.pyx | 10 ++--- 6 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index c1f255a6eb9..801d3700707 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -774,12 +774,13 @@ def product(self, x, y): def __init_extra__(self): """ + EXAMPLES:: + sage: S = Semigroups().example("free") sage: S('a') * S('b') # indirect doctest 'ab' sage: S('a').__class__._mul_ == S('a').__class__._mul_parent True - """ # This should instead register the multiplication to the coercion model # But this is not yet implemented in the coercion model diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index f18f6fb75a2..a686dfef513 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -1605,6 +1605,8 @@ def __init__(self, t, domain, codomain): def __call__(self, partition): """ + EXAMPLES:: + sage: Sym = SymmetricFunctions(QQ['x']) sage: p = Sym.p(); s = Sym.s() sage: p[1] + s[1] # indirect doctest diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index de1401dde68..bea5c4e2445 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -1434,6 +1434,8 @@ def _derivative_(self, a, z, diff_param=None): def _print_latex_(self, a, z): """ + EXAMPLES:: + sage: latex(struve_L(2,x)) L_{{2}}({x}) """ diff --git a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx index eb3263d914d..a03a4c2c672 100644 --- a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +++ b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx @@ -99,15 +99,15 @@ REFERENCE: """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 - 2011 Robert L. Miller # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from libc.string cimport memcmp, memcpy from cysignals.memory cimport sig_malloc, sig_realloc, sig_free @@ -134,24 +134,25 @@ cdef int compare_structures_trivial(int *gamma_1, int *gamma_2, void *S1, void * def test_get_aut_gp_and_can_lab_trivially(int n=6, list partition=[[0,1,2],[3,4],[5]], canonical_label=True, base=False): """ - sage: tttt = sage.groups.perm_gps.partn_ref.automorphism_group_canonical_label.test_get_aut_gp_and_can_lab_trivially - sage: tttt() - 12 - sage: tttt(canonical_label=False, base=False) - 12 - sage: tttt(canonical_label=False, base=True) - 12 - sage: tttt(canonical_label=True, base=True) - 12 - sage: tttt(n=0, partition=[]) - 1 - sage: tttt(n=0, partition=[], canonical_label=False, base=False) - 1 - sage: tttt(n=0, partition=[], canonical_label=False, base=True) - 1 - sage: tttt(n=0, partition=[], canonical_label=True, base=True) - 1 + TESTS:: + sage: tttt = sage.groups.perm_gps.partn_ref.automorphism_group_canonical_label.test_get_aut_gp_and_can_lab_trivially + sage: tttt() + 12 + sage: tttt(canonical_label=False, base=False) + 12 + sage: tttt(canonical_label=False, base=True) + 12 + sage: tttt(canonical_label=True, base=True) + 12 + sage: tttt(n=0, partition=[]) + 1 + sage: tttt(n=0, partition=[], canonical_label=False, base=False) + 1 + sage: tttt(n=0, partition=[], canonical_label=False, base=True) + 1 + sage: tttt(n=0, partition=[], canonical_label=True, base=True) + 1 """ cdef aut_gp_and_can_lab *output cdef Integer I = Integer(0) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index df893a488f6..f122211113a 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -374,25 +374,27 @@ def items(self): @cached_method def __getitem__(self, item): r""" - sage: from sage.knots.knotinfo import KnotInfo - sage: L = KnotInfo.L4a1_0 - sage: L[L.items.alternating] - 'Y' - sage: L[L.items.arc_notation] - '{{6, 4}, {3, 5}, {4, 2}, {1, 3}, {2, 6}, {5, 1}}' - sage: L[L.items.braid_notation] - '{3, {-2, -2, -1, 2, -1}}' - sage: L[0] - Traceback (most recent call last): - ... - KeyError: "Item must be an instance of " + EXAMPLES:: + + sage: from sage.knots.knotinfo import KnotInfo + sage: L = KnotInfo.L4a1_0 + sage: L[L.items.alternating] + 'Y' + sage: L[L.items.arc_notation] + '{{6, 4}, {3, 5}, {4, 2}, {1, 3}, {2, 6}, {5, 1}}' + sage: L[L.items.braid_notation] + '{3, {-2, -2, -1, 2, -1}}' + sage: L[0] + Traceback (most recent call last): + ... + KeyError: "Item must be an instance of " """ if not isinstance(item, KnotInfoColumns): - raise KeyError('Item must be an instance of %s' %(KnotInfoColumns)) + raise KeyError('Item must be an instance of %s' % (KnotInfoColumns)) if item.column_type() == item.types.OnlyLinks and self.is_knot(): - raise KeyError('Item not available for knots' %(KnotInfoColumns)) + raise KeyError('Item not available for knots' % (KnotInfoColumns)) if item.column_type() == item.types.OnlyKnots and not self.is_knot(): - raise KeyError('Item not available for links' %(KnotInfoColumns)) + raise KeyError('Item not available for links' % (KnotInfoColumns)) l = db.read(item) ind = db.read_row_dict()[self.name][0] @@ -400,7 +402,7 @@ def __getitem__(self, item): if item.column_type() == item.types.OnlyLinks: offset = self._offset_knots() - return l[ind-offset] + return l[ind - offset] def _offset_knots(self): r""" diff --git a/src/sage/rings/padics/padic_capped_absolute_element.pyx b/src/sage/rings/padics/padic_capped_absolute_element.pyx index b8f7598251f..91e973ccf7e 100644 --- a/src/sage/rings/padics/padic_capped_absolute_element.pyx +++ b/src/sage/rings/padics/padic_capped_absolute_element.pyx @@ -9,8 +9,7 @@ AUTHORS: - Genya Zaytman: documentation - David Harvey: doctests """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2013 David Roe # William Stein # @@ -18,9 +17,8 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** include "sage/libs/linkages/padics/mpz.pxi" include "CA_template.pxi" @@ -89,6 +87,8 @@ cdef class pAdicCappedAbsoluteElement(CAElement): """ def lift(self): """ + EXAMPLES:: + sage: R = ZpCA(3) sage: R(10).lift() 10 From c28b7e10fde5e8bfd368eded843c51f8aaf14a66 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 28 Sep 2022 21:23:30 +0800 Subject: [PATCH 219/350] add MPolynomialRing_base.monomials_of_degree() --- .../polynomial/multi_polynomial_ring_base.pyx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 02eeb51bacf..bdd40bfdda2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1184,6 +1184,27 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): """ return self({exponents: self.base_ring().one()}) + def monomials_of_degree(self, degree): + r""" + Return a list of all monomials of the given total degree in this + multivariate polynomial ring. + + EXAMPLES:: + + sage: R. = ZZ[] + sage: mons = R.monomials_of_degree(2) + sage: mons + [x^2, x*y, x*z, y^2, y*z, z^2] + + The number of such monomials equals `\binom{n+k-1}{k}` + where `n` is the number of variables and `k` the degree:: + + sage: len(mons) == binomial(3+2-1,2) + True + """ + from sage.combinat.integer_vector import IntegerVectors + return [self.monomial(*a) for a in IntegerVectors(degree, self.ngens())] + def _macaulay_resultant_getS(self, mon_deg_tuple, dlist): r""" In the Macaulay resultant algorithm the list of all monomials of the total degree is partitioned into sets `S_i`. From c5202ea6a09218ab24e5f35f423529dc91b08ed5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 28 Sep 2022 15:07:47 -0700 Subject: [PATCH 220/350] build/pkgs/latte_int/patches/6dbf7f07d5c9e1f3afe793f782d191d4465088ae.patch: Remove hunks for files not in the distribution --- ...7f07d5c9e1f3afe793f782d191d4465088ae.patch | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/build/pkgs/latte_int/patches/6dbf7f07d5c9e1f3afe793f782d191d4465088ae.patch b/build/pkgs/latte_int/patches/6dbf7f07d5c9e1f3afe793f782d191d4465088ae.patch index 308456304d7..199ab2d0156 100644 --- a/build/pkgs/latte_int/patches/6dbf7f07d5c9e1f3afe793f782d191d4465088ae.patch +++ b/build/pkgs/latte_int/patches/6dbf7f07d5c9e1f3afe793f782d191d4465088ae.patch @@ -51,29 +51,3 @@ index c9fa4ace..43a4ab63 100644 ZZ scalar_power(const vec_ZZ &generic_vector, -diff --git a/code/latte/sqlite/IntegrationDB.cpp b/code/latte/sqlite/IntegrationDB.cpp -index ab8df535..c1dde830 100644 ---- a/code/latte/sqlite/IntegrationDB.cpp -+++ b/code/latte/sqlite/IntegrationDB.cpp -@@ -1277,7 +1277,7 @@ void IntegrationDB::insertSpecficPolytopeIntegrationTest(string polymakeFile, i - * @parm filePath: to the latte-style polynomial. - * @return rowid of the inserted row. - */ --int IntegrationDB::insertPolynomial(int dim, int degree, const char*filePath) throw(SqliteDBexception) -+int IntegrationDB::insertPolynomial(int dim, int degree, const char*filePath) - { - if ( doesPolynomialExist(filePath)) - throw SqliteDBexception(string("insertPolynomial::Polynomial ")+filePath+" already exist"); -diff --git a/code/latte/sqlite/IntegrationDB.h b/code/latte/sqlite/IntegrationDB.h -index d690a832..ce8cfac6 100644 ---- a/code/latte/sqlite/IntegrationDB.h -+++ b/code/latte/sqlite/IntegrationDB.h -@@ -67,7 +67,7 @@ class IntegrationDB: public SqliteDB - int insertIntegrationTest(int polynomialID, int polytopeID); - void insertIntegrationTest(int dim, int degree, int vertexCount, int count); - void insertSpecficPolytopeIntegrationTest(string polymakeFile, int degree, int count); -- int insertPolynomial(int dim, int degree, const char*filePath) throw(SqliteDBexception); -+ int insertPolynomial(int dim, int degree, const char*filePath); - - int insertPolytope(int dim, int vertexCount, int simple, int dualRowID, const char* latteFilePath, const char* polymakeFilePath); - From 81ff989f53610b3c367a46e50ed046aa1cfe8f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 29 Sep 2022 10:28:02 +0200 Subject: [PATCH 221/350] 34594: f -> f.name --- src/sage/misc/latex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index e98f62d70d2..04df1b0a4b3 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -1859,7 +1859,7 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, sage: with NamedTemporaryFile(mode="w+t", suffix=".tex") as f: # optional - latex latex_package_tkz_graph ....: _ = f.write(_latex_file_(g)) ....: f.flush() - ....: _run_latex_(f, engine="pdflatex") + ....: _run_latex_(f.name, engine="pdflatex") 'pdf' sage: view(4, margin=5, debug=True) # not tested From 103bcc4fa4eec920ac65979906f90403e269a79e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 29 Sep 2022 11:21:38 +0200 Subject: [PATCH 222/350] 34606: Since version 9.7 -> Since version 9.8 --- src/doc/en/thematic_tutorials/geometry/polytope_tikz.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/en/thematic_tutorials/geometry/polytope_tikz.rst b/src/doc/en/thematic_tutorials/geometry/polytope_tikz.rst index a0c98ea3836..ee96fe1831e 100644 --- a/src/doc/en/thematic_tutorials/geometry/polytope_tikz.rst +++ b/src/doc/en/thematic_tutorials/geometry/polytope_tikz.rst @@ -15,7 +15,7 @@ paper. TikZ is a very versatile tool to draw in scientific documents and Sage can deal easily with 3-dimensional polytopes. Finally sagetex makes everything work together nicely between Sage, TikZ and LaTeX. Since version 6.3 of Sage, there is a function for (projection -of) polytopes to output a TikZ picture of the polytope. Since version 9.7 of +of) polytopes to output a TikZ picture of the polytope. Since version 9.8 of SageMath, the tikz output can be a ``TikzPicture`` object from the sage module ``sage.misc.latex_standalone``. This short tutorial shows how it all works. @@ -61,7 +61,7 @@ You can customize the polytope using the following options in the command ``P.ti - ``opacity`` : real number (default: ``0.8``) between 0 and 1 giving the opacity of the front facets, - ``axis`` : Boolean (default: ``False``) draw the axes at the origin or not. - ``output_type`` : string (default: ``None``) ``None``, ``'LatexExpr'`` or - ``'TikzPicture'``, the type of the output. Since SageMath 9.7, the value ``None`` is deprecated + ``'TikzPicture'``, the type of the output. Since SageMath 9.8, the value ``None`` is deprecated as the default value will soon be changed from ``'LatexExpr'`` to ``'TikzPicture'``. Examples @@ -90,7 +90,7 @@ When you found a good angle, follow the above procedure to obtain the values .. end of output -Note: the ``output_type='TikzPicture'`` is necessary since SagMath 9.7 to avoid +Note: the ``output_type='TikzPicture'`` is necessary since SagMath 9.8 to avoid a deprecation warning message since the default output type will soon change from a ``LatexExpr`` (Python str) to a ``TikzPicture`` object (allowing more versatility, like being able to view it directly in the Jupyter notebook). From d46a7fcd462b84e3163dfd79b9a57d759148d448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 29 Sep 2022 11:45:34 +0200 Subject: [PATCH 223/350] 34607: more robust octave doctests --- src/sage/interfaces/octave.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index ae1b87c55cb..b22c2fb1d3a 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -156,14 +156,17 @@ class Octave(Expect): EXAMPLES:: - sage: octave.eval("a = [ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]") # optional - octave - 'a =\n\n 1 1 2\n 3 5 8\n 13 21 33\n' - sage: octave.eval("b = [ 1; 3; 13]") # optional - octave - 'b =\n\n 1\n 3\n 13\n' - sage: octave.eval(r"c=a \ b") # solves linear equation: a*c = b # optional - octave; random output - 'c =\n\n 1\n 7.21645e-16\n -7.21645e-16\n' - sage: octave.eval("c") # optional - octave; random output - 'c =\n\n 1\n 7.21645e-16\n -7.21645e-16\n' + sage: octave.eval("a = [ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]").strip() # optional - octave + 'a =\n\n 1 1 2\n 3 5 8\n 13 21 33' + sage: octave.eval("b = [ 1; 3; 13]").strip() # optional - octave + 'b =\n\n 1\n 3\n 13' + + The following solves the linear equation: a*c = b:: + + sage: octave.eval(r"c=a \ b").strip() # optional - octave # abs tol 0.01 + 'c =\n\n 1\n -0\n 0' + sage: octave.eval("c").strip() # optional - octave # abs tol 0.01 + 'c =\n\n 1\n -0\n 0' TESTS: From e9b1f02ca755e9c1f83b30b3146572ad564740e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 29 Sep 2022 11:58:04 +0200 Subject: [PATCH 224/350] 34609: fix doctests failures with oeis --- src/sage/databases/oeis.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index ca5b3e65290..a800db53df2 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -28,13 +28,13 @@ :: - sage: search = oeis([3, 7, 15, 1], max_results=4) ; search # optional -- internet + sage: search = oeis([3, 7, 15, 1], max_results=4) ; search # optional -- internet # random 0: A001203: Simple continued fraction expansion of Pi. 1: A240698: Partial sums of divisors of n, cf. A027750. 2: A082495: a(n) = (2^n - 1) mod n. 3: A165416: Irregular array read by rows: The n-th row contains those distinct positive integers that each, when written in binary, occurs as a substring in binary n. - sage: [u.id() for u in search] # optional -- internet + sage: [u.id() for u in search] # optional -- internet # random ['A001203', 'A240698', 'A082495', 'A165416'] sage: c = search[0] ; c # optional -- internet A001203: Simple continued fraction expansion of Pi. @@ -349,7 +349,7 @@ class OEIS: The database can be searched by description:: - sage: oeis('prime gap factorization', max_results=4) # optional --internet + sage: oeis('prime gap factorization', max_results=4) # optional --internet # random 0: A073491: Numbers having no prime gaps in their factorization. 1: A073485: Product of any number of consecutive primes; squarefree numbers with no gaps in their prime factorization. 2: A073490: Number of prime gaps in factorization of n. @@ -491,7 +491,7 @@ def find_by_description(self, description, max_results=3, first_result=0): 2: A...: ... sage: prime_gaps = _[2] ; prime_gaps # optional -- internet - A073490: Number of prime gaps in factorization of n. + A... sage: oeis('beaver') # optional -- internet 0: A...: ...eaver... @@ -535,7 +535,7 @@ def find_by_subsequence(self, subsequence, max_results=3, first_result=0): EXAMPLES:: - sage: oeis.find_by_subsequence([2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]) # optional -- internet + sage: oeis.find_by_subsequence([2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]) # optional -- internet # random 0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. 1: A212804: Expansion of (1 - x)/(1 - x - x^2). 2: A020695: Pisot sequence E(2,3). From 1ef60e42efa64f9971a7b4d88034e53add4aa076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 29 Sep 2022 12:09:13 +0200 Subject: [PATCH 225/350] 34612: fix failing internet doctest --- src/sage/graphs/isgci.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py index 2ea1adce781..147e2ba2778 100644 --- a/src/sage/graphs/isgci.py +++ b/src/sage/graphs/isgci.py @@ -869,6 +869,7 @@ def update_db(self): EXAMPLES:: sage: graph_classes.update_db() # optional - internet + Database downloaded """ self._download_db() From 83e0322c3f81a5fc807480dae1c90d4d776984a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 29 Sep 2022 14:40:29 +0200 Subject: [PATCH 226/350] fix a bunch of typos --- src/sage/combinat/words/finite_word.py | 3 +- .../arithmetic_dynamics/berkovich_ds.py | 2 +- .../endPN_automorphism_group.py | 36 ++++++++++--------- .../arithmetic_dynamics/projective_ds.py | 18 +++++----- src/sage/ext_data/pari/simon/ell.gp | 2 +- .../modular_decomposition.py | 2 +- src/sage/groups/braid.py | 4 +-- src/sage/knots/knotinfo.py | 2 +- src/sage/rings/padics/relaxed_template.pxi | 2 +- .../skew_polynomial_finite_field.pyx | 3 +- 10 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 5773491e025..91bc443c8f5 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -217,6 +217,7 @@ from itertools import repeat from collections import defaultdict from itertools import islice, cycle + from sage.combinat.words.abstract_word import Word_class from sage.combinat.words.words import Words from sage.misc.cachefunc import cached_method @@ -2622,7 +2623,7 @@ def palindromic_lacunas_study(self, f=None): and lacunas of ``self`` (see [BMBL2008]_ and [BMBFLR2008]_). Note that a word `w` has at most `|w| + 1` different palindromic factors - (see [DJP2001]_). For `f`-palindromes (or pseudopalidromes or theta-palindromes), + (see [DJP2001]_). For `f`-palindromes (or pseudopalindromes or theta-palindromes), the maximum number of `f`-palindromic factors is `|w|+1-g_f(w)`, where `g_f(w)` is the number of pairs `\{a, f(a)\}` such that `a` is a letter, `a` is not equal to `f(a)`, and `a` or `f(a)` occurs in `w`, see [Star2011]_. diff --git a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py index 92f10c05a9a..7810a88fd7f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py @@ -1,5 +1,5 @@ r""" -Dynamical systmes on Berkovich space over `\CC_p`. +Dynamical systems on Berkovich space over `\CC_p`. A dynamical system on Berkovich space over `\CC_p` is determined by a dynamical system on `A^1(\CC_p)` or `P^1(\CC_p)`, diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 8424b2fc505..72f63af7eac 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -1907,7 +1907,7 @@ def conjugating_set_initializer(f, g): repeated_mult_L[repeated] += [mult_to_point_L[mult_L]] more = True - # the n+2 points to be used to specificy PGL conjugations + # the n+2 points to be used to specify PGL conjugations source = [] # a list of tuples of the form ((multiplier, level), repeat) where the @@ -1997,9 +1997,10 @@ def conjugating_set_initializer(f, g): for r in sorted(repeated_mult_L.keys()): for point_lst in repeated_mult_L[r]: all_points += point_lst - # this loop is quite long, so we break after finding the first subset - # with the desired property. There is, however, no guarentee that the - # subset we found minimizes the combinatorics when checking conjugations + # this loop is quite long, so we break after finding the + # first subset with the desired property. There is, + # however, no guarantee that the subset we found minimizes + # the combinatorics when checking conjugations for subset in Subsets(range(len(all_points)), n+2): source = [] for i in subset: @@ -2166,10 +2167,10 @@ def conjugating_set_helper(f, g, num_cpus, source, possible_targets): subset_iterators.append(Subsets(range(len(lst[0])), lst[1])) # helper function for parallelization - # given a list of tuples which specify indicies of possible target points - # in possible_targets, check all arragements of those possible target points - # and if any of them define a conjugation which sends f to g, return - # those conjugations as a list + # given a list of tuples which specify indices of possible target + # points in possible_targets, check all arrangements of those + # possible target points and if any of them define a conjugation + # which sends f to g, return those conjugations as a list def find_conjugations_subset(tuples): conj = [] for tup in tuples: @@ -2195,9 +2196,9 @@ def find_conjugations_subset(tuples): return conj # helper function for parallelization - # given a list of tuples which specify indicies of possible target points - # in possible_targets, check all possible target points - # and if any of them define a conjugation which sends f to g, return + # given a list of tuples which specify indices of possible target + # points in possible_targets, check all possible target points and + # if any of them define a conjugation which sends f to g, return # those conjugations as a list def find_conjugations_arrangement(tuples): conj = [] @@ -2229,7 +2230,7 @@ def find_conjugations_arrangement(tuples): if ret[1]: Conj += ret[1] # otherwise, we need to first check linear independence of the subsets - # and then build a big list of all the arrangemenets to split among + # and then build a big list of all the arrangements to split among # the threads else: good_targets = [] @@ -2307,9 +2308,10 @@ def is_conjugate_helper(f, g, num_cpus, source, possible_targets): subset_iterators.append(Subsets(range(len(lst[0])), lst[1])) # helper function for parallelization - # given a list of tuples which specify indicies of possible target points - # in possible_targets, check all arragements of those possible target points - # and if any of them define a conjugation which sends f to g, return True + # given a list of tuples which specify indices of possible target + # points in possible_targets, check all arrangements of those + # possible target points and if any of them define a conjugation + # which sends f to g, return True def find_conjugations_subset(tuples): for tup in tuples: target_set = [] @@ -2334,7 +2336,7 @@ def find_conjugations_subset(tuples): return False # helper function for parallelization - # given a list of tuples which specify indicies of possible target points + # given a list of tuples which specify indices of possible target points # in possible_targets, check all possible target points # and if any of them define a conjugation which sends f to g, return True def find_conjugations_arrangement(tuples): @@ -2367,7 +2369,7 @@ def find_conjugations_arrangement(tuples): is_conj = True break # otherwise, we need to first check linear independence of the subsets - # and then build a big list of all the arrangemenets to split among + # and then build a big list of all the arrangements to split among # the threads else: good_targets = [] diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index cdfc11a9e52..1565f9e7664 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4219,7 +4219,7 @@ def preperiodic_points(self, m, n, **kwds): f_deformed = DynamicalSystem(deformed_polys) # after deforming by the parameter, the preperiodic points with multiplicity - # will seperate into different points. we can now calculate the minimal preperiodic + # will separate into different points. we can now calculate the minimal preperiodic # points with the parameter, and then specialize to get the formal preperiodic points ideal = f_deformed.preperiodic_points(m, n, return_scheme=True).defining_ideal() L = [poly.specialization({t:0}) for poly in ideal.gens()] @@ -4569,7 +4569,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari f_deformed = DynamicalSystem(deformed_polys) # after deforming by the parameter, the preperiodic points with multiplicity - # will seperate into different points. we can now calculate the minimal preperiodic + # will separate into different points. we can now calculate the minimal preperiodic # points with the parameter, and then specialize to get the formal periodic points ideal = f_deformed.periodic_points(n, return_scheme=True).defining_ideal() L = [poly.specialization({t:0}) for poly in ideal.gens()] @@ -4901,7 +4901,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', - ``n`` periodic points are repeated, multipliers are all distinct -- to deal with this case, we deform the map by a formal parameter `k`. The deformation - seperates the ``n`` periodic points, making them distinct, and we can recover + separates the ``n`` periodic points, making them distinct, and we can recover the ``n`` periodic points of the original map by specializing `k` to 0. This corresponds to ``deform=True``. @@ -4952,7 +4952,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', - ``check`` -- (default: ``True``) boolean; when ``True`` the degree of the sigma polynomial is checked against the expected degree. This is - done as the sigma polynomial may drop degree if multiplicites of periodic + done as the sigma polynomial may drop degree if multiplicities of periodic points or multipliers are not correctly accounted for using ``chow`` or ``deform``. @@ -5236,8 +5236,8 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', # create polynomial ring for result R2 = PolynomialRing(F, var[:N] + var[-2:]) psi = R2.hom(N*[0]+list(newR.gens()), newR) - # create substition to set extra variables to 0 - R_zero = {R.gen(N):1} + # create substitution to set extra variables to 0 + R_zero = {R.gen(N): 1} for j in range(N+1, 2*N+1): R_zero[R.gen(j)] = 0 t = var.pop() @@ -5251,7 +5251,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', w = var.pop() sigma_polynomial = 1 # go through each affine patch to avoid repeating periodic points - # setting the visited coordiantes to 0 as we go + # setting the visited coordinates to 0 as we go for j in range(N,-1,-1): Xa = X.affine_patch(j) fa = Fn.dehomogenize(j) @@ -5308,7 +5308,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', 'try setting chow=True and/or deform=True') if return_polynomial: return sigma_polynomial - # if we are returing a numerical list, read off the coefficients + # if we are returning a numerical list, read off the coefficients # in order of degree adjusting sign appropriately sigmas = [] sigma_dictionary = dict([list(reversed(i)) for i in list(sigma_polynomial)]) @@ -6833,7 +6833,7 @@ def conjugating_set(self, other, R=None, num_cpus=2): by taking the fixed points of one map and mapping them to permutations of the fixed points of the other map. As conjugacy preserves the multipliers as a set, fixed points - are only maped to fixed points with the same multiplier. + are only mapped to fixed points with the same multiplier. If there are not enough fixed points the function compares the mapping between rational preimages of fixed points and the rational preimages of the preimages of diff --git a/src/sage/ext_data/pari/simon/ell.gp b/src/sage/ext_data/pari/simon/ell.gp index 4e9870eb13e..663df10a7c3 100644 --- a/src/sage/ext_data/pari/simon/ell.gp +++ b/src/sage/ext_data/pari/simon/ell.gp @@ -1503,7 +1503,7 @@ if( DEBUGLEVEL_ell >= 4, print(" end of bnfredquartique")); \\ si bigflag !=0 alors on applique bnfredquartique. \\ si flag3 ==1 alors on utilise bnfqfsolve2 (equation aux normes) pour resoudre Legendre \\ aut est une liste d'automorphismes connus de bnf -\\ (ca peut aider a factoriser certains discriminiants). +\\ (ca peut aider a factoriser certains discriminants). \\ ell est de la forme y^2=x^3+A*x^2+B*x+C \\ ie ell=[0,A,0,B,C], avec A,B et C entiers. \\ diff --git a/src/sage/graphs/graph_decompositions/modular_decomposition.py b/src/sage/graphs/graph_decompositions/modular_decomposition.py index 9aef9721fc8..0c1ae4da5b3 100644 --- a/src/sage/graphs/graph_decompositions/modular_decomposition.py +++ b/src/sage/graphs/graph_decompositions/modular_decomposition.py @@ -1278,7 +1278,7 @@ def permute_decomposition(trials, algorithm, vertices, prob, verbose=False): t1p = relabel_tree(t1, random_perm) assert(equivalent_trees(t1p, t2)) if verbose: - print("Passses!") + print("Passes!") def random_md_tree(max_depth, max_fan_out, leaf_probability): diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 99c468f75dd..af5fa4b8e29 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2200,7 +2200,7 @@ def reduced_word(self): .. TODO:: - Paralellize this function, calculating all summands in the sum + Parallelize this function, calculating all summands in the sum in parallel. """ M = self._algebra._indices @@ -2245,7 +2245,7 @@ def eps(self, N): .. TODO:: - Paralellize this function, calculating all summands in the sum + Parallelize this function, calculating all summands in the sum in parallel. """ def eps_monom(q_tuple): diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index df893a488f6..568af3e7507 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -117,7 +117,7 @@ sage: l6sn.sage_link().is_isotopic(l6) # optional - snappy True -But observe that the name conversion to SnapPy does not distingiush orientation +But observe that the name conversion to SnapPy does not distinguish orientation types:: sage: L6b = KnotInfo.L6a1_1 diff --git a/src/sage/rings/padics/relaxed_template.pxi b/src/sage/rings/padics/relaxed_template.pxi index f87034e56e3..4de2b197ad1 100644 --- a/src/sage/rings/padics/relaxed_template.pxi +++ b/src/sage/rings/padics/relaxed_template.pxi @@ -702,7 +702,7 @@ cdef class RelaxedElement(pAdicGenericElement): use the default halting precision of the parent - ``secure`` -- a boolean (default: ``False`` if ``prec`` is given, - ``True`` otherwise); when the elements cannot be distingiushed + ``True`` otherwise); when the elements cannot be distinguished at the given precision, raise an error if ``secure`` is ``True``, return ``True`` otherwise. diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx index 220c9b87c1d..289784b94b3 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx @@ -822,10 +822,9 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): factors.reverse() return Factorization(factors, sort=False, unit=unit) - cdef _factor_uniform_c(self): r""" - Compute a uniformly distrbuted factorization of ``self``. + Compute a uniformly distributed factorization of ``self``. This is the low level implementation of :meth:`factor`. """ From 539324204ae876de4292c469eed336d8b6ee0f4a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 29 Sep 2022 15:13:46 +0200 Subject: [PATCH 227/350] fixes for pycodestyle and pyflakes --- src/sage/rings/lazy_series.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 0b1eba2a6a7..48af601a570 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -839,8 +839,8 @@ def _richcmp_(self, other, op): return False # undecidable otherwise - prec = self.parent().options.halting_precision - if prec == None: + prec = self.parent().options['halting_precision'] + if prec is None: raise ValueError("undecidable") # at least one of the approximate orders is not infinity m = min(self._coeff_stream._approximate_order, @@ -957,8 +957,8 @@ def __bool__(self): if self[v]: return True - prec = self.parent().options.halting_precision - if prec == None: + prec = self.parent().options['halting_precision'] + if prec is None: raise ValueError("undecidable as lazy Laurent series") return any(self[i] for i in range(v, v + prec)) @@ -5449,6 +5449,7 @@ def revert(self): la = Partition([1]) X = R(la) + def coefficient(n): if n: return 0 From c2e610cfba02a8cb4db7d7691bfc8210be8a1ffb Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Thu, 29 Sep 2022 21:29:04 +0200 Subject: [PATCH 228/350] Fix build with sphinx 5.2 --- src/sage_docbuild/ext/multidocs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage_docbuild/ext/multidocs.py b/src/sage_docbuild/ext/multidocs.py index 39121ef90ac..b73baeadb71 100644 --- a/src/sage_docbuild/ext/multidocs.py +++ b/src/sage_docbuild/ext/multidocs.py @@ -146,6 +146,10 @@ def merge_js_index(app): titles = app.builder.indexer._titles for (res, title) in index._titles.items(): titles[fixpath(res)] = title + # merge the alltitles + alltitles = app.builder.indexer._all_titles + for (res, alltitle) in index._all_titles.items(): + alltitles[fixpath(res)] = alltitle # merge the filenames filenames = app.builder.indexer._filenames for (res, filename) in index._filenames.items(): From 0be8a8fa6ccea5c8514828913757be9c4da86062 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Thu, 29 Sep 2022 23:00:39 +0200 Subject: [PATCH 229/350] Update sphinx to 5.2 --- build/pkgs/sphinx/checksums.ini | 6 +++--- build/pkgs/sphinx/install-requires.txt | 2 +- build/pkgs/sphinx/package-version.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/sphinx/checksums.ini b/build/pkgs/sphinx/checksums.ini index 624ea28a1b1..49b3d2806f4 100644 --- a/build/pkgs/sphinx/checksums.ini +++ b/build/pkgs/sphinx/checksums.ini @@ -1,5 +1,5 @@ tarball=Sphinx-VERSION.tar.gz -sha1=c0aa13911c331244877fc3947c0e7cec10d9e72b -md5=663e2f2ee9219ef4913831950825f68b -cksum=1902891868 +sha1=e1c25f090eb9e1960276bafd636374413f17660f +md5=a266df26c4cabd093f55b79eaaffc4bd +cksum=2420152777 upstream_url=https://pypi.io/packages/source/s/sphinx/Sphinx-VERSION.tar.gz diff --git a/build/pkgs/sphinx/install-requires.txt b/build/pkgs/sphinx/install-requires.txt index 9a8ff0bf429..16e1ac533d9 100644 --- a/build/pkgs/sphinx/install-requires.txt +++ b/build/pkgs/sphinx/install-requires.txt @@ -1 +1 @@ -sphinx >=4.3, <4.5 +sphinx >=5.2, <6 diff --git a/build/pkgs/sphinx/package-version.txt b/build/pkgs/sphinx/package-version.txt index fdc6698807a..91ff57278e3 100644 --- a/build/pkgs/sphinx/package-version.txt +++ b/build/pkgs/sphinx/package-version.txt @@ -1 +1 @@ -4.4.0 +5.2.0 From b8630ace295ff5b33fe4dd40e15ebeee9bd74263 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 30 Sep 2022 13:18:25 +0900 Subject: [PATCH 230/350] Make it more efficient --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index ee4e632e4b2..2c38a1bef91 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2833,15 +2833,13 @@ def hilbert_polynomial(self, algorithm='sage'): return denom.parent().zero() t = denom.parent().gen() s = denom.valuation(t - 1) - second_hilbert = hilbert_poincare.numerator() + numerator = hilbert_poincare.numerator() # we assume the denominator of the Hilbert series is of - # the form (1-t)^s, scale if needed - if denom[0] == -1: - second_hilbert = -second_hilbert - denom = (s - 1).factorial() + # the form (1 - t)^s, need to scale numerator by denom[0] + scalar = ~denom[0] / (s - 1).factorial() st = s - 1 + t - out = sum(c / denom * prod(st - n - nu for nu in range(s - 1)) - for n, c in enumerate(second_hilbert)) + out = scalar * sum(c * prod(st - n - nu for nu in range(s - 1)) + for n, c in enumerate(numerator)) return t.parent().zero() + out if algorithm == 'singular': from sage.libs.singular.function_factory import ff From 98f118dc6595400d0c4667b006f426616e35ee91 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 30 Sep 2022 13:34:15 +0900 Subject: [PATCH 231/350] Minor edits --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 2c38a1bef91..d1b0e9a5032 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2835,8 +2835,8 @@ def hilbert_polynomial(self, algorithm='sage'): s = denom.valuation(t - 1) numerator = hilbert_poincare.numerator() # we assume the denominator of the Hilbert series is of - # the form (1 - t)^s, need to scale numerator by denom[0] - scalar = ~denom[0] / (s - 1).factorial() + # the form (1 - t)^s, need to scale numerator + scalar = ~(denom[0] * (s - 1).factorial()) st = s - 1 + t out = scalar * sum(c * prod(st - n - nu for nu in range(s - 1)) for n, c in enumerate(numerator)) From fba8e59f23883da82998cfef87aa45b06eae6f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 10:00:37 +0200 Subject: [PATCH 232/350] fix and activate check of W391 --- .vscode/settings.json | 2 +- src/doc/de/thematische_anleitungen/conf.py | 5 ++--- src/doc/de/tutorial/conf.py | 1 - src/doc/en/a_tour_of_sage/conf.py | 1 - src/doc/en/constructions/conf.py | 1 - src/doc/en/developer/conf.py | 1 - src/doc/en/installation/conf.py | 1 - .../explicit_methods_in_number_theory/conf.py | 1 - src/doc/en/thematic_tutorials/numerical_sage/conf.py | 1 - src/doc/en/tutorial/conf.py | 1 - src/doc/en/website/conf.py | 1 - src/doc/fr/tutorial/conf.py | 1 - src/doc/ru/tutorial/conf.py | 1 - src/doc/tr/a_tour_of_sage/conf.py | 3 +-- src/sage_docbuild/conf.py | 7 +++++-- src/tox.ini | 3 ++- 16 files changed, 11 insertions(+), 20 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c2193d76a35..e414fb65d7f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,7 +27,7 @@ "python.linting.enabled": true, // The following pycodestyle arguments are the same as the pycodestyle-minimal // tox environnment, see the file SAGE_ROOT/src/tox.ini - "python.linting.pycodestyleArgs": ["--select=E111,E306,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722"], + "python.linting.pycodestyleArgs": ["--select=E111,E306,E401,E701,E702,E703,W391,W605,E711,E712,E713,E721,E722"], "cSpell.words": [ "furo", "Conda", diff --git a/src/doc/de/thematische_anleitungen/conf.py b/src/doc/de/thematische_anleitungen/conf.py index 114346944d5..7f2753ab0e4 100644 --- a/src/doc/de/thematische_anleitungen/conf.py +++ b/src/doc/de/thematische_anleitungen/conf.py @@ -27,7 +27,7 @@ # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = project + " v"+release +html_title = project + " v" + release # Output file base name for HTML help builder. htmlhelp_basename = name @@ -35,7 +35,6 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('index', name+'.tex', project, + ('index', name + '.tex', project, 'The Sage Group', 'manual'), ] - diff --git a/src/doc/de/tutorial/conf.py b/src/doc/de/tutorial/conf.py index 16804d981c9..8d18c44aa6b 100644 --- a/src/doc/de/tutorial/conf.py +++ b/src/doc/de/tutorial/conf.py @@ -38,4 +38,3 @@ ('index', name+'.tex', project, 'The Sage Group', 'manual'), ] - diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py index 89225513782..14ecb994215 100644 --- a/src/doc/en/a_tour_of_sage/conf.py +++ b/src/doc/en/a_tour_of_sage/conf.py @@ -37,4 +37,3 @@ ('index', 'a_tour_of_sage.tex', 'A Tour Of Sage', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/constructions/conf.py b/src/doc/en/constructions/conf.py index eee2feb033a..37215f418c6 100644 --- a/src/doc/en/constructions/conf.py +++ b/src/doc/en/constructions/conf.py @@ -36,4 +36,3 @@ ('index', 'constructions.tex', 'Constructions', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/developer/conf.py b/src/doc/en/developer/conf.py index 1ee9e105947..bde00a0970d 100644 --- a/src/doc/en/developer/conf.py +++ b/src/doc/en/developer/conf.py @@ -36,4 +36,3 @@ ('index', 'developer.tex', 'Developer\'s Guide', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/installation/conf.py b/src/doc/en/installation/conf.py index 33ed20fa8e9..e50bf3c1c57 100644 --- a/src/doc/en/installation/conf.py +++ b/src/doc/en/installation/conf.py @@ -36,4 +36,3 @@ ('index', 'installation.tex', 'Installation Guide', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py index cdcbdb584c9..b8eef385e4f 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py @@ -40,4 +40,3 @@ ('index', name + '.tex', 'Three Lectures about Explicit Methods in\nNumber Theory Using Sage', 'William Stein', 'manual'), ] - diff --git a/src/doc/en/thematic_tutorials/numerical_sage/conf.py b/src/doc/en/thematic_tutorials/numerical_sage/conf.py index 08e174fde3b..5772289f6fa 100644 --- a/src/doc/en/thematic_tutorials/numerical_sage/conf.py +++ b/src/doc/en/thematic_tutorials/numerical_sage/conf.py @@ -40,4 +40,3 @@ ('index', name + '.tex', 'Numerical Computing with Sage', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/tutorial/conf.py b/src/doc/en/tutorial/conf.py index b2b525d2c2a..8a4f626f440 100644 --- a/src/doc/en/tutorial/conf.py +++ b/src/doc/en/tutorial/conf.py @@ -36,4 +36,3 @@ ('index', 'sage_tutorial.tex', 'Tutorial', 'The Sage Development Team', 'manual'), ] - diff --git a/src/doc/en/website/conf.py b/src/doc/en/website/conf.py index 1f7847b232a..099a10865c4 100644 --- a/src/doc/en/website/conf.py +++ b/src/doc/en/website/conf.py @@ -43,4 +43,3 @@ html_additional_pages = { 'index': 'index_furo.html' if html_theme == 'furo' else 'index.html', } - diff --git a/src/doc/fr/tutorial/conf.py b/src/doc/fr/tutorial/conf.py index b23aaf6841c..7208ddada17 100644 --- a/src/doc/fr/tutorial/conf.py +++ b/src/doc/fr/tutorial/conf.py @@ -45,4 +45,3 @@ # the definition of \\at in the standard preamble of the sphinx doc # conflicts with that in babel/french[b] latex_elements['preamble'] += '\\let\\at\\undefined' - diff --git a/src/doc/ru/tutorial/conf.py b/src/doc/ru/tutorial/conf.py index c237e769ed4..0b7a8c4e3db 100644 --- a/src/doc/ru/tutorial/conf.py +++ b/src/doc/ru/tutorial/conf.py @@ -41,4 +41,3 @@ # Additional LaTeX stuff if necessary: #latex_elements['preamble'] += '\\DeclareUnicodeCharacter{00A0}{\\nobreakspace}\n' - diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py index adb526f1c78..f969a1b516a 100644 --- a/src/doc/tr/a_tour_of_sage/conf.py +++ b/src/doc/tr/a_tour_of_sage/conf.py @@ -35,7 +35,6 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('index', name+'.tex', 'Sage Turu', + ('index', name + '.tex', 'Sage Turu', 'The Sage Development Team', 'manual'), ] - diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 245fce04aeb..4c880cdca63 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -196,6 +196,7 @@ def sphinx_plot(graphics, **kwds): # Cross-links to other project's online documentation. python_version = sys.version_info.major + def set_intersphinx_mappings(app, config): """ Add precompiled inventory (the objects.inv) @@ -207,7 +208,7 @@ def set_intersphinx_mappings(app, config): app.config.intersphinx_mapping = {} return - app.config.intersphinx_mapping = { + app.config.intersphinx_mapping = { 'python': ('https://docs.python.org/', os.path.join(SAGE_DOC_SRC, "common", "python{}.inv".format(python_version))), @@ -232,6 +233,7 @@ def set_intersphinx_mappings(app, config): intersphinx.normalize_intersphinx_mapping(app, config) + # By default document are not master. multidocs_is_master = True @@ -819,6 +821,7 @@ def nitpick_patch_config(app): '__builtin__', ] + def check_nested_class_picklability(app, what, name, obj, skip, options): """ Print a warning if pickling is broken for nested classes. @@ -878,6 +881,7 @@ class will be properly documented inside its surrounding class. return skip + # This replaces the setup() in sage.misc.sagedoc_conf def setup(app): app.connect('autodoc-process-docstring', process_docstring_cython) @@ -904,4 +908,3 @@ def setup(app): app.connect('missing-reference', find_sage_dangling_links) app.connect('builder-inited', nitpick_patch_config) app.connect('html-page-context', add_page_context) - diff --git a/src/tox.ini b/src/tox.ini index b54938f74e3..e534e4a6d3f 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -106,10 +106,11 @@ description = # E713 test for membership should be 'not in' # E721: do not compare types, use isinstance() # E722: do not use bare except, specify exception instead + # W391: blank line at end of file # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E306,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E306,E401,E701,E702,E703,W391,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} pycodestyle --select E111,E401,E703,E712,E713,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] From c6bbbc38d92468035a2d3d0bab9842a4defca7d4 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 30 Sep 2022 01:30:56 +0800 Subject: [PATCH 233/350] add more EllipticCurveHom methods to EllipticCurveHom_velusqrt --- .../schemes/elliptic_curves/hom_velusqrt.py | 192 ++++++++++++++++-- 1 file changed, 180 insertions(+), 12 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 043edcd7399..1c93950e6db 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -104,12 +104,6 @@ ... NotImplementedError: only implemented for elliptic curves over finite fields -.. NOTE:: - - Currently :class:`EllipticCurveHom_velusqrt` does not implement - all methods of :class:`EllipticCurveHom`. This will hopefully - change in the future. - AUTHORS: - Lorenz Panny (2022) @@ -128,6 +122,8 @@ from sage.structure.sequence import Sequence from sage.structure.all import coercion_model as cm +from sage.misc.cachefunc import cached_method + from sage.misc.misc_c import prod from sage.structure.richcmp import op_EQ @@ -527,7 +523,7 @@ def __init__(self, E, n, P, Q=None): IJK = _choose_IJK(2*n+1) # [1,3,5,7,...,2n-1] = [0,1,2,3,...,n-2,n-1] self.base = E.base_ring() - R, Z = self.base['x'].objgen() + R, Z = self.base['Z'].objgen() # Cassels, Lectures on Elliptic Curves, p.132 A,B = E.a_invariants()[-2:] @@ -595,6 +591,7 @@ def __call__(self, alpha, *, derivative=False): R = self._hI_resultant(EJ, EJrems) hK = self.hK(alpha) res = hK * R / self.DeltaIJ + res = base(res) if not derivative: return res @@ -609,6 +606,7 @@ def __call__(self, alpha, *, derivative=False): dR = 0 dhK = self.dhK(alpha) dres = (dhK * R + hK * dR) / self.DeltaIJ + dres = base(dres) return res, dres @@ -629,7 +627,7 @@ def _hI_resultant(self, poly, rems=None): sage: E = EllipticCurve(GF(71), [5,5]) sage: P = E(4, 35) sage: hP = FastEllipticPolynomial(E, P.order(), P) - sage: f = GF(71)['x']([5,4,3,2,1]) + sage: f = GF(71)['Z']([5,4,3,2,1]) sage: hP._hI_resultant(f) 66 sage: prod(f(r) for fi in hP.hItree.layers[0] @@ -640,7 +638,7 @@ def _hI_resultant(self, poly, rems=None): sage: Q = E(0, 17) sage: hPQ = FastEllipticPolynomial(E, P.order(), P, Q) - sage: f = GF(71)['x']([9,8,7,6,5,4,3,2,1]) + sage: f = GF(71)['Z']([9,8,7,6,5,4,3,2,1]) sage: hPQ._hI_resultant(f) 36 sage: prod(f(r) for fi in hPQ.hItree.layers[0] @@ -918,7 +916,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): EE = self._Q.curve() self._P = EE(self._P) - self._base_ring = EE.base_ring() + self._internal_base_ring = EE.base_ring() self._h0 = FastEllipticPolynomial(EE, self._degree, self._P) self._h1 = FastEllipticPolynomial(EE, self._degree, self._P, self._Q) @@ -972,6 +970,13 @@ def _raw_eval(self, x, y=None): 50907 sage: phi._raw_eval(123, 456) (3805, 29941) + + TESTS:: + + sage: {t.parent() for t in phi._raw_eval(*Q.xy())} + {Finite Field of size 65537} + sage: {t.parent() for t in phi._raw_eval(123, 456)} + {Finite Field of size 65537} """ if y is None: h0 = self._h0(x) @@ -1041,7 +1046,7 @@ def _compute_codomain(self, model=None): From: Elliptic Curve defined by y^2 + 3*t*x*y + (3*t+2)*y = x^3 + (2*t+4)*x^2 + (t+4)*x + 3*t over Finite Field in t of size 5^2 To: Elliptic Curve defined by y^2 = x^3 + (4*t+3)*x + 2 over Finite Field in t of size 5^2 """ - R, Z = self._base_ring['Z'].objgen() + R, Z = self._internal_base_ring['Z'].objgen() poly = self._raw_domain.two_division_polynomial().monic()(Z) f = 1 @@ -1049,7 +1054,7 @@ def _compute_codomain(self, model=None): if g.degree() == 1: f *= Z - self._raw_eval(-g[0]) else: - K, X0 = self._base_ring.extension(g,'T').objgen() + K, X0 = self._internal_base_ring.extension(g,'T').objgen() imX0 = self._raw_eval(X0) try: imX0 = imX0.polynomial() # K is a FiniteField @@ -1193,6 +1198,169 @@ def _comparison_impl(left, right, op): return NotImplemented return compare_via_evaluation(left, right) + @cached_method + def kernel_polynomial(self): + r""" + Return the kernel polynomial of this √élu isogeny. + + .. NOTE:: + + The data returned by this method has size linear in the degree. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(65537^2,'a'), [5,5]) + sage: K = E.cardinality()//31 * E.gens()[0] + sage: phi = E.isogeny(K, algorithm='velusqrt') + sage: h = phi.kernel_polynomial(); h + x^15 + 21562*x^14 + 8571*x^13 + 20029*x^12 + 1775*x^11 + 60402*x^10 + 17481*x^9 + 46543*x^8 + 46519*x^7 + 18590*x^6 + 36554*x^5 + 36499*x^4 + 48857*x^3 + 3066*x^2 + 23264*x + 53937 + sage: h == E.isogeny(K).kernel_polynomial() + True + sage: h(K.xy()[0]) + 0 + + TESTS:: + + sage: phi.kernel_polynomial().parent() + Univariate Polynomial Ring in x over Finite Field in a of size 65537^2 + """ + R,x = self._domain.base_ring()['x'].objgen() + h = self._h0(x) + h = h(self._pre_iso.x_rational_map()) + return R(h).monic() + + @cached_method + def dual(self): + r""" + Return the dual of this √élu isogeny as an :class:`EllipticCurveHom`. + + .. NOTE:: + + The dual is computed by :class:`EllipticCurveIsogeny`, + hence it does not benefit from the √élu speedup. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) + sage: K = E.cardinality()//11 * E.gens()[0] + sage: phi = E.isogeny(K, algorithm='velusqrt'); phi + Elliptic-curve isogeny (using √élu) of degree 11: + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 + To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 + sage: phi.dual() + Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 + sage: phi.dual() * phi == phi.domain().multiplication_by_m_isogeny(11) + True + sage: phi * phi.dual() == phi.codomain().multiplication_by_m_isogeny(11) + True + """ + #FIXME This code fails if the degree is divisible by the characteristic. + F = self._raw_domain.base_ring() + from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism + isom = ~WeierstrassIsomorphism(self._raw_domain, (~F(self._degree), 0, 0, 0)) + from sage.schemes.elliptic_curves.ell_curve_isogeny import EllipticCurveIsogeny + phi = EllipticCurveIsogeny(self._raw_codomain, None, isom.domain(), self._degree) + return ~self._pre_iso * isom * phi * ~self._post_iso + + @cached_method + def rational_maps(self): + r""" + Return the pair of explicit rational maps of this √élu isogeny + as fractions of bivariate polynomials in `x` and `y`. + + .. NOTE:: + + The data returned by this method has size linear in the degree. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) + sage: K = E.cardinality()//11 * E.gens()[0] + sage: phi = E.isogeny(K, algorithm='velusqrt'); phi + Elliptic-curve isogeny (using √élu) of degree 11: + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 + To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 + sage: phi.rational_maps() + ((-17*x^11 - 34*x^10 - 36*x^9 + ... - 29*x^2 - 25*x - 25)/(x^10 + 10*x^9 + 19*x^8 - ... + x^2 + 47*x + 24), + (-3*x^16 - 6*x^15*y - 48*x^15 + ... - 49*x - 9*y + 46)/(x^15 + 15*x^14 - 35*x^13 - ... + 3*x^2 - 45*x + 47)) + + TESTS:: + + sage: phi.rational_maps()[0].parent() + Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field in z2 of size 101^2 + sage: phi.rational_maps()[1].parent() + Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field in z2 of size 101^2 + """ + S = self._internal_base_ring['x,y'] + fx, fy = map(S, self._pre_iso.rational_maps()) + fx, fy = self._raw_eval(fx, fy) + gx, gy = self._post_iso.rational_maps() + fx, fy = gx(fx, fy), gy(fx, fy) + R = self._domain.base_ring()['x,y'].fraction_field() + return R(fx), R(fy) + + @cached_method + def x_rational_map(self): + r""" + Return the `x`-coordinate rational map of this √élu isogeny + as a univariate rational expression in `x`. + + .. NOTE:: + + The data returned by this method has size linear in the degree. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) + sage: K = E.cardinality()//11 * E.gens()[0] + sage: phi = E.isogeny(K, algorithm='velusqrt'); phi + Elliptic-curve isogeny (using √élu) of degree 11: + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 + To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 + sage: phi.x_rational_map() + (84*x^11 + 67*x^10 + 65*x^9 + ... + 72*x^2 + 76*x + 76)/(x^10 + 10*x^9 + 19*x^8 + ... + x^2 + 47*x + 24) + sage: phi.x_rational_map() == phi.rational_maps()[0] + True + + TESTS:: + + sage: phi.x_rational_map().parent() + Fraction Field of Univariate Polynomial Ring in x over Finite Field in z2 of size 101^2 + """ + S = self._internal_base_ring['x'] + fx = S(self._pre_iso.x_rational_map()) + fx = self._raw_eval(fx) + gx = self._post_iso.x_rational_map() + fx = gx(fx) + R = self._domain.base_ring()['x'].fraction_field() + return R(fx) + + def scaling_factor(self): + r""" + Return the Weierstrass scaling factor associated to this + √élu isogeny. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this isogeny and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) + sage: K = E.cardinality()//11 * E.gens()[0] + sage: phi = E.isogeny(K, algorithm='velusqrt', model='montgomery'); phi + Elliptic-curve isogeny (using √élu) of degree 11: + From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 + To: Elliptic Curve defined by y^2 = x^3 + 61*x^2 + x over Finite Field in z2 of size 101^2 + sage: phi.scaling_factor() + 55 + sage: phi.scaling_factor() == phi.formal()[1] + True + """ + return self._pre_iso.scaling_factor() * self._post_iso.scaling_factor() + def _random_example_for_testing(): r""" From 1e2f16b63fc7620e15166893ee369ca3e0d937b3 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 30 Sep 2022 13:05:17 +0100 Subject: [PATCH 234/350] forbid pari 2.15.* and higher from the system: #34496 --- build/pkgs/pari/spkg-configure.m4 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build/pkgs/pari/spkg-configure.m4 b/build/pkgs/pari/spkg-configure.m4 index 9721849e7ba..b864d72118e 100644 --- a/build/pkgs/pari/spkg-configure.m4 +++ b/build/pkgs/pari/spkg-configure.m4 @@ -1,6 +1,7 @@ SAGE_SPKG_CONFIGURE([pari], [ dnl See gp_version below on how the version is computed from MAJV.MINV.PATCHV - m4_pushdef([SAGE_PARI_MINVER],["134401"]) + m4_pushdef([SAGE_PARI_MINVER],["134401"])dnl this version and higher allowed + m4_pushdef([SAGE_PARI_MAXVER],["134912"])dnl this version and higher not allowed SAGE_SPKG_DEPCHECK([gmp readline], [ AC_PATH_PROG([GP], [gp]) if test x$GP = x; then dnl GP test @@ -101,6 +102,7 @@ SAGE_SPKG_CONFIGURE([pari], [ [AC_MSG_RESULT([cross compiling. Assume they match])]) AC_MSG_CHECKING([is GP's version good enough? ]) AX_COMPARE_VERSION([$gp_version], [ge], [$SAGE_PARI_MINVER], [ + AX_COMPARE_VERSION([$gp_version], [lt], [$SAGE_PARI_MAXVER], [ AC_MSG_RESULT([yes]) AC_MSG_CHECKING([getting GP's datadir]) gp_datadir=`echo "default(datadir)" | $GP -qf 2>> config.log` @@ -127,13 +129,17 @@ SAGE_SPKG_CONFIGURE([pari], [ [AC_MSG_RESULT([libpari's datadir does not match GP's datadir. Not good]) sage_spkg_install_pari=yes], [AC_MSG_RESULT([cross compiling. Assume yes])]) - ], [ + ], [dnl compared maxver + AC_MSG_RESULT([no]) + sage_spkg_install_pari=yes], [AC_MSG_RESULT([cross compiling. Assume yes])]) + ], [dnl compared minver AC_MSG_RESULT([no]) sage_spkg_install_pari=yes], [AC_MSG_RESULT([cross compiling. Assume yes])]) AC_LANG_POP() ], [sage_spkg_install_pari=yes]) fi dnl end main PARI test ]) + m4_popdef([SAGE_PARI_MAXVER]) m4_popdef([SAGE_PARI_MINVER]) ], [], [], [ if test x$sage_spkg_install_pari = xyes; then From 4fc981b458f8d628684decf221618911ace06333 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 30 Sep 2022 15:08:41 +0200 Subject: [PATCH 235/350] fix for pyflakes and blocks --- src/sage/rings/lazy_series.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index c9d2198bbf7..16513a25ad7 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -217,7 +217,6 @@ from sage.arith.functions import lcm from sage.arith.misc import divisors, moebius from sage.combinat.partition import Partition, Partitions -from sage.misc.misc_c import prod from sage.misc.derivative import derivative_parse from sage.rings.infinity import infinity from sage.rings.integer_ring import ZZ @@ -3899,7 +3898,7 @@ def compute_coefficients(self, i): def _im_gens_(self, codomain, im_gens, base_map=None): """ - Returns the image of ``self`` under the map that sends the + Return the image of ``self`` under the map that sends the generators of the parent of ``self`` to the elements of the tuple ``im_gens``. From 79ce7d94e90fe60d96d5d233a26611700319efca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 17:37:33 +0200 Subject: [PATCH 236/350] use libgap in elements of dual abelian groups --- .../abelian_gps/dual_abelian_group_element.py | 105 ++++-------------- 1 file changed, 21 insertions(+), 84 deletions(-) diff --git a/src/sage/groups/abelian_gps/dual_abelian_group_element.py b/src/sage/groups/abelian_gps/dual_abelian_group_element.py index aaabe107781..dcd08e5c4fa 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group_element.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group_element.py @@ -41,7 +41,6 @@ - Volker Braun (2012-11) port to new Parent base. Use tuples for immutables. Default to cyclotomic base ring. """ - # **************************************************************************** # Copyright (C) 2006 William Stein # Copyright (C) 2006 David Joyner @@ -53,62 +52,22 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - -import operator - from sage.arith.all import LCM from sage.misc.misc_c import prod from sage.groups.abelian_gps.element_base import AbelianGroupElementBase -from functools import reduce -def add_strings(x, z=0): - """ - This was in sage.misc.misc but commented out. Needed to add - lists of strings in the word_problem method below. - - Return the sum of the elements of x. If x is empty, - return z. - - INPUT: - - - ``x`` -- iterable - - - ``z`` -- the ``0`` that will be returned if ``x`` is empty. - - OUTPUT: - - The sum of the elements of ``x``. - - EXAMPLES:: - - sage: from sage.groups.abelian_gps.dual_abelian_group_element import add_strings - sage: add_strings([], z='empty') - 'empty' - sage: add_strings(['a', 'b', 'c']) - 'abc' - """ - if len(x) == 0: - return z - if not isinstance(x, list): - m = iter(x) - y = next(m) - return reduce(operator.add, m, y) - else: - return reduce(operator.add, x[1:], x[0]) - - -def is_DualAbelianGroupElement(x): +def is_DualAbelianGroupElement(x) -> bool: """ Test whether ``x`` is a dual Abelian group element. INPUT: - - ``x`` -- anything. + - ``x`` -- anything OUTPUT: - Boolean. + Boolean EXAMPLES:: @@ -169,10 +128,10 @@ def __call__(self, g): N = LCM(order) order_not = [N / o for o in order] zeta = F.zeta(N) - return F.prod(zeta ** (expsX[i] * expsg[i] * order_not[i]) + return F.prod(zeta**(expsX[i] * expsg[i] * order_not[i]) for i in range(len(expsX))) - def word_problem(self, words, display=True): + def word_problem(self, words): """ This is a rather hackish method and is included for completeness. @@ -196,43 +155,21 @@ def word_problem(self, words, display=True): sage: w = a^7*b^3*c^5*d^4*e^4 sage: x = a^3*b^2*c^2*d^3*e^5 sage: y = a^2*b^4*c^2*d^4*e^5 - sage: e.word_problem([u,v,w,x,y],display=False) + sage: e.word_problem([u,v,w,x,y]) [[b^2*c^2*d^3*e^5, 245]] - - The command e.word_problem([u,v,w,x,y],display=True) returns - the same list but also prints ``e = (b^2*c^2*d^3*e^5)^245``. """ - ## First convert the problem to one using AbelianGroups - import copy - from sage.groups.abelian_gps.abelian_group import AbelianGroup - from sage.interfaces.gap import gap - M = self.parent() - G = M.group() - gens = M.variable_names() - g = prod([G.gen(i)**(self.list()[i]) for i in range(G.ngens())]) - gap.eval("l:=One(Rationals)") ## trick needed for LL line below to keep Sage from parsing - s1 = "gens := GeneratorsOfGroup(%s)"%G._gap_init_() - gap.eval(s1) - for i in range(len(gens)): - cmd = ("%s := gens["+str(i+1)+"]") % gens[i] - gap.eval(cmd) - s2 = "g0:=%s; gensH:=%s" % (str(g), words) - gap.eval(s2) - s3 = 'G:=Group(gens); H:=Group(gensH)' - gap.eval(s3) - phi = gap.eval("hom:=EpimorphismFromFreeGroup(H)") - l1 = gap.eval("ans:=PreImagesRepresentative(hom,g0)") - l2 = copy.copy(l1) - l4 = [] - l3 = l1.split("*") - for i in range(1,len(words)+1): - l2 = l2.replace("x"+str(i),"("+str(words[i-1])+")") - l3 = eval(gap.eval("L3:=ExtRepOfObj(ans)")) - nn = eval(gap.eval("n:=Int(Length(L3)/2)")) - LL1 = eval(gap.eval("L4:=List([l..n],i->L3[2*i])")) ## note the l not 1 - LL2 = eval(gap.eval("L5:=List([l..n],i->L3[2*i-1])")) ## note the l not 1 - if display: - s = str(g)+" = "+add_strings(["("+str(words[LL2[i]-1])+")^"+str(LL1[i])+"*" for i in range(nn)]) - m = len(s) - print(" ", s[:m-1], "\n") - return [[words[LL2[i]-1],LL1[i]] for i in range(nn)] + from sage.libs.gap.libgap import libgap + A = libgap.AbelianGroup(self.parent().gens_orders()) + gens = A.GeneratorsOfGroup() + gap_g = libgap.Product([gi**Li for gi, Li in zip(gens, self.list())]) + gensH = [libgap.Product([gi**Li for gi, Li in zip(gens, w.list())]) + for w in words] + H = libgap.Group(gensH) + + hom = H.EpimorphismFromFreeGroup() + ans = hom.PreImagesRepresentative(gap_g) + + resu = ans.ExtRepOfObj().sage() # (indice, power, indice, power, etc) + indices = resu[0::2] + powers = resu[1::2] + return [[words[indi - 1], powi] for indi, powi in zip(indices, powers)] From 5b787492299e3eca7636abd43d4b5cf5e99847b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 21:22:01 +0200 Subject: [PATCH 237/350] fix some details in doc of charpoly_frobenius --- .../cyclic_covers/charpoly_frobenius.py | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py index 3e892e31fde..4c63fe44783 100644 --- a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py +++ b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py @@ -1,16 +1,11 @@ r""" - Computation of the Frobenius polynomial using Newton's identities - """ - - # ***************************************************************************** # Copyright (C) 2018 Edgar Costa # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ # ***************************************************************************** - from sage.rings.integer_ring import ZZ from sage.functions.log import log @@ -23,15 +18,15 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= - ``frob_matrix`` -- a matrix representing the Frobenius matrix up to some precision - - ``charpoly_prec`` -- a vector ai, such that, `frob_matrix.change_ring(ZZ).charpoly()[i]` - will be correct mod `p^ai`, this can be easily deduced from the Hodge numbers and - knowing the q-adic precision of ``frob_matrix`` + - ``charpoly_prec`` -- a vector ai, such that, ``frob_matrix.change_ring(ZZ).charpoly()[i]`` + will be correct mod `p^ai`, this can be easily deduced from the + Hodge numbers and knowing the q-adic precision of ``frob_matrix`` - ``p`` -- prime `p` - ``weight`` -- weight of the motive - - ``a`` -- `q = q^a` + - ``a`` -- `p = q^a` - ``known_factor`` -- the list of coefficients of the known factor @@ -195,14 +190,12 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= sage: F+= F.base_ring()(0).add_bigoh(6)*ones_matrix(*F.dimensions()) sage: charpoly_frobenius(F, [6, 5, 4, 4], 17, 2) [-4913, -221, 13, 1] - - """ assert known_factor[-1] == 1 try: cp = frob_matrix.change_ring(ZZ).charpoly().list() except ValueError: - # the given matrix wasn't integral + # the given matrix was not integral cp = frob_matrix.charpoly().change_ring(ZZ).list() assert len(charpoly_prec) == len(cp) - (len(known_factor) - 1) assert cp[-1] == 1 @@ -216,7 +209,7 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= # figure out the sign # i.e., if it is a reciprocal or an antireciprocal polynomial - if weight % 2 == 1: + if weight % 2: # for odd weight the sign is always 1 # it's the charpoly of a USp matrix # and charpoly of a symplectic matrix is reciprocal @@ -227,7 +220,7 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= raise NotImplementedError() # we compare ith coefficient and (degree - i)th coefficient to deduce the sign # note, if degree is even, the middle coefficient will not help us determine the sign - for i in range((degree + 1)//2): + for i in range((degree + 1) // 2): # Note: degree*weight is even p_power = p**min( charpoly_prec[i], @@ -248,19 +241,21 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= # note, this includes the middle coefficient if degree is even halfdegree = degree // 2 + 1 - cp[0] = sign * p**((a * degree * weight) // 2) # Note: degree*weight is even + cp[0] = sign * p**((a * degree * weight) // 2) + # Note: degree*weight is even + # calculate the i-th power sum of the roots and correct cp along the way e = cp[-halfdegree:] e.reverse() for k in range(halfdegree): - if k % 2 != 0: + if k % 2: e[k] = -e[k] % mod[degree - k] # e[k] = cp[degree - k] if (k%2 ==0) else -cp[degree - k] if k > 0: # verify if p^charpoly_prec[degree - k] > 2*degree/k * q^(w*k/2) assert ( - log(k) / log(p) + charpoly_prec[degree - k] - > log(2 * degree) / log(p) + a * 0.5 * weight * k + log(k, p) + charpoly_prec[degree - k] + > log(2 * degree, p) + a * 0.5 * weight * k ), ( "log(k)/log(p) + charpoly_prec[degree - k] <= log(2*degree)/log(p) + a*0.5*weight*k, k = %d" % k @@ -271,7 +266,7 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= if len(fix_e) < halfdegree: fix_e.extend([0] * (halfdegree - len(fix_e))) for i in range(halfdegree): - if i % 2 != 0: + if i % 2: fix_e[i] *= -1 # e[k] = \sum x_{i_1} x_{i_2} ... x_{i_k} # where x_* are eigenvalues @@ -280,7 +275,9 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= # s[k] = \sum x_i ^k for k>0 s = [None] * (halfdegree) res = [None] * len(charpoly_prec) - res[0] = sign * p**((a * degree * weight) // 2) # Note: degree*weight is even + res[0] = sign * p**((a * degree * weight) // 2) + # Note: degree*weight is even + res[-1] = 1 e[1] -= fix_e[1] e[1] = e[1] % mod[degree - 1] @@ -306,8 +303,9 @@ def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor= # (-1)^(k-1) s[k] - S = k*e[k] e[k] = (-S + (-1)**(k - 1) * s[k]) // k assert (-S + (-1)**(k - 1) * s[k]) % k == 0 - res[degree - k] = e[k] if k % 2 == 0 else -e[k] + res[degree - k] = e[k] if not k % 2 else -e[k] # Note: degree*weight is even + res[k] = sign * res[degree - k] * p**((a * (degree - 2 * k) * weight) // 2) # fix e[k + 1] if k + 1 < halfdegree: From 402bec3604c2276639e17cbee27cc0a6e9c4abf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 21:34:19 +0200 Subject: [PATCH 238/350] fix a bunch of similar errors in the doc --- src/sage/categories/additive_magmas.py | 2 +- src/sage/categories/category.py | 2 +- src/sage/categories/coxeter_groups.py | 2 +- src/sage/categories/crystals.py | 12 ++++++++---- src/sage/coding/cyclic_code.py | 2 +- src/sage/crypto/block_cipher/present.py | 4 ++-- src/sage/dynamics/finite_dynamical_system_catalog.py | 2 +- src/sage/graphs/weakly_chordal.pyx | 4 ++-- src/sage/matrix/matrix_misc.py | 4 ++-- src/sage/symbolic/function.pyx | 2 +- 10 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index cf2fdf242b9..8d2c46d0771 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -730,7 +730,7 @@ def is_empty(self): TESTS: - We check that the method `is_empty` is inherited from this + We check that the method ``is_empty`` is inherited from this category in both examples above:: sage: A.is_empty.__module__ diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index eef5e7acc70..02f4b292f42 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -2236,7 +2236,7 @@ def _sort(categories): .. NOTE:: - The auxiliary function `_flatten_categories` used in the test + The auxiliary function ``_flatten_categories`` used in the test below expects a second argument, which is a type such that instances of that type will be replaced by its super categories. Usually, this type is :class:`JoinCategory`. diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 0aacd2aeda5..c4f4cdab349 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -668,7 +668,7 @@ def _test_reduced_word(self, **options): def simple_projection(self, i, side='right', length_increasing=True): r""" - Return the simple projection `\pi_i` (or `\overline\pi_i` if `length_increasing` is ``False``). + Return the simple projection `\pi_i` (or `\overline\pi_i` if ``length_increasing`` is ``False``). INPUT: diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index 1cfbf9175ab..32fad8ee75f 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -1563,7 +1563,9 @@ def to_highest_weight(self, index_set=None): r""" Return the highest weight element `u` and a list `[i_1,...,i_k]` such that `self = f_{i_1} ... f_{i_k} u`, where `i_1,...,i_k` are - elements in `index_set`. By default the index set is assumed to be + elements in ``index_set``. + + By default the index set is assumed to be the full index set of self. EXAMPLES:: @@ -1602,8 +1604,10 @@ def to_lowest_weight(self, index_set=None): r""" Return the lowest weight element `u` and a list `[i_1,...,i_k]` such that `self = e_{i_1} ... e_{i_k} u`, where `i_1,...,i_k` are - elements in `index_set`. By default the index set is assumed to be - the full index set of self. + elements in ``index_set``. + + By default the index set is assumed to be the full index + set of self. EXAMPLES:: @@ -1642,7 +1646,7 @@ def to_lowest_weight(self, index_set=None): def all_paths_to_highest_weight(self, index_set=None): r""" Iterate over all paths to the highest weight from ``self`` - with respect to `index_set`. + with respect to ``index_set``. INPUT: diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index a5c3a4c88fb..f47c5433d3e 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -334,7 +334,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, ... ValueError: The code is not cyclic. - If the `primitive_root` does not lie in an extension of `field`, + If the ``primitive_root`̀ does not lie in an extension of ``field``, or is not a primitive `n`-th root of unity, then an exception is raised:: diff --git a/src/sage/crypto/block_cipher/present.py b/src/sage/crypto/block_cipher/present.py index 4cbb74fc241..1774e6d5977 100644 --- a/src/sage/crypto/block_cipher/present.py +++ b/src/sage/crypto/block_cipher/present.py @@ -838,7 +838,7 @@ def __getitem__(self, r): Computes the sub key for round ``r`` derived from initial master key. The key schedule object has to have been initialised with the - `master_key` argument. + ``master_key`` argument. INPUT: @@ -860,7 +860,7 @@ def __getitem__(self, r): def __iter__(self): """ Iterate over the ``self._rounds + 1`` PRESENT round keys, derived from - `master_key` + ``master_key``. EXAMPLES:: diff --git a/src/sage/dynamics/finite_dynamical_system_catalog.py b/src/sage/dynamics/finite_dynamical_system_catalog.py index 3ba09eb9948..74217178a29 100755 --- a/src/sage/dynamics/finite_dynamical_system_catalog.py +++ b/src/sage/dynamics/finite_dynamical_system_catalog.py @@ -5,7 +5,7 @@ dynamical systems. These are accessible through :mod:`sage.dynamics.finite_dynamical_system_catalog. ` -or just through `finite_dynamical_systems.` +or just through ``finite_dynamical_systems.`` (type either of these in Sage and hit ``tab`` for a list). AUTHORS: diff --git a/src/sage/graphs/weakly_chordal.pyx b/src/sage/graphs/weakly_chordal.pyx index 45c692d8955..79e574fc4f5 100644 --- a/src/sage/graphs/weakly_chordal.pyx +++ b/src/sage/graphs/weakly_chordal.pyx @@ -53,7 +53,7 @@ cdef inline is_long_hole_free_process(g, short_digraph sd, bitset_t dense_graph, bint certificate, int a, int b, int c, int n): """ - This method is part of method `is_long_hole_free`. + This method is part of method ``is_long_hole_free``. EXAMPLES:: @@ -285,7 +285,7 @@ cdef inline is_long_antihole_free_process(g, short_digraph sd, bitset_t dense_gr bint certificate, int a, int b, int c, int n): """ - This method is part of method `is_long_antihole_free`. + This method is part of method ``is_long_antihole_free``. EXAMPLES:: diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index e68ba3ad0bc..859620ae2f2 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -39,10 +39,10 @@ def prm_mul(p1, p2, mask_free, prec): - `p1,p2` -- polynomials as dictionaries - - `mask_free` -- an integer mask that give the list of free variables + - ``mask_free`` -- an integer mask that give the list of free variables (the `i`-th variable is free if the `i`-th bit of ``mask_free`` is `1`) - - `prec` -- if `prec` is not None, truncate the product at precision `prec` + - ``prec`` -- if ``prec`` is not ``None``, truncate the product at precision ``prec`` EXAMPLES:: diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 06e626c7748..0baedce69c0 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -502,7 +502,7 @@ cdef class Function(SageObject): sage: (out, parent(out)) (0, Integer Ring) - Check that `real_part` and `imag_part` still works after :trac:`21216`:: + Check that ``real_part`` and ``imag_part`` still works after :trac:`21216`:: sage: import numpy sage: a = numpy.array([1+2*I, -2-3*I], dtype=complex) From 9ee09dff6dbbf41b2c237a4a419995a6c6830ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 21:39:09 +0200 Subject: [PATCH 239/350] remove import --- src/sage/groups/abelian_gps/dual_abelian_group_element.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/groups/abelian_gps/dual_abelian_group_element.py b/src/sage/groups/abelian_gps/dual_abelian_group_element.py index dcd08e5c4fa..18fac135c94 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group_element.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group_element.py @@ -53,7 +53,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from sage.arith.all import LCM -from sage.misc.misc_c import prod from sage.groups.abelian_gps.element_base import AbelianGroupElementBase From f83a25d0400626a5561c76ec837e58abc8ac5262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 30 Sep 2022 21:53:29 +0200 Subject: [PATCH 240/350] pep cleanup for Weyl groups --- src/sage/combinat/root_system/weyl_group.py | 113 ++++++++++---------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 42aa218115c..efcdce97384 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -6,13 +6,11 @@ - Daniel Bump (2008): initial version - Mike Hansen (2008): initial version - Anne Schilling (2008): initial version -- Nicolas Thiery (2008): initial version +- Nicolas Thiéry (2008): initial version - Volker Braun (2013): LibGAP-based matrix groups EXAMPLES: -More examples on Weyl Groups should be added here... - The Cayley graph of the Weyl Group of type ['A', 3]:: sage: w = WeylGroup(['A',3]) @@ -26,8 +24,12 @@ sage: d = w.cayley_graph(); d Digraph on 192 vertices sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) #long time (less than one minute) + +.. TODO:: + + More examples on Weyl Groups should be added here. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Daniel Bump , # Mike Hansen # Anne Schilling @@ -35,8 +37,8 @@ # # Distributed under the terms of the GNU General Public License (GPL) # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_gap from sage.groups.matrix_gps.group_element import MatrixGroupElement_gap from sage.groups.perm_gps.permgroup import PermutationGroup_generic @@ -59,12 +61,12 @@ def WeylGroup(x, prefix=None, implementation='matrix'): """ - Returns the Weyl group of the root system defined by the Cartan + Return the Weyl group of the root system defined by the Cartan type (or matrix) ``ct``. INPUT: - - ``x`` - a root system or a Cartan type (or matrix) + - ``x`` -- a root system or a Cartan type (or matrix) OPTIONAL: @@ -236,7 +238,7 @@ def __init__(self, domain, prefix): category = WeylGroups() if self.cartan_type().is_irreducible(): category = category.Irreducible() - self.n = domain.dimension() # Really needed? + self.n = domain.dimension() # Really needed? self._prefix = prefix # FinitelyGeneratedMatrixGroup_gap takes plain matrices as input @@ -252,7 +254,7 @@ def __init__(self, domain, prefix): @cached_method def cartan_type(self): """ - Returns the CartanType associated to self. + Return the ``CartanType`` associated to ``self``. EXAMPLES:: @@ -265,7 +267,7 @@ def cartan_type(self): @cached_method def index_set(self): """ - Returns the index set of self. + Return the index set of ``self``. EXAMPLES:: @@ -289,7 +291,7 @@ def from_morphism(self, f): @cached_method def simple_reflections(self): """ - Returns the simple reflections of self, as a family. + Return the simple reflections of ``self``, as a family. EXAMPLES: @@ -393,13 +395,13 @@ def _repr_(self): Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) """ return "Weyl Group of type %s (as a matrix group acting on the %s)" % (self.cartan_type(), - self._domain._name_string(capitalize=False, - base_ring=False, - type=False)) + self._domain._name_string(capitalize=False, + base_ring=False, + type=False)) def character_table(self): """ - Returns the character table as a matrix + Return the character table as a matrix. Each row is an irreducible character. For larger tables you may preface this with a command such as @@ -421,14 +423,14 @@ def character_table(self): X.4 3 -1 1 . -1 X.5 1 1 1 1 1 """ - gens_str = ', '.join(str(g.gap()) for g in self.gens()) + gens_str = ', '.join(str(g.gap()) for g in self.gens()) ctbl = gap('CharacterTable(Group({0}))'.format(gens_str)) return ctbl.Display() @cached_method def one(self): """ - Returns the unit element of the Weyl group + Return the unit element of the Weyl group. EXAMPLES:: @@ -441,13 +443,13 @@ def one(self): sage: type(e) == W.element_class True """ - return self._element_constructor_(matrix(QQ,self.n,self.n,1)) + return self._element_constructor_(matrix(QQ, self.n, self.n, 1)) - unit = one # For backward compatibility + unit = one # For backward compatibility def domain(self): """ - Returns the domain of the element of ``self``, that is the + Return the domain of the element of ``self``, that is the root lattice realization on which they act. EXAMPLES:: @@ -463,7 +465,7 @@ def domain(self): def simple_reflection(self, i): """ - Returns the `i^{th}` simple reflection. + Return the `i^{th}` simple reflection. EXAMPLES:: @@ -485,7 +487,7 @@ def simple_reflection(self, i): def long_element_hardcoded(self): """ - Returns the long Weyl group element (hardcoded data) + Return the long Weyl group element (hardcoded data). Do we really want to keep it? There is a generic implementation which works in all cases. The hardcoded should @@ -497,22 +499,22 @@ def long_element_hardcoded(self): sage: types = [ ['A',5],['B',3],['C',3],['D',4],['G',2],['F',4],['E',6] ] sage: [WeylGroup(t).long_element().length() for t in types] [15, 9, 9, 12, 6, 24, 36] - sage: all( WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types ) # long time (17s on sage.math, 2011) + sage: all(WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types) # long time (17s on sage.math, 2011) True """ type = self.cartan_type() - if type[0] == 'D' and type[1]%2 == 1: - l = [-1 for i in range(self.n-1)] + if type[0] == 'D' and type[1] % 2: + l = [-1 for i in range(self.n - 1)] l.append(1) - m = diagonal_matrix(QQ,l) + m = diagonal_matrix(QQ, l) elif type[0] == 'A': l = [0 for k in range((self.n)**2)] - for k in range(self.n-1, (self.n)**2-1, self.n-1): + for k in range(self.n - 1, (self.n)**2 - 1, self.n - 1): l[k] = 1 m = matrix(QQ, self.n, l) elif type[0] == 'E': if type[1] == 6: - half = ZZ(1)/ZZ(2) + half = ZZ(1) / ZZ(2) l = [[-half, -half, -half, half, 0, 0, 0, 0], [-half, -half, half, -half, 0, 0, 0, 0], [-half, half, -half, -half, 0, 0, 0, 0], @@ -523,10 +525,10 @@ def long_element_hardcoded(self): [0, 0, 0, 0, -half, half, half, half]] m = matrix(QQ, 8, l) else: - raise NotImplementedError("Not implemented yet for this type") + raise NotImplementedError("not implemented yet for this type") elif type[0] == 'G': - third = ZZ(1)/ZZ(3) - twothirds = ZZ(2)/ZZ(3) + third = ZZ(1) / ZZ(3) + twothirds = ZZ(2) / ZZ(3) l = [[-third, twothirds, twothirds], [twothirds, -third, twothirds], [twothirds, twothirds, -third]] @@ -559,6 +561,7 @@ def classical(self): raise ValueError("classical subgroup only defined for affine types") return ClassicalWeylSubgroup(self._domain, prefix=self._prefix) + class ClassicalWeylSubgroup(WeylGroup_gens): """ A class for Classical Weyl Subgroup of an affine Weyl Group @@ -638,9 +641,9 @@ def __repr__(self): Parabolic Subgroup of the Weyl Group of type ['C', 4, 1]^* (as a matrix group acting on the coweight lattice) """ return "Parabolic Subgroup of the Weyl Group of type %s (as a matrix group acting on the %s)" % (self.domain().cartan_type(), - self._domain._name_string(capitalize=False, - base_ring=False, - type=False)) + self._domain._name_string(capitalize=False, + base_ring=False, + type=False)) def weyl_group(self, prefix="hereditary"): """ @@ -672,6 +675,7 @@ def _test_is_finite(self, **options): tester.assertTrue(not self.weyl_group(self._prefix).is_finite()) tester.assertTrue(self.is_finite()) + class WeylGroupElement(MatrixGroupElement_gap): """ Class for a Weyl Group elements @@ -705,7 +709,7 @@ def to_matrix(self): def domain(self): """ - Returns the ambient lattice associated with self. + Return the ambient lattice associated with ``self``. EXAMPLES:: @@ -789,8 +793,8 @@ def __eq__(self, other): purposes. """ return (self.__class__ == other.__class__ and - self._parent == other._parent and - self.matrix() == other.matrix()) + self._parent == other._parent and + self.matrix() == other.matrix()) def _richcmp_(self, other, op): """ @@ -835,15 +839,14 @@ def action(self, v): alpha[0] + alpha[1] """ if v not in self.domain(): - raise ValueError("{} is not in the domain".format(v)) - return self.domain().from_vector(self.matrix()*v.to_vector()) + raise ValueError(f"{v} is not in the domain") + return self.domain().from_vector(self.matrix() * v.to_vector()) - - ########################################################################## + # ####################################################################### # Descents - ########################################################################## + # ####################################################################### - def has_descent(self, i, positive=False, side = "right"): + def has_descent(self, i, positive=False, side="right"): """ Test if ``self`` has a descent at position ``i``. @@ -934,7 +937,7 @@ def has_left_descent(self, i): sage: [(s[3]*s[2]).has_left_descent(i) for i in W.domain().index_set()] [False, False, True] """ - return self.has_descent(i, side = "left") + return self.has_descent(i, side="left") def has_right_descent(self, i): """ @@ -957,13 +960,14 @@ def has_right_descent(self, i): """ return self.has_descent(i, side="right") - def apply_simple_reflection(self, i, side = "right"): + def apply_simple_reflection(self, i, side="right"): s = self.parent().simple_reflections() if side == "right": return self * s[i] else: return s[i] * self +# TODO # The methods first_descent, descents, reduced_word appear almost verbatim in # root_lattice_realizations and need to be factored out! @@ -978,9 +982,8 @@ def to_permutation(self): """ W = self.parent() e = W.domain().basis() - return tuple( c*(j+1) - for i in e.keys() - for (j,c) in self.action(e[i]) ) + return tuple(c * (j + 1) for i in e.keys() + for (j, c) in self.action(e[i])) def to_permutation_string(self): """ @@ -993,6 +996,7 @@ def to_permutation_string(self): """ return "".join(str(i) for i in self.to_permutation()) + WeylGroup_gens.Element = WeylGroupElement @@ -1025,13 +1029,12 @@ def __init__(self, cartan_type, prefix): """ self._cartan_type = cartan_type self._index_set = cartan_type.index_set() - self._index_set_inverse = {ii: i for i,ii in enumerate(cartan_type.index_set())} + self._index_set_inverse = {ii: i for i, ii in enumerate(cartan_type.index_set())} self._reflection_representation = None self._prefix = prefix - #from sage.libs.gap.libgap import libgap Q = cartan_type.root_system().root_lattice() Phi = list(Q.positive_roots()) + [-x for x in Q.positive_roots()] - p = [[Phi.index(x.weyl_action([i]))+1 for x in Phi] + p = [[Phi.index(x.weyl_action([i])) + 1 for x in Phi] for i in self._cartan_type.index_set()] cat = FiniteWeylGroups() if self._cartan_type.is_irreducible(): @@ -1207,7 +1210,7 @@ def reflection_index_set(self): sage: W.reflection_index_set() (1, 2, 3, 4, 5, 6) """ - return tuple(range(1, self.number_of_reflections()+1)) + return tuple(range(1, self.number_of_reflections() + 1)) def cartan_type(self): """ @@ -1301,9 +1304,9 @@ def distinguished_reflections(self): def build_elt(index): r = pos_roots[index] - perm = [Phi.index(x.reflection(r))+1 for x in Phi] + perm = [Phi.index(x.reflection(r)) + 1 for x in Phi] return self.element_class(perm, self, check=False) - return Family(self.reflection_index_set(), lambda i: build_elt(i-1)) + return Family(self.reflection_index_set(), lambda i: build_elt(i - 1)) reflections = distinguished_reflections From 98041eb7bcff7c4e16e01b3eb61cf45b94c718e4 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 1 Oct 2022 10:31:52 +0200 Subject: [PATCH 241/350] trac #34123: review commit --- src/sage/graphs/edge_connectivity.pyx | 39 ++++++++++++++++++++------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 83f1111c2bf..e39929dfffc 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -189,11 +189,11 @@ cdef class GabowEdgeConnectivity: cdef int num_start_f_trees # number of f-trees at the beginning of an iteration cdef int num_joins # number of joined vertices from dfs - cdef bint* T # whether the an edge is in the proven k-intersection + cdef bint* T # whether an edge is in the proven k-intersection cdef bint* visited # for method find_dfs_tree - cdef bint dfs_preprocessing # whether or not we should use DFS-based fast initialization cdef int * incident_edge_index # used for DFS initialization - cdef bint use_rec # variable to remove, used for development + cdef bint dfs_preprocessing # whether to use DFS-based fast initialization + cdef bint use_rec # whether to use the recursive DFS initialization def __init__(self, G, dfs_preprocessing=True, use_rec=False): r""" @@ -202,11 +202,15 @@ cdef class GabowEdgeConnectivity: INPUT: - ``G`` -- a :class:`~sage.graphs.digraph.DiGraph` + - ``dfs_preprocessing`` -- boolean (default: ``True``); indicates whether to - use the DFS-based "Fast initialization" provided in [GKLP2021]_ - - ``use_rec`` -- boolean (default: ``False``); indicates whether to use a - recursive or non-recursive DFS for ``dfs_preprocessing``. The recursive DFS - tends to be faster than the non-recursive version on complete digraphs + use the DFS-based speed-up initialization proposed in [GKLP2021]_ + + - ``use_rec`` -- boolean (default: ``False``); indicates whether to use + a recursive or non-recursive DFS for ``dfs_preprocessing``. The + recursive DFS tends to be faster than the non-recursive version on + complete digraphs and slower on other graphs. This parameter is + ignored when ``dfs_preprocessing`` is ``False``. EXAMPLES:: @@ -240,9 +244,11 @@ cdef class GabowEdgeConnectivity: self.m = G.size() self.mem = MemoryAllocator() - # Build compact graph data structure with out and in adjacencies + # Build compact graph data structure with out and in adjacencies. + # Loops are removed from the graph. self.build_graph_data_structure() # From now on, vertices are numbered in [0..n-1] and edges in [0..m-1] + # where m is the number of edges after the removal of the loops # Set upper bound on the edge connectivity cdef int i, d @@ -408,7 +414,7 @@ cdef class GabowEdgeConnectivity: cdef int z self.num_start_f_trees = self.n - self.num_joins - # There are fewer than n f-trees. We prepare to join them. If there's + # There are fewer than n f-trees. We prepare to join them. If there's # only one f-tree, we just save the edges and advance to the next # iteration if self.dfs_preprocessing and self.num_start_f_trees < self.n - 1: @@ -489,17 +495,23 @@ cdef class GabowEdgeConnectivity: r""" Find a DFS spanning forest of `G \backslash T`. + This is the DFS-based speed-up initialization proposed in [GKLP2021]_. + EXAMPLES:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = digraphs.Complete(5) - sage: GabowEdgeConnectivity(D).edge_connectivity() + sage: GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() + 4 + sage: GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() 4 """ # Mark all vertices as unvisited + cdef int i for i in range(self.n): self.visited[i] = False + cdef int r for r in range(self.n): if not self.visited[r]: # Make this vertex the root of the following dfs tree @@ -518,6 +530,9 @@ cdef class GabowEdgeConnectivity: r""" Find more vertices of the f-tree rooted at `r`. + This is part of the DFS-based speed-up initialization proposed in + [GKLP2021]_. + EXAMPLES:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity @@ -562,6 +577,9 @@ cdef class GabowEdgeConnectivity: r""" Find more vertices of the f-tree rooted at `r`. + This is part of the DFS-based speed-up initialization proposed in + [GKLP2021]_. + EXAMPLES:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity @@ -573,6 +591,7 @@ cdef class GabowEdgeConnectivity: self.visited[u] = True # Visit outgoing arcs of current vertex + cdef int e_id, v for e_id in self.my_g_reversed[u]: v = self.my_to[e_id] # Ensure a vertex is not visited, is not a proven k-intersection edge From 96e1cd92f12fc2f0d6dd813edad2ec49cfa2c33f Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 1 Oct 2022 10:36:58 +0200 Subject: [PATCH 242/350] trac #34123: extra care --- src/sage/graphs/edge_connectivity.pyx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index e39929dfffc..459ee90fe4f 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -69,14 +69,15 @@ cdef class GabowEdgeConnectivity: sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() 9 - :: + Check that we get the same result when with and without the DFS-based + speed-up initialization proposed in [GKLP2021]_:: sage: G = graphs.RandomBarabasiAlbert(100, 2) sage: D = DiGraph(G) - sage: GabowEdgeConnectivity(D).edge_connectivity() - 2 sage: GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() 2 + sage: GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() + 2 sage: GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() 2 @@ -203,11 +204,11 @@ cdef class GabowEdgeConnectivity: - ``G`` -- a :class:`~sage.graphs.digraph.DiGraph` - - ``dfs_preprocessing`` -- boolean (default: ``True``); indicates whether to - use the DFS-based speed-up initialization proposed in [GKLP2021]_ + - ``dfs_preprocessing`` -- boolean (default: ``True``); whether to use + the DFS-based speed-up initialization proposed in [GKLP2021]_ - - ``use_rec`` -- boolean (default: ``False``); indicates whether to use - a recursive or non-recursive DFS for ``dfs_preprocessing``. The + - ``use_rec`` -- boolean (default: ``False``); whether to use a + recursive or non-recursive DFS for ``dfs_preprocessing``. The recursive DFS tends to be faster than the non-recursive version on complete digraphs and slower on other graphs. This parameter is ignored when ``dfs_preprocessing`` is ``False``. From 0e88192afda9bfd7c551276380bc2dd76feadbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 1 Oct 2022 12:00:42 +0200 Subject: [PATCH 243/350] fix one detail --- src/sage/coding/cyclic_code.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index f47c5433d3e..93ce9730f49 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -47,6 +47,7 @@ from sage.misc.cachefunc import cached_method from sage.rings.all import Zmod + def find_generator_polynomial(code, check=True): r""" Returns a possible generator polynomial for ``code``. @@ -334,7 +335,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, ... ValueError: The code is not cyclic. - If the ``primitive_root`̀ does not lie in an extension of ``field``, + If the ``primitive_root`` does not lie in an extension of ``field``, or is not a primitive `n`-th root of unity, then an exception is raised:: @@ -1321,7 +1322,7 @@ def decoding_radius(self): return self._bch_decoder.decoding_radius() -####################### registration ############################### +# ###################### registration ############################## CyclicCode._registered_encoders["Polynomial"] = CyclicCodePolynomialEncoder CyclicCode._registered_encoders["Vector"] = CyclicCodeVectorEncoder From 373bd38ae25acadf3bbedc412b61541d65a718fb Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 1 Oct 2022 12:17:29 +0100 Subject: [PATCH 244/350] remove harmful \ --- build/pkgs/singular/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/singular/spkg-configure.m4 b/build/pkgs/singular/spkg-configure.m4 index af2eb854143..d4d145defe3 100644 --- a/build/pkgs/singular/spkg-configure.m4 +++ b/build/pkgs/singular/spkg-configure.m4 @@ -7,7 +7,7 @@ SAGE_SPKG_CONFIGURE([singular], [ dnl Use pkg-config to ensure that Singular is new enough. PKG_CHECK_MODULES([SINGULAR], [Singular >= 4.2.1], [ AC_MSG_CHECKING([that Singular's help is working]) - AS_IF([test x`printf "system(\"--browser\", \"builtin\"); \n help;" | Singular 2>&1 | grep "error\ occurred"` = x], [ + AS_IF([test x`printf "system(\"--browser\", \"builtin\"); \n help;" | Singular 2>&1 | grep "error occurred"` = x], [ AC_MSG_RESULT(yes) dnl We have Singular. Now determine the shared library path on dnl platforms on which sage.libs.singular needs to reload the library with RTLD_GLOBAL. From f1da83e82a0f03aea53d1e54075535b12d1bcc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 1 Oct 2022 13:55:18 +0200 Subject: [PATCH 245/350] partial cleanup in partition.py --- src/sage/combinat/partition.py | 156 ++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 73 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index f6cf8e4f364..39bee4b8b53 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -542,7 +542,6 @@ def __init__(self, parent, mu): Traceback (most recent call last): ... ValueError: [3, 1, 7] is not an element of Partitions - """ if isinstance(mu, Partition): # since we are (suppose to be) immutable, we can share the underlying data @@ -737,9 +736,9 @@ def _repr_exp_high(self): if not self._list: return '-' exp = self.to_exp()[::-1] # reversed list of exponents - M=max(self) - return '%s' % ', '.join('%s%s' % (M-m, '' if e==1 else '^%s'%e) - for (m,e) in enumerate(exp) if e>0) + M = max(self) + return ', '.join('%s%s' % (M - m, '' if e == 1 else '^%s' % e) + for m, e in enumerate(exp) if e > 0) def _repr_compact_low(self): """ @@ -1050,10 +1049,10 @@ def __truediv__(self, p): sage: p/[2,2,2] Traceback (most recent call last): ... - ValueError: To form a skew partition p/q, q must be contained in p. + ValueError: to form a skew partition p/q, q must be contained in p """ if not self.contains(p): - raise ValueError("To form a skew partition p/q, q must be contained in p.") + raise ValueError("to form a skew partition p/q, q must be contained in p") return SkewPartition([self[:], p]) @@ -2263,7 +2262,7 @@ def t_completion(self, t): ValueError: 5-completion is not defined """ if self._list and t < self.size() + self._list[0]: - raise ValueError("{}-completion is not defined".format(t)) + raise ValueError(f"{t}-completion is not defined") return Partition([t - self.size()] + self._list) def larger_lex(self, rhs): @@ -3038,14 +3037,15 @@ def arm_length(self, i, j): p = self if i < len(p) and j < p[i]: return p[i]-(j+1) - else: - raise ValueError("The cell is not in the diagram") + raise ValueError("the cell is not in the diagram") def arm_lengths(self, flat=False): """ Return a tableau of shape ``self`` where each cell is filled with - its arm length. The optional boolean parameter ``flat`` provides - the option of returning a flat list. + its arm length. + + The optional boolean parameter ``flat`` provides the option of + returning a flat list. EXAMPLES:: @@ -3089,15 +3089,12 @@ def arm_cells(self, i, j): sage: Partition([]).arm_cells(0,0) Traceback (most recent call last): ... - ValueError: The cell is not in the diagram - + ValueError: the cell is not in the diagram """ p = self if i < len(p) and j < p[i]: - return [ (i, x) for x in range(j+1, p[i]) ] - else: - raise ValueError("The cell is not in the diagram") - + return [(i, x) for x in range(j + 1, p[i])] + raise ValueError("the cell is not in the diagram") def leg_length(self, i, j): """ @@ -3131,12 +3128,10 @@ def leg_length(self, i, j): sage: cell = [0,0]; Partition([3,3]).leg_length(*cell) 1 """ - conj = self.conjugate() if j < len(conj) and i < conj[j]: - return conj[j]-(i+1) - else: - raise ValueError("The cell is not in the diagram") + return conj[j] - (i + 1) + raise ValueError("the cell is not in the diagram") def leg_lengths(self, flat=False): """ @@ -3191,10 +3186,10 @@ def leg_cells(self, i, j): sage: Partition([]).leg_cells(0,0) Traceback (most recent call last): ... - ValueError: The cell is not in the diagram + ValueError: the cell is not in the diagram """ l = self.leg_length(i, j) - return [(x, j) for x in range(i+1, i+l+1)] + return [(x, j) for x in range(i + 1, i + l + 1)] def attacking_pairs(self): """ @@ -3513,8 +3508,8 @@ def lower_hook_lengths(self, alpha): """ p = self conj = p.conjugate() - return [[conj[j] - i + alpha*(p[i]-(j+1)) for j in range(p[i])] for i in range(len(p))] - + return [[conj[j] - i + alpha*(p[i] - (j + 1)) for j in range(p[i])] + for i in range(len(p))] def weighted_size(self): r""" @@ -4430,10 +4425,9 @@ def add_cell(self, i, j = None): pl[i] += 1 return Partition(pl) - raise ValueError("[%s, %s] is not an addable cell"%(i,j)) + raise ValueError(f"[{i}, {j}] is not an addable cell") - - def remove_cell(self, i, j = None): + def remove_cell(self, i, j=None): """ Return the partition obtained by removing a cell at the end of row ``i`` of ``self``. @@ -4526,7 +4520,7 @@ def k_skew(self, k): return SkewPartition([[],[]]) if self[0] > k: - raise ValueError("the partition must be %d-bounded" % k) + raise ValueError(f"the partition must be {k}-bounded") #Find the k-skew diagram of the partition formed #by removing the first row @@ -4912,13 +4906,13 @@ def remove_horizontal_border_strip(self, k): sage: Partition([]).remove_horizontal_border_strip(6).list() [] """ - return Partitions_with_constraints(n = self.size()-k, - min_length = len(self)-1, - max_length = len(self), - floor = self[1:]+[0], - ceiling = self[:], - max_slope = 0, - name = "The subpartitions of {} obtained by removing an horizontal border strip of length {}".format(self,k)) + return Partitions_with_constraints(n=self.size() - k, + min_length=len(self) - 1, + max_length=len(self), + floor=self[1:] + [0], + ceiling=self[:], + max_slope=0, + name=f"The subpartitions of {self} obtained by removing an horizontal border strip of length {k}") def k_conjugate(self, k): r""" @@ -5085,11 +5079,9 @@ def jacobi_trudi(self): """ return SkewPartition([ self, [] ]).jacobi_trudi() - def character_polynomial(self): r""" - Return the character polynomial associated to the partition - ``self``. + Return the character polynomial associated to the partition ``self``. The character polynomial `q_\mu` associated to a partition `\mu` is defined by @@ -5120,8 +5112,7 @@ def character_polynomial(self): sage: Partition([2,1]).character_polynomial() 1/3*x0^3 - 2*x0^2 + 8/3*x0 - x2 """ - - #Create the polynomial ring we will use + # Create the polynomial ring we will use k = self.size() P = PolynomialRing(QQ, k, 'x') x = P.gens() @@ -5213,7 +5204,7 @@ def dimension(self, smaller=None, k=1): Checks that the dimension satisfies the obvious recursion relation:: sage: test = lambda larger, smaller: larger.dimension(smaller) == sum(mu.dimension(smaller) for mu in larger.down()) - sage: all(test(larger,smaller) for l in range(1,10) for s in range(10) + sage: all(test(larger,smaller) for l in range(1,8) for s in range(8) ....: for larger in Partitions(l) for smaller in Partitions(s) if smaller != larger) True @@ -5489,6 +5480,7 @@ def coloring(i): immutable=True, multiedges=True) return self.dual_equivalence_graph(directed, coloring) + ############## # Partitions # ############## @@ -5746,15 +5738,15 @@ class Partitions(UniqueRepresentation, Parent): sage: Partitions(5,parts_in=[1,2,3,4], length=4) Traceback (most recent call last): ... - ValueError: The parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else. + ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else sage: Partitions(5,starting=[3,2], length=2) Traceback (most recent call last): ... - ValueError: The parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else. + ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else sage: Partitions(5,ending=[3,2], length=2) Traceback (most recent call last): ... - ValueError: The parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else. + ValueError: the parameters 'parts_in', 'starting' and 'ending' cannot be combined with anything else sage: Partitions(NN, length=2) Traceback (most recent call last): ... @@ -5847,8 +5839,8 @@ def __classcall_private__(cls, n=None, **kwargs): ('parts_in' in kwargs or 'starting' in kwargs or 'ending' in kwargs)): - raise ValueError("The parameters 'parts_in', 'starting' and "+ - "'ending' cannot be combined with anything else.") + raise ValueError("the parameters 'parts_in', 'starting' and "+ + "'ending' cannot be combined with anything else") if 'parts_in' in kwargs: return Partitions_parts_in(n, kwargs['parts_in']) @@ -5865,10 +5857,10 @@ def __classcall_private__(cls, n=None, **kwargs): kwargs['name'] = "Partitions of the integer %s satisfying constraints %s"%(n, ", ".join( ["%s=%s"%(key, kwargs[key]) for key in sorted(kwargs)] )) # min_part is at least 1, and it is 1 by default - kwargs['min_part'] = max(1,kwargs.get('min_part',1)) + kwargs['min_part'] = max(1, kwargs.get('min_part', 1)) # max_slope is at most 0, and it is 0 by default - kwargs['max_slope'] = min(0,kwargs.get('max_slope',0)) + kwargs['max_slope'] = min(0, kwargs.get('max_slope', 0)) if kwargs.get('min_slope', -float('inf')) > 0: raise ValueError("the minimum slope must be non-negative") @@ -6053,7 +6045,7 @@ def _element_constructor_(self, lst): """ if isinstance(lst, PartitionTuple): if lst.level() != 1: - raise ValueError('%s is not an element of %s' % (lst, self)) + raise ValueError(f'{lst} is not an element of {self}') lst = lst[0] if lst.parent() is self: return lst @@ -6127,12 +6119,13 @@ def subset(self, *args, **kwargs): sage: P.subset(ending=[3,1]) Traceback (most recent call last): ... - ValueError: Invalid combination of arguments + ValueError: invalid combination of arguments """ if len(args) != 0 or len(kwargs) != 0: - raise ValueError("Invalid combination of arguments") + raise ValueError("invalid combination of arguments") return self + class Partitions_all(Partitions): """ Class of all partitions. @@ -6236,12 +6229,12 @@ def from_frobenius_coordinates(self, frobenius_coordinates): [7, 5, 5, 1, 1] """ if len(frobenius_coordinates) != 2: - raise ValueError('%s is not a valid partition, two sequences of coordinates are needed'%str(frobenius_coordinates)) + raise ValueError('%s is not a valid partition, two sequences of coordinates are needed' % str(frobenius_coordinates)) else: a = frobenius_coordinates[0] b = frobenius_coordinates[1] if len(a) != len(b): - raise ValueError('%s is not a valid partition, the sequences of coordinates need to be the same length'%str(frobenius_coordinates)) + raise ValueError('%s is not a valid partition, the sequences of coordinates need to be the same length' % str(frobenius_coordinates)) # should add tests to see if a and b are sorted down, nonnegative and strictly decreasing r = len(a) if r == 0: @@ -6249,16 +6242,16 @@ def from_frobenius_coordinates(self, frobenius_coordinates): tmp = [a[i]+i+1 for i in range(r)] # should check that a is strictly decreasing if a[-1] < 0: - raise ValueError('%s is not a partition, no coordinate can be negative'%str(frobenius_coordinates)) + raise ValueError('%s is not a partition, no coordinate can be negative' % str(frobenius_coordinates)) if b[-1] >= 0: tmp.extend([r]*b[r-1]) else: - raise ValueError('%s is not a partition, no coordinate can be negative'%str(frobenius_coordinates)) - for i in range(r-1,0,-1): + raise ValueError('%s is not a partition, no coordinate can be negative' % str(frobenius_coordinates)) + for i in range(r - 1, 0, -1): if b[i-1]-b[i] > 0: tmp.extend([i]*(b[i-1]-b[i]-1)) else: - raise ValueError('%s is not a partition, the coordinates need to be strictly decreasing'%str(frobenius_coordinates)) + raise ValueError('%s is not a partition, the coordinates need to be strictly decreasing' % str(frobenius_coordinates)) return self.element_class(self, tmp) def from_beta_numbers(self, beta): @@ -6403,6 +6396,7 @@ def from_core_and_quotient(self, core, quotient): new_w.sort(reverse=True) return self.element_class(self, [new_w[i]+i for i in range(len(new_w))]) + class Partitions_all_bounded(Partitions): def __init__(self, k): """ @@ -6462,6 +6456,7 @@ def __iter__(self): yield self.element_class(self, p) n += 1 + class Partitions_n(Partitions): """ Partitions of the integer `n`. @@ -6842,6 +6837,7 @@ def subset(self, **kwargs): """ return Partitions(self.n, **kwargs) + class Partitions_nk(Partitions): """ Partitions of the integer `n` of length equal to `k`. @@ -7056,6 +7052,7 @@ def subset(self, **kwargs): """ return Partitions(self.n, length=self.k, **kwargs) + class Partitions_parts_in(Partitions): """ Partitions of `n` with parts in a given set `S`. @@ -7082,7 +7079,7 @@ def __classcall_private__(cls, n, parts): True """ parts = tuple(sorted(parts)) - return super(Partitions_parts_in, cls).__classcall__(cls, Integer(n), parts) + return super().__classcall__(cls, Integer(n), parts) def __init__(self, n, parts): """ @@ -7391,8 +7388,8 @@ def __classcall_private__(cls, n, starting_partition): True """ starting_partition = Partition(starting_partition) - return super(Partitions_starting, cls).__classcall__(cls, Integer(n), - starting_partition) + return super().__classcall__(cls, Integer(n), + starting_partition) def __init__(self, n, starting_partition): """ @@ -7465,6 +7462,7 @@ def next(self, part): """ return next(part) + class Partitions_ending(Partitions): """ All partitions with a given ending. @@ -7483,8 +7481,8 @@ def __classcall_private__(cls, n, ending_partition): True """ ending_partition = Partition(ending_partition) - return super(Partitions_ending, cls).__classcall__(cls, Integer(n), - ending_partition) + return super().__classcall__(cls, Integer(n), + ending_partition) def __init__(self, n, ending_partition): """ @@ -7559,8 +7557,8 @@ def next(self, part): """ if part == self._ending: return None - else: - return next(part) + return next(part) + class PartitionsInBox(Partitions): r""" @@ -7681,6 +7679,7 @@ def cardinality(self): """ return binomial(self.h + self.w, self.w) + class Partitions_constraints(IntegerListsLex): """ For unpickling old constrained ``Partitions_constraints`` objects created @@ -7733,6 +7732,7 @@ class Partitions_with_constraints(IntegerListsLex): Element = Partition options = Partitions.options + ###################### # Regular Partitions # ###################### @@ -7831,11 +7831,12 @@ def _fast_iterator(self, n, max_part): max_part = n bdry = self._ell - 1 - for i in reversed(range(1, max_part+1)): - for p in self._fast_iterator(n-i, i): + for i in reversed(range(1, max_part + 1)): + for p in self._fast_iterator(n - i, i): if p.count(i) < bdry: yield [i] + p + class RegularPartitions_all(RegularPartitions): r""" The class of all `\ell`-regular partitions. @@ -7903,6 +7904,7 @@ def __iter__(self): yield self.element_class(self, p) n += 1 + class RegularPartitions_truncated(RegularPartitions): r""" The class of `\ell`-regular partitions with max length `k`. @@ -8019,11 +8021,12 @@ def _fast_iterator(self, n, max_part, depth=0): max_part = n bdry = self._ell - 1 - for i in reversed(range(1, max_part+1)): - for p in self._fast_iterator(n-i, i, depth+1): + for i in reversed(range(1, max_part + 1)): + for p in self._fast_iterator(n - i, i, depth + 1): if p.count(i) < bdry: yield [i] + p + class RegularPartitions_bounded(RegularPartitions): r""" The class of `\ell`-regular `k`-bounded partitions. @@ -8101,6 +8104,7 @@ def __iter__(self): for p in self._fast_iterator(n, k): yield self.element_class(self, p) + class RegularPartitions_n(RegularPartitions, Partitions_n): r""" The class of `\ell`-regular partitions of `n`. @@ -8228,6 +8232,7 @@ def _an_element_(self): raise EmptySetError return Partitions_n._an_element_(self) + ###################### # Ordered Partitions # ###################### @@ -8278,7 +8283,7 @@ def __classcall_private__(cls, n, k=None): """ if k is not None: k = Integer(k) - return super(OrderedPartitions, cls).__classcall__(cls, Integer(n), k) + return super().__classcall__(cls, Integer(n), k) def __init__(self, n, k): """ @@ -8375,6 +8380,7 @@ def cardinality(self): ans = libgap.NrOrderedPartitions(n, k) return ZZ(ans) + ########################## # Partitions Greatest LE # ########################## @@ -8452,6 +8458,7 @@ def cardinality(self): Element = Partition options = Partitions.options + ########################## # Partitions Greatest EQ # ########################## @@ -8543,6 +8550,7 @@ def cardinality(self): Element = Partition options = Partitions.options + ######################### # Restricted Partitions # ######################### @@ -8664,6 +8672,7 @@ def _fast_iterator(self, n, max_part): break yield [i] + p + class RestrictedPartitions_all(RestrictedPartitions_generic): r""" The class of all `\ell`-restricted partitions. @@ -8715,6 +8724,7 @@ def __iter__(self): yield self.element_class(self, p) n += 1 + class RestrictedPartitions_n(RestrictedPartitions_generic, Partitions_n): r""" The class of `\ell`-restricted partitions of `n`. @@ -8923,7 +8933,7 @@ def number_of_partitions(n, algorithm='default'): """ n = ZZ(n) if n < 0: - raise ValueError("n (=%s) must be a nonnegative integer"%n) + raise ValueError("n (=%s) must be a nonnegative integer" % n) elif n == 0: return ZZ.one() @@ -8933,7 +8943,7 @@ def number_of_partitions(n, algorithm='default'): if algorithm == 'flint': return cached_number_of_partitions(n) - raise ValueError("unknown algorithm '%s'"%algorithm) + raise ValueError("unknown algorithm '%s'" % algorithm) def number_of_partitions_length(n, k, algorithm='hybrid'): @@ -9001,7 +9011,7 @@ def number_of_partitions_length(n, k, algorithm='hybrid'): # Rather than caching an under-used function I have cached the default # number_of_partitions functions which is currently using FLINT. # AM trac #13072 -cached_number_of_partitions = cached_function( flint_number_of_partitions ) +cached_number_of_partitions = cached_function(flint_number_of_partitions) # October 2012: fixing outdated pickles which use classes being deprecated from sage.misc.persist import register_unpickle_override From 2d8fdae102dcec3fa90cae39156a6aea90931c0f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Oct 2022 10:00:03 -0700 Subject: [PATCH 246/350] .gitpod.yml: Stop when errors occur in the init/command scripts --- .gitpod-command.sh | 37 ++++++++++++++++++++++++++++++++++ .gitpod-init.sh | 16 +++++++++++++++ .gitpod.yml | 49 ++-------------------------------------------- 3 files changed, 55 insertions(+), 47 deletions(-) create mode 100755 .gitpod-command.sh create mode 100755 .gitpod-init.sh diff --git a/.gitpod-command.sh b/.gitpod-command.sh new file mode 100755 index 00000000000..9a83fa23d66 --- /dev/null +++ b/.gitpod-command.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Exit on error +set -e + +# Activate conda environment +conda config --append envs_dirs $(pwd) +conda activate $(pwd)/venv || exit 1 + +# RestructuredText extension recommends python extension, although we have already installed it +## So disable the recommendation dialog +echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json + +# Setup trac as remote +## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( /dev/null # might still exists from a previous run/prebuild +if [[ -n "${PRIVATE_SSH_KEY}" ]]; then + # Setup ssh key for authentication with trac + mkdir -p ~/.ssh + echo $PRIVATE_SSH_KEY | sed 's/\(-----\(BEGIN\|END\) OPENSSH PRIVATE KEY-----\)/\n\1\n/g' > ~/.ssh/id_rsa + sed -i '/^$/d' ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + echo "PubkeyAcceptedKeyTypes +ssh-rsa" > ~/.ssh/config + ssh-keyscan -H trac.sagemath.org >> ~/.ssh/known_hosts + + # Setup trac repo + git remote add trac git@trac.sagemath.org:sage.git -t master -t develop -t $(git branch --show-current) + git remote set-url --push trac git@trac.sagemath.org:sage.git + git fetch trac + git branch -u trac/$(git branch --show-current) +else + # Fallback to sagemath mirror + git remote add trac https://github.com/sagemath/sagetrac-mirror.git -t master -t develop + git remote set-url --push trac pushing-needs-ssh-key +fi diff --git a/.gitpod-init.sh b/.gitpod-init.sh new file mode 100755 index 00000000000..674bb26b312 --- /dev/null +++ b/.gitpod-init.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Exit on error +set -e + +# Create conda environment +./bootstrap-conda +mamba env create --file src/environment-dev.yml --prefix venv +conda config --append envs_dirs $(pwd) +conda activate $(pwd)/venv + +# Build sage +./bootstrap +./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX +pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup +pip install --no-build-isolation -v -v -e ./src diff --git a/.gitpod.yml b/.gitpod.yml index fcd6027c88d..ffb9c030769 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,53 +5,8 @@ image: # Start up tasks. https://www.gitpod.io/docs/config-start-tasks/ tasks: - name: Setup - init: | - # Create conda environment - ./bootstrap-conda - mamba env create --file src/environment-dev.yml --prefix venv - conda config --append envs_dirs $(pwd) - conda activate $(pwd)/venv - - # Build sage - ./bootstrap - ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX - pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup - pip install --no-build-isolation -v -v -e ./src - - command: | - # Activate conda environment - conda config --append envs_dirs $(pwd) - conda activate $(pwd)/venv - - # RestructuredText extension recommends python extension, although we have already installed it - ## So disable the recommendation dialog - echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json - - # Setup trac as remote - ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( /dev/null # might still exists from a previous run/prebuild - if [[ -n "${PRIVATE_SSH_KEY}" ]]; then - # Setup ssh key for authentication with trac - mkdir -p ~/.ssh - echo $PRIVATE_SSH_KEY | sed 's/\(-----\(BEGIN\|END\) OPENSSH PRIVATE KEY-----\)/\n\1\n/g' > ~/.ssh/id_rsa - sed -i '/^$/d' ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - echo "PubkeyAcceptedKeyTypes +ssh-rsa" > ~/.ssh/config - ssh-keyscan -H trac.sagemath.org >> ~/.ssh/known_hosts - - # Setup trac repo - git remote add trac git@trac.sagemath.org:sage.git -t master -t develop -t $(git branch --show-current) - git remote set-url --push trac git@trac.sagemath.org:sage.git - git fetch trac - git branch -u trac/$(git branch --show-current) - else - # Fallback to sagemath mirror - git remote add trac https://github.com/sagemath/sagetrac-mirror.git -t master -t develop - git remote set-url --push trac pushing-needs-ssh-key - fi - + init: ./.gitpod-init.sh + command: ./.gitpod-command.sh env: SAGE_NUM_THREADS: 8 From d1fcd37e784141b5181b5af7ccf0778804386dbb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Oct 2022 10:20:51 -0700 Subject: [PATCH 247/350] build/pkgs/setuptools_scm_git_archive/distros/conda.txt: Remove - not available in the conda-forge channel --- build/pkgs/setuptools_scm_git_archive/distros/conda.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build/pkgs/setuptools_scm_git_archive/distros/conda.txt diff --git a/build/pkgs/setuptools_scm_git_archive/distros/conda.txt b/build/pkgs/setuptools_scm_git_archive/distros/conda.txt deleted file mode 100644 index 538474ff946..00000000000 --- a/build/pkgs/setuptools_scm_git_archive/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -setuptools-scm-git-archive From 9f055b5bc739a0a66caeb6e64acbb1a9dd09fd1b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Oct 2022 10:28:33 -0700 Subject: [PATCH 248/350] .gitpod-command.sh: Fix up --- .gitpod-command.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitpod-command.sh b/.gitpod-command.sh index 9a83fa23d66..a7c4134a0fa 100755 --- a/.gitpod-command.sh +++ b/.gitpod-command.sh @@ -5,7 +5,7 @@ set -e # Activate conda environment conda config --append envs_dirs $(pwd) -conda activate $(pwd)/venv || exit 1 +conda activate $(pwd)/venv # RestructuredText extension recommends python extension, although we have already installed it ## So disable the recommendation dialog @@ -15,7 +15,7 @@ echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/. ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( /dev/null # might still exists from a previous run/prebuild +git remote remove trac 2> /dev/null || true # might still exists from a previous run/prebuild if [[ -n "${PRIVATE_SSH_KEY}" ]]; then # Setup ssh key for authentication with trac mkdir -p ~/.ssh From 400b680e3f9e85aee5e79931e518e9af71483f18 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Oct 2022 11:13:16 -0700 Subject: [PATCH 249/350] .gitpod-setup-trac-remote.sh: New, move other scripts back into .gitpod.yml, chained with && --- .gitpod-init.sh | 16 --------------- ...command.sh => .gitpod-setup-trac-remote.sh | 8 -------- .gitpod.yml | 20 +++++++++++++++++-- 3 files changed, 18 insertions(+), 26 deletions(-) delete mode 100755 .gitpod-init.sh rename .gitpod-command.sh => .gitpod-setup-trac-remote.sh (80%) diff --git a/.gitpod-init.sh b/.gitpod-init.sh deleted file mode 100755 index 674bb26b312..00000000000 --- a/.gitpod-init.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -# Exit on error -set -e - -# Create conda environment -./bootstrap-conda -mamba env create --file src/environment-dev.yml --prefix venv -conda config --append envs_dirs $(pwd) -conda activate $(pwd)/venv - -# Build sage -./bootstrap -./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX -pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup -pip install --no-build-isolation -v -v -e ./src diff --git a/.gitpod-command.sh b/.gitpod-setup-trac-remote.sh similarity index 80% rename from .gitpod-command.sh rename to .gitpod-setup-trac-remote.sh index a7c4134a0fa..4ca3b19f26d 100755 --- a/.gitpod-command.sh +++ b/.gitpod-setup-trac-remote.sh @@ -3,14 +3,6 @@ # Exit on error set -e -# Activate conda environment -conda config --append envs_dirs $(pwd) -conda activate $(pwd)/venv - -# RestructuredText extension recommends python extension, although we have already installed it -## So disable the recommendation dialog -echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json - # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$(- + ./bootstrap-conda + && mamba env create --file src/environment-dev.yml --prefix venv + && conda config --append envs_dirs $(pwd) + && conda activate $(pwd)/venv + && ./bootstrap + && ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX + && pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup + && pip install --no-build-isolation -v -v -e ./src + # Activate conda environment, set up Trac remote + command: >- + # RestructuredText extension recommends python extension, although we have already installed it + ## So disable the recommendation dialog + echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json + && conda config --append envs_dirs $(pwd) + && conda activate $(pwd)/venv + && ./.gitpod-setup-trac-remote.sh env: SAGE_NUM_THREADS: 8 From 8b1063c23912dc4f6cc5b53f4c929f8f87148183 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Oct 2022 11:54:30 -0700 Subject: [PATCH 250/350] .gitpod.yml: Fix up comment placement --- .gitpod.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index ef14a6f93c8..52ac8d7184c 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -16,9 +16,9 @@ tasks: && pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup && pip install --no-build-isolation -v -v -e ./src # Activate conda environment, set up Trac remote + # RestructuredText extension recommends python extension, although we have already installed it + # So disable the recommendation dialog command: >- - # RestructuredText extension recommends python extension, although we have already installed it - ## So disable the recommendation dialog echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json && conda config --append envs_dirs $(pwd) && conda activate $(pwd)/venv From 39edec7c6a09c3a0e14288c49eea792fbbb17d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 1 Oct 2022 20:56:10 +0200 Subject: [PATCH 251/350] doctest for integral of max_symbolic with giac --- src/sage/symbolic/integration/integral.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/symbolic/integration/integral.py b/src/sage/symbolic/integration/integral.py index f9914e438a1..34d96b1c731 100644 --- a/src/sage/symbolic/integration/integral.py +++ b/src/sage/symbolic/integration/integral.py @@ -194,6 +194,16 @@ def __init__(self): sage: from sage.symbolic.integration.integral import definite_integral sage: definite_integral(sin(x),x,0,pi) 2 + + TESTS: + + Check for :trac:`32354`:: + + sage: ex = 1/max_symbolic(x, 1)**2 + sage: integral(ex, x, 0, 2, algorithm='giac') + 3/2 + sage: integral(1/max_symbolic(x, 1)**2, x, 0, oo, algorithm='giac') + 2 """ # The automatic evaluation routine will try these integrators # in the given order. This is an attribute of the class instead of From 1d6ce21ab453aa0547927e3930d2600a0e1a826b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 25 Sep 2022 10:59:06 +0200 Subject: [PATCH 252/350] pep8 cleanup in algebras/letterplace (pyx files) --- .../free_algebra_element_letterplace.pyx | 202 +++++++++--------- .../letterplace/free_algebra_letterplace.pyx | 137 ++++++------ .../letterplace/letterplace_ideal.pyx | 46 ++-- 3 files changed, 185 insertions(+), 200 deletions(-) diff --git a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx index fc1d43c574c..41444812c49 100644 --- a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx @@ -107,9 +107,9 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: loads(dumps(x*y*x)) == x*y*x # indirect doctest True - """ - return self.__class__, (self._parent,self._poly) + return self.__class__, (self._parent, self._poly) + def __copy__(self): """ TESTS:: @@ -117,10 +117,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: copy(x*y*z+z*y*x) == x*y*z+z*y*x # indirect doctest True - """ self._poly = (self._parent)._current_ring(self._poly) - return self.__class__(self._parent,self._poly,check=False) + return self.__class__(self._parent, self._poly, check=False) + def __hash__(self): """ TESTS:: @@ -128,7 +128,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: set([x*y*z, z*y+x*z,x*y*z]) # indirect doctest {x*z + z*y, x*y*z} - """ return hash(self._poly) @@ -163,66 +162,65 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): w + (z + 1)*x - y sage: print(a+b*(z+1)-c) a + (z + 1)*b - c - """ cdef list L = [] cdef FreeAlgebra_letterplace P = self._parent cdef int ngens = P.__ngens if P._base._repr_option('element_is_atomic'): - for E,c in zip(self._poly.exponents(),self._poly.coefficients()): + for E, c in zip(self._poly.exponents(), self._poly.coefficients()): monstr = P.exponents_to_string(E) if monstr: - if c==1: + if c == 1: if L: - L.extend(['+',monstr]) + L.extend(['+', monstr]) else: L.append(monstr) - elif c==-1: + elif c == -1: if L: - L.extend(['-',monstr]) + L.extend(['-', monstr]) else: - L.append('-'+monstr) + L.append('-' + monstr) else: if L: - if c>=0: - L.extend(['+',repr(c)+'*'+monstr]) + if c >= 0: + L.extend(['+', repr(c) + '*' + monstr]) else: - L.extend(['-',repr(-c)+'*'+monstr]) + L.extend(['-', repr(-c) + '*' + monstr]) else: - L.append(repr(c)+'*'+monstr) + L.append(repr(c) + '*' + monstr) else: - if c>=0: + if c >= 0: if L: - L.extend(['+',repr(c)]) + L.extend(['+', repr(c)]) else: L.append(repr(c)) else: if L: - L.extend(['-',repr(-c)]) + L.extend(['-', repr(-c)]) else: L.append(repr(c)) else: - for E,c in zip(self._poly.exponents(),self._poly.coefficients()): + for E, c in zip(self._poly.exponents(), self._poly.coefficients()): monstr = P.exponents_to_string(E) if monstr: - if c==1: + if c == 1: if L: - L.extend(['+',monstr]) + L.extend(['+', monstr]) else: L.append(monstr) - elif c==-1: + elif c == -1: if L: - L.extend(['-',monstr]) + L.extend(['-', monstr]) else: - L.append('-'+monstr) + L.append('-' + monstr) else: if L: - L.extend(['+','('+repr(c)+')*'+monstr]) + L.extend(['+', '(' + repr(c) + ')*' + monstr]) else: - L.append('('+repr(c)+')*'+monstr) + L.append('(' + repr(c) + ')*' + monstr) else: if L: - L.extend(['+',repr(c)]) + L.extend(['+', repr(c)]) else: L.append(repr(c)) if L: @@ -245,60 +243,60 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): cdef int ngens = P.__ngens from sage.misc.latex import latex if P._base._repr_option('element_is_atomic'): - for E,c in zip(self._poly.exponents(),self._poly.coefficients()): + for E, c in zip(self._poly.exponents(), self._poly.coefficients()): monstr = P.exponents_to_latex(E) if monstr: - if c==1: + if c == 1: if L: - L.extend(['+',monstr]) + L.extend(['+', monstr]) else: L.append(monstr) - elif c==-1: + elif c == -1: if L: - L.extend(['-',monstr]) + L.extend(['-', monstr]) else: - L.append('-'+monstr) + L.append('-' + monstr) else: if L: - if c>=0: - L.extend(['+',repr(latex(c))+' '+monstr]) + if c >= 0: + L.extend(['+', repr(latex(c)) + ' ' + monstr]) else: - L.extend(['-',repr(latex(-c))+' '+monstr]) + L.extend(['-', repr(latex(-c)) + ' ' + monstr]) else: - L.append(repr(latex(c))+' '+monstr) + L.append(repr(latex(c)) + ' ' + monstr) else: - if c>=0: + if c >= 0: if L: - L.extend(['+',repr(latex(c))]) + L.extend(['+', repr(latex(c))]) else: L.append(repr(latex(c))) else: if L: - L.extend(['-',repr(latex(-c))]) + L.extend(['-', repr(latex(-c))]) else: L.append(repr(c)) else: - for E,c in zip(self._poly.exponents(),self._poly.coefficients()): + for E, c in zip(self._poly.exponents(), self._poly.coefficients()): monstr = P.exponents_to_latex(E) if monstr: - if c==1: + if c == 1: if L: - L.extend(['+',monstr]) + L.extend(['+', monstr]) else: L.append(monstr) - elif c==-1: + elif c == -1: if L: - L.extend(['-',monstr]) + L.extend(['-', monstr]) else: - L.append('-'+monstr) + L.append('-' + monstr) else: if L: - L.extend(['+','\\left('+repr(latex(c))+'\\right) '+monstr]) + L.extend(['+', '\\left(' + repr(latex(c)) + '\\right) ' + monstr]) else: - L.append('\\left('+repr(latex(c))+'\\right) '+monstr) + L.append('\\left(' + repr(latex(c)) + '\\right) ' + monstr) else: if L: - L.extend(['+',repr(latex(c))]) + L.extend(['+', repr(latex(c))]) else: L.append(repr(latex(c))) if L: @@ -309,10 +307,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): """ Return the degree of this element. - NOTE: + .. NOTE:: - Generators may have a positive integral degree weight. All - elements must be weighted homogeneous. + Generators may have a positive integral degree weight. All + elements must be weighted homogeneous. EXAMPLES:: @@ -322,7 +320,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: ((x*y+z)^3).degree() 9 - """ return self._poly.degree() @@ -342,7 +339,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: ((x*y+z)^2).letterplace_polynomial() x*x__1*y_2*x_3*x__4*y_5 + x*x__1*y_2*z_3*x__4*x__5 + z*x__1*x__2*x_3*x__4*y_5 + z*x__1*x__2*z_3*x__4*x__5 - """ return self._poly @@ -358,7 +354,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: ((2*x*y+z)^2).lm() x*y*x*y - """ return FreeAlgebraElement_letterplace(self._parent, self._poly.lm()) @@ -375,7 +370,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: ((2*x*y+z)^2).lt() 4*x*y*x*y - """ return FreeAlgebraElement_letterplace(self._parent, self._poly.lt()) @@ -394,7 +388,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: ((2*x*y+z)^2).lc() 4 - """ return self._poly.lc() @@ -407,7 +400,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): True sage: bool(F.zero()) False - """ return bool(self._poly) @@ -416,10 +408,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): Tell whether or not the leading monomial of self divides the leading monomial of another element. - NOTE: + .. NOTE:: - A free algebra element `p` divides another one `q` if there are - free algebra elements `s` and `t` such that `spt = q`. + A free algebra element `p` divides another one `q` if there are + free algebra elements `s` and `t` such that `spt = q`. EXAMPLES:: @@ -430,7 +422,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): y*x*y sage: (y*x*y-y^4).lm_divides((2*x*y+z)^2*z) True - """ if self._parent is not p._parent: raise TypeError("the two arguments must be elements in the same free algebra") @@ -440,16 +431,16 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): s_poly = self._poly = P(self._poly) cdef int p_d = p_poly.degree() cdef int s_d = s_poly.degree() - if s_d>p_d: + if s_d > p_d: return False cdef int i - if P.monomial_divides(s_poly,p_poly): + if P.monomial_divides(s_poly, p_poly): return True realngens = A._commutative_ring.ngens() CG = CyclicPermutationGroup(P.ngens()) - for i from 0 <= i < p_d-s_d: + for i in range(p_d - s_d): s_poly = s_poly * CG[realngens] - if P.monomial_divides(s_poly,p_poly): + if P.monomial_divides(s_poly, p_poly): return True return False @@ -469,7 +460,7 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): return PyObject_RichCompare(left, right, op) ################################ - ## Arithmetic + # Arithmetic cpdef _neg_(self): """ TESTS:: @@ -483,7 +474,9 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): -3*x*y - 2*z*z """ - return FreeAlgebraElement_letterplace(self._parent,-self._poly,check=False) + return FreeAlgebraElement_letterplace(self._parent, -self._poly, + check=False) + cpdef _add_(self, other): """ Addition, under the side condition that either one summand @@ -502,20 +495,21 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): x sage: 0+x x - """ if not other: return self if not self: return other cdef FreeAlgebraElement_letterplace right = other - if right._poly.degree()!=self._poly.degree(): + if right._poly.degree() != self._poly.degree(): raise ArithmeticError("can only add elements of the same weighted degree") # update the polynomials cdef FreeAlgebra_letterplace A = self._parent self._poly = A._current_ring(self._poly) right._poly = A._current_ring(right._poly) - return FreeAlgebraElement_letterplace(self._parent,self._poly+right._poly,check=False) + return FreeAlgebraElement_letterplace(self._parent, + self._poly + right._poly, + check=False) cpdef _sub_(self, other): """ @@ -541,20 +535,21 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: x*y+z x*y + z - """ if not other: return self if not self: return -other cdef FreeAlgebraElement_letterplace right = other - if right._poly.degree()!=self._poly.degree(): + if right._poly.degree() != self._poly.degree(): raise ArithmeticError("can only subtract elements of the same degree") # update the polynomials cdef FreeAlgebra_letterplace A = self._parent self._poly = A._current_ring(self._poly) right._poly = A._current_ring(right._poly) - return FreeAlgebraElement_letterplace(self._parent,self._poly-right._poly,check=False) + return FreeAlgebraElement_letterplace(self._parent, + self._poly - right._poly, + check=False) cpdef _lmul_(self, Element right): """ @@ -566,9 +561,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(K, implementation='letterplace') sage: (a+b)*(z+1) # indirect doctest (z + 1)*a + (z + 1)*b - """ - return FreeAlgebraElement_letterplace(self._parent,self._poly._lmul_(right),check=False) + return FreeAlgebraElement_letterplace(self._parent, + self._poly._lmul_(right), + check=False) cpdef _rmul_(self, Element left): """ @@ -580,9 +576,10 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(K, implementation='letterplace') sage: (z+1)*(a+b) # indirect doctest (z + 1)*a + (z + 1)*b - """ - return FreeAlgebraElement_letterplace(self._parent,self._poly._rmul_(left),check=False) + return FreeAlgebraElement_letterplace(self._parent, + self._poly._rmul_(left), + check=False) cpdef _mul_(self, other): """ @@ -598,14 +595,15 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): cdef FreeAlgebraElement_letterplace left = self cdef FreeAlgebraElement_letterplace right = other cdef FreeAlgebra_letterplace A = left._parent - A.set_degbound(left._poly.degree()+right._poly.degree()) + A.set_degbound(left._poly.degree() + right._poly.degree()) # we must put the polynomials into the same ring left._poly = A._current_ring(left._poly) right._poly = A._current_ring(right._poly) realngens = A._commutative_ring.ngens() CG = CyclicPermutationGroup(A._current_ring.ngens()) rshift = right._poly * CG[left._poly.degree() * realngens] - return FreeAlgebraElement_letterplace(A,left._poly*rshift, check=False) + return FreeAlgebraElement_letterplace(A, left._poly * rshift, + check=False) def __pow__(FreeAlgebraElement_letterplace self, int n, k): """ @@ -615,30 +613,29 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): sage: F. = FreeAlgebra(K, implementation='letterplace') sage: (a+z*b)^3 # indirect doctest a*a*a + (z)*a*a*b + (z)*a*b*a + (z + 3)*a*b*b + (z)*b*a*a + (z + 3)*b*a*b + (z + 3)*b*b*a + (4*z + 3)*b*b*b - """ cdef FreeAlgebra_letterplace A = self._parent - if n<0: + if n < 0: raise ValueError("negative exponents are not allowed") - if n==0: + if n == 0: return FreeAlgebraElement_letterplace(A, A._current_ring(1), check=False) - if n==1: + if n == 1: return self - A.set_degbound(self._poly.degree()*n) - cdef MPolynomial_libsingular p,q + A.set_degbound(self._poly.degree() * n) + cdef MPolynomial_libsingular p, q self._poly = A._current_ring(self._poly) cdef int d = self._poly.degree() q = p = self._poly realngens = A._commutative_ring.ngens() cdef int i CG = CyclicPermutationGroup(A._current_ring.ngens()) - for i from 0 # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # ############################################################################### @@ -133,13 +133,13 @@ freeAlgebra = singular_function("freeAlgebra") # unfortunately we cannot set Singular attributes for MPolynomialRing_libsingular # Hence, we must constantly work around Letterplace's sanity checks, # and cannot use the following library functions: -#set_letterplace_attributes = singular_function("setLetterplaceAttributes") -#lpMult = singular_function("lpMult") +# set_letterplace_attributes = singular_function("setLetterplaceAttributes") +# lpMult = singular_function("lpMult") ##################### -# Auxiliar functions +# Auxiliary functions -cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring,blocks): +cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring, blocks): """ Create a polynomial ring in block order. @@ -177,7 +177,6 @@ cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring,blocks): Block term order with blocks: (Lexicographic term order of length 3, Lexicographic term order of length 3) - """ n = base_ring.ngens() T0 = base_ring.term_order() @@ -185,11 +184,11 @@ cdef MPolynomialRing_libsingular make_letterplace_ring(base_ring,blocks): cdef i cdef tuple names0 = base_ring.variable_names() cdef list names = list(names0) - for i from 1<=i = FreeAlgebra(K, implementation='letterplace') sage: loads(dumps(F)) is F # indirect doctest True - """ from sage.algebras.free_algebra import FreeAlgebra - if self._nb_slackvars==0: - return FreeAlgebra,(self._commutative_ring,) - return FreeAlgebra,(self._commutative_ring,None,None,None,None,None,None,None,self._degrees) + if self._nb_slackvars == 0: + return FreeAlgebra, (self._commutative_ring,) + return FreeAlgebra, (self._commutative_ring, None, None, None, + None, None, None, None, self._degrees) + # Small methods def ngens(self): """ @@ -307,10 +307,10 @@ cdef class FreeAlgebra_letterplace(Algebra): sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: F.ngens() 3 - """ - return self.__ngens-self._nb_slackvars - def gen(self,i): + return self.__ngens - self._nb_slackvars + + def gen(self, i): """ Return the `i`-th generator. @@ -329,21 +329,21 @@ cdef class FreeAlgebra_letterplace(Algebra): True sage: F.gen(2) c - """ - if i>=self.__ngens-self._nb_slackvars: + if i >= self.__ngens - self._nb_slackvars: raise ValueError("this free algebra only has %d generators" % (self.__ngens - self._nb_slackvars)) if self._gens is not None: return self._gens[i] deg = self._degrees[i] - #self.set_degbound(deg) + # self.set_degbound(deg) p = self._current_ring.gen(i) cdef int n - cdef int j = self.__ngens-1 - for n from 1<=n = FreeAlgebra(QQ, implementation='letterplace',order='lex') sage: L.term_order_of_block() Lexicographic term order - """ return self._commutative_ring.term_order() @@ -416,27 +415,25 @@ cdef class FreeAlgebra_letterplace(Algebra): False sage: FreeAlgebra(QQ, implementation='letterplace', names=['x']).is_commutative() True - """ - return self.__ngens-self._nb_slackvars <= 1 + return self.__ngens - self._nb_slackvars <= 1 def is_field(self, proof=True): """ Tell whether this free algebra is a field. - NOTE: + .. NOTE:: - This would only be the case in the degenerate case of no generators. - But such an example cannot be constructed in this implementation. + This would only be the case in the degenerate case of no generators. + But such an example cannot be constructed in this implementation. TESTS:: sage: F. = FreeAlgebra(QQ, implementation='letterplace') sage: F.is_field() False - """ - return (not (self.__ngens-self._nb_slackvars)) and self._base.is_field(proof=proof) + return (not (self.__ngens - self._nb_slackvars)) and self._base.is_field(proof=proof) def _repr_(self): """ @@ -451,10 +448,8 @@ cdef class FreeAlgebra_letterplace(Algebra): sage: F. = FreeAlgebra(QQ, implementation='letterplace', degrees=[2,1,3]) sage: F Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - - """ - return "Free Associative Unital Algebra on %d generators %s over %s"%(self.__ngens-self._nb_slackvars,self.gens(),self._base) + return "Free Associative Unital Algebra on %d generators %s over %s" % (self.__ngens - self._nb_slackvars, self.gens(), self._base) def _latex_(self): r""" @@ -467,17 +462,17 @@ cdef class FreeAlgebra_letterplace(Algebra): \Bold{Q}\langle \mathit{bla}, \alpha, z\rangle """ from sage.misc.latex import latex - return "%s\\langle %s\\rangle"%(latex(self.base_ring()),', '.join(self.latex_variable_names())) + return "%s\\langle %s\\rangle" % (latex(self.base_ring()), ', '.join(self.latex_variable_names())) def degbound(self): """ Return the degree bound that is currently used. - NOTE: + .. NOTE:: - When multiplying two elements of this free algebra, the degree - bound will be dynamically adapted. It can also be set by - :meth:`set_degbound`. + When multiplying two elements of this free algebra, the degree + bound will be dynamically adapted. It can also be set by + :meth:`set_degbound`. EXAMPLES: @@ -495,16 +490,16 @@ cdef class FreeAlgebra_letterplace(Algebra): sage: F.set_degbound(4) sage: F.degbound() 4 - """ return self._degbound - def set_degbound(self,d): + + def set_degbound(self, d): """ Increase the degree bound that is currently in place. - NOTE: + .. NOTE:: - The degree bound cannot be decreased. + The degree bound cannot be decreased. EXAMPLES: @@ -525,19 +520,18 @@ cdef class FreeAlgebra_letterplace(Algebra): sage: F.set_degbound(2) sage: F.degbound() 4 - """ - if d<=self._degbound: + if d <= self._degbound: return self._degbound = d - self._current_ring = make_letterplace_ring(self._commutative_ring,d) + self._current_ring = make_letterplace_ring(self._commutative_ring, d) # def base_extend(self, R): # if self._base.has_coerce_map_from(R): # return self ################################################ - ## Ideals + # Ideals def _ideal_class_(self, n=0): """ @@ -551,7 +545,6 @@ cdef class FreeAlgebra_letterplace(Algebra): Right Ideal (x*y + y*z, x*x + x*y - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field sage: type(I) is F._ideal_class_() True - """ from sage.algebras.letterplace.letterplace_ideal import LetterplaceIdeal return LetterplaceIdeal @@ -567,7 +560,6 @@ cdef class FreeAlgebra_letterplace(Algebra): Monoid of ideals of Free Associative Unital Algebra on 2 generators (x, y) over Finite Field of size 2 sage: F.ideal_monoid() is F.ideal_monoid() True - """ if self.__monoid is None: self.__monoid = IdealMonoid_nc(self) @@ -591,16 +583,15 @@ cdef class FreeAlgebra_letterplace(Algebra): sage: from sage.algebras.letterplace.free_algebra_element_letterplace import FreeAlgebraElement_letterplace sage: P = F.commutative_ring() sage: FreeAlgebraElement_letterplace(F, P.0*P.1^2+P.1^3) # indirect doctest - ) failed: NotImplementedError: + ) failed: NotImplementedError: Apparently you tried to view the letterplace algebra with shift-multiplication as the free algebra over a finitely generated free abelian monoid. In principle, this is correct, but it is not implemented, yet.> - """ cdef int ngens = self.__ngens - cdef int nblocks = len(E)/ngens - cdef int i,j,base, exp, var_ind + cdef int nblocks = len(E) // ngens + cdef int i, j, base, exp, var_ind cdef list out = [] cdef list tmp for i from 0<=i1 or exp>1: + if len(tmp) > 1 or exp > 1: raise NotImplementedError("\n Apparently you tried to view the letterplace algebra with\n shift-multiplication as the free algebra over a finitely\n generated free abelian monoid.\n In principle, this is correct, but it is not implemented, yet.") out.append(self._names[var_ind]) @@ -631,8 +622,8 @@ cdef class FreeAlgebra_letterplace(Algebra): \left(2 z + 1\right) a b a b + \left(z + 1\right) a b c + \left(z + 1\right) c a b - c c """ cdef int ngens = self.__ngens - cdef int nblocks = len(E)/ngens - cdef int i,j,base, exp, var_ind + cdef int nblocks = len(E) // ngens + cdef int i, j, base, exp, var_ind cdef list out = [] cdef list tmp cdef list names = self.latex_variable_names() @@ -642,11 +633,11 @@ cdef class FreeAlgebra_letterplace(Algebra): if not tmp: continue var_ind, exp = tmp[0] - if len(tmp)>1 or exp>1: + if len(tmp) > 1 or exp > 1: raise NotImplementedError("\n Apparently you tried to view the letterplace algebra with\n shift-multiplication as the free algebra over a finitely\n generated free abelian monoid.\n In principle, this is correct, but it is not implemented, yet.") out.append(names[var_ind]) - i += (self._degrees[var_ind]-1) + i += (self._degrees[var_ind] - 1) return ' '.join(out) def _reductor_(self, g, d): @@ -686,7 +677,6 @@ cdef class FreeAlgebra_letterplace(Algebra): y*y_1*y_2 - y*y_1*z_2 + y*z_1*y_2 - y*z_1*z_2 sage: p.reduce(I).letterplace_polynomial() == q True - """ cdef list out = [] C = self.current_ring() @@ -697,12 +687,13 @@ cdef class FreeAlgebra_letterplace(Algebra): from sage.groups.perm_gps.all import CyclicPermutationGroup CG = CyclicPermutationGroup(C.ngens()) for y in G: - out.extend([y]+[y * CG[ngens*(n+1)] for n in xrange(d-y.degree())]) + out.extend([y] + [y * CG[ngens * (n + 1)] + for n in range(d - y.degree())]) return C.ideal(out) ########################### - ## Coercion - cpdef _coerce_map_from_(self,S): + # Coercion + cpdef _coerce_map_from_(self, S): """ A ring ``R`` coerces into self, if @@ -729,7 +720,7 @@ cdef class FreeAlgebra_letterplace(Algebra): t*x """ - if self==S or self._current_ring.has_coerce_map_from(S): + if self == S or self._current_ring.has_coerce_map_from(S): return True cdef int i # Do we have another letterplace algebra? @@ -747,7 +738,7 @@ cdef class FreeAlgebra_letterplace(Algebra): # Do the degrees match degs = self._degrees Sdegs = (S)._degrees - for i from 0<=i = FreeAlgebra(QQ, implementation='letterplace') sage: F.an_element() # indirect doctest x - """ return FreeAlgebraElement_letterplace(self, self._current_ring.an_element(), check=False) @@ -825,11 +815,11 @@ cdef class FreeAlgebra_letterplace(Algebra): l = len(e) break cdef dict out = {} - self.set_degbound(l/self.__ngens) + self.set_degbound(l // self.__ngens) cdef Py_ssize_t n = self._current_ring.ngens() for e, c in D.iteritems(): - out[tuple(e) + (0,)*(n-l)] = c - return FreeAlgebraElement_letterplace(self,self._current_ring(out), + out[tuple(e) + (0,) * (n - l)] = c + return FreeAlgebraElement_letterplace(self, self._current_ring(out), check=check) def _element_constructor_(self, x): @@ -875,7 +865,7 @@ cdef class FreeAlgebra_letterplace(Algebra): """ if isinstance(x, basestring): from sage.misc.sage_eval import sage_eval - return sage_eval(x,locals=self.gens_dict()) + return sage_eval(x, locals=self.gens_dict()) try: P = x.parent() except AttributeError: @@ -890,9 +880,10 @@ cdef class FreeAlgebra_letterplace(Algebra): Names = self._current_ring.variable_names() PNames = list(Ppoly.variable_names()) # translate the slack variables - PNames[P.ngens(): len(PNames): P.ngens()+1] = list(Names[self.ngens(): len(Names): self.ngens()+1])[:P.degbound()] + PNames[P.ngens(): len(PNames): P.ngens() + 1] = list(Names[self.ngens(): len(Names): self.ngens() + 1])[:P.degbound()] x = Ppoly.hom([Gens[Names.index(asdf)] for asdf in PNames])(x.letterplace_polynomial()) - return FreeAlgebraElement_letterplace(self,self._current_ring(x)) + return FreeAlgebraElement_letterplace(self, self._current_ring(x)) + cdef class FreeAlgebra_letterplace_libsingular(): """ diff --git a/src/sage/algebras/letterplace/letterplace_ideal.pyx b/src/sage/algebras/letterplace/letterplace_ideal.pyx index 56ec1c3d399..747ba2ca6e0 100644 --- a/src/sage/algebras/letterplace/letterplace_ideal.pyx +++ b/src/sage/algebras/letterplace/letterplace_ideal.pyx @@ -1,9 +1,8 @@ """ Homogeneous ideals of free algebras -For twosided ideals and when the base ring is a field, this -implementation also provides Groebner bases and ideal containment -tests. +For twosided ideals and when the base ring is a field, this implementation +also provides Groebner bases and ideal containment tests. EXAMPLES:: @@ -31,9 +30,7 @@ forms and can test containment in the ideal:: AUTHOR: - Simon King (2011-03-22): See :trac:`7797`. - """ - # **************************************************************************** # Copyright (C) 2011 Simon King # @@ -43,7 +40,6 @@ AUTHOR: # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - from sage.rings.noncommutative_ideals import Ideal_nc from sage.libs.singular.function import lib, singular_function from sage.algebras.letterplace.free_algebra_letterplace cimport FreeAlgebra_letterplace, FreeAlgebra_letterplace_libsingular @@ -53,8 +49,9 @@ from sage.rings.infinity import Infinity ##################### # Define some singular functions lib("freegb.lib") -singular_twostd=singular_function("twostd") -poly_reduce=singular_function("NF") +singular_twostd = singular_function("twostd") +poly_reduce = singular_function("NF") + class LetterplaceIdeal(Ideal_nc): """ @@ -159,7 +156,6 @@ class LetterplaceIdeal(Ideal_nc): 0 sage: (z*I.0-x*y*z).normal_form(I) -y*x*z + z*z - """ def __init__(self, ring, gens, coerce=True, side="twosided"): """ @@ -198,6 +194,7 @@ class LetterplaceIdeal(Ideal_nc): Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) self.__GB = self self.__uptodeg = 0 + def groebner_basis(self, degbound=None): """ Twosided Groebner basis with degree bound. @@ -287,17 +284,18 @@ class LetterplaceIdeal(Ideal_nc): return self.__GB if not A.base().is_field(): raise TypeError("Currently, we can only compute Groebner bases if the ring of coefficients is a field") - if self.side()!='twosided': + if self.side() != 'twosided': raise TypeError("This ideal is not two-sided. We can only compute two-sided Groebner bases") if degbound == Infinity: - while self.__uptodeg= 2*max([x._poly.degree() for x in out]): + self.__GB = A.ideal(out, side='twosided', coerce=False) + if degbound >= 2 * max([x._poly.degree() for x in out]): degbound = Infinity self.__uptodeg = degbound self.__GB.__uptodeg = degbound return self.__GB - def __contains__(self,x): + def __contains__(self, x): """ The containment test is based on a normal form computation. @@ -349,7 +347,6 @@ class LetterplaceIdeal(Ideal_nc): True sage: 1 in I False - """ R = self.ring() return (x in R) and R(x).normal_form(self).is_zero() @@ -384,25 +381,26 @@ class LetterplaceIdeal(Ideal_nc): Twosided Ideal (y*z, x*x - y*x - y*y) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field sage: I.reduce(F*[x^2+x*y,y^2+y*z]*F) Twosided Ideal (x*y + y*z, -y*x + y*z) of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field - """ P = self.ring() - if not isinstance(G,(list,tuple)): - if G==P: + if not isinstance(G, (list, tuple)): + if G == P: return P.ideal([P.zero()]) if G in P: return G.normal_form(self) G = G.gens() C = P.current_ring() - sI = C.ideal([C(X.letterplace_polynomial()) for X in self.gens()], coerce=False) + sI = C.ideal([C(X.letterplace_polynomial()) for X in self.gens()], + coerce=False) selfdeg = max([x.degree() for x in sI.gens()]) gI = P._reductor_(G, selfdeg) from sage.libs.singular.option import LibSingularOptions libsingular_options = LibSingularOptions() - bck = (libsingular_options['redTail'],libsingular_options['redSB']) + bck = (libsingular_options['redTail'], libsingular_options['redSB']) libsingular_options['redTail'] = True libsingular_options['redSB'] = True - sI = poly_reduce(sI,gI, ring=C, attributes={gI:{"isSB":1}}) + sI = poly_reduce(sI, gI, ring=C, attributes={gI: {"isSB": 1}}) libsingular_options['redTail'] = bck[0] libsingular_options['redSB'] = bck[1] - return P.ideal([FreeAlgebraElement_letterplace(P,x,check=False) for x in sI], coerce=False) + return P.ideal([FreeAlgebraElement_letterplace(P, x, check=False) + for x in sI], coerce=False) From 75fa0fd06de3066a035d927c1e6eca2557daaa26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 2 Oct 2022 21:43:01 +0200 Subject: [PATCH 253/350] using the :kbd: role in the documentation (for Tab and other keys) --- src/doc/en/developer/coding_basics.rst | 2 +- src/doc/en/faq/faq-usage.rst | 4 +-- src/doc/en/prep/Intro-Tutorial.rst | 12 ++++---- .../en/thematic_tutorials/group_theory.rst | 4 +-- src/doc/en/tutorial/latex.rst | 2 +- src/doc/en/tutorial/tour_help.rst | 11 ++++--- src/doc/ja/tutorial/latex.rst | 2 +- src/sage/algebras/catalog.py | 2 +- src/sage/combinat/path_tableaux/catalog.py | 2 +- src/sage/combinat/words/word.py | 30 +++++++++---------- src/sage/combinat/words/word_generators.py | 14 ++++----- src/sage/databases/sql_db.py | 6 ++-- .../dynamics/cellular_automata/catalog.py | 2 +- src/sage/graphs/graph_database.py | 3 +- src/sage/graphs/graph_generators.py | 2 +- src/sage/groups/groups_catalog.py | 2 +- src/sage/interfaces/giac.py | 2 +- src/sage/interfaces/interface.py | 4 ++- src/sage/interfaces/maple.py | 2 +- src/sage/interfaces/qepcad.py | 12 ++++---- src/sage/manifolds/catalog.py | 2 +- src/sage/matroids/constructor.py | 10 +++---- src/sage/matroids/matroids_catalog.py | 4 +-- src/sage/misc/trace.py | 2 +- src/sage/sandpiles/examples.py | 2 +- src/sage/topology/delta_complex.py | 2 +- .../topology/simplicial_complex_catalog.py | 2 +- .../topology/simplicial_complex_examples.py | 2 +- 28 files changed, 74 insertions(+), 72 deletions(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index 4f208b8e357..0371341a3ab 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -44,7 +44,7 @@ In particular, - Use 4 spaces for indentation levels. Do not use tabs as they can result in indentation confusion. Most editors have a feature that - will insert 4 spaces when the tab key is hit. Also, many editors + will insert 4 spaces when the :kbd:`Tab` key is hit. Also, many editors will automatically search/replace leading tabs with 4 spaces. - Whitespace before and after assignment and binary operator of the diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 9d5f2cbeb95..d072057189e 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -229,9 +229,9 @@ Can I do X in Sage? """"""""""""""""""" You are encouraged to use Sage's tab autocompletion. Just type a few -characters, hit the tab key, and see if the command you want appears +characters, hit the :kbd:`Tab` key, and see if the command you want appears in the list of tab autocompletion. If you have a command called -``mycmd``, then type ``mycmd.`` and hit the tab key to get a list of +``mycmd``, then type ``mycmd.`` and hit the :kbd:`Tab` key to get a list of functionalities that are supported by that command. To read the documentation of ``mycmd``, type ``mycmd?`` and press the enter key to read the documentation for that command. Similarly, type ``mycmd??`` diff --git a/src/doc/en/prep/Intro-Tutorial.rst b/src/doc/en/prep/Intro-Tutorial.rst index 2febd01ac19..cdd785df05f 100644 --- a/src/doc/en/prep/Intro-Tutorial.rst +++ b/src/doc/en/prep/Intro-Tutorial.rst @@ -365,7 +365,7 @@ Here's an example. - Still, it seems reasonable that the command might start with ``pl``. -- Then one can type ``pl`` in an input cell, and then press the tab key +- Then one can type ``pl`` in an input cell, and then press the :kdb:`Tab` key to see all the commands that start with the letters ``pl``. Try tabbing after the ``pl`` in the following cell to see all the @@ -379,7 +379,7 @@ commands that start with the letters ``pl``. You should see that sage: pl To pick one, just click on it; to stop viewing them, press the -Escape/esc key. +:kbd:`Escape` key. You can also use this to see what you can do to an expression or mathematical object. @@ -399,7 +399,7 @@ defined. sage: f(x)=x^2 -Now put your cursor after the period and press your tab key. +Now put your cursor after the period and press your :kbd:`Tab` key. .. skip @@ -407,7 +407,7 @@ Now put your cursor after the period and press your tab key. sage: f. -Again, Escape should remove the list. +Again, :kbd:`Escape` should remove the list. One of the things in that list above was ``integrate``. Let's try it. @@ -437,7 +437,7 @@ that can illustrate how to use the function. - Press tab *or* evaluate to see the documentation. To see how this help works, move your cursor after the question mark -below and press tab. +below and press :kbd:`Tab`. .. skip @@ -450,7 +450,7 @@ not just ``f.integrate()``. (After all, the latter could be ambiguous if several variables had already been defined). To stop viewing the documentation after pressing tab, you can press the -Escape key, just like with the completion of options. +:kbd:`Escape` key, just like with the completion of options. If you would like the documentation to be visible longer\-term, you can *evaluate* a command with the question mark (like below) to access the diff --git a/src/doc/en/thematic_tutorials/group_theory.rst b/src/doc/en/thematic_tutorials/group_theory.rst index ca45acf7082..8323abb26f2 100644 --- a/src/doc/en/thematic_tutorials/group_theory.rst +++ b/src/doc/en/thematic_tutorials/group_theory.rst @@ -318,7 +318,7 @@ since `\sigma` is an odd permutation. Many more available functions that can be applied to a permutation can be found via "tab-completion." With ``sigma`` defined as an element of a permutation group, in a Sage cell, type ``sigma.`` (Note the -"``.``") and then press the tab key. You will get a list of available +"``.``") and then press the :kbd:`Tab` key. You will get a list of available functions (you may need to scroll down to see the whole list). Experiment and explore! It is what Sage is all about. You really cannot break anything. @@ -359,7 +359,7 @@ and then a variety of functions become available. After trying the examples below, experiment with tab-completion. Having defined ``H``, type ``H.`` (note the "``.``") and then press -the tab key. You will get a list of available functions (you may need +the :kbd:`Tab` key. You will get a list of available functions (you may need to scroll down to see the whole list). As before, *experiment and explore*---it is really hard to break anything. diff --git a/src/doc/en/tutorial/latex.rst b/src/doc/en/tutorial/latex.rst index 5c10f4ac183..b9297a1cfab 100644 --- a/src/doc/en/tutorial/latex.rst +++ b/src/doc/en/tutorial/latex.rst @@ -151,7 +151,7 @@ Customizing LaTeX Generation There are several ways to customize the actual LaTeX code generated by the ``latex()`` command. In the notebook and at the Sage command-line there is a pre-defined object named ``latex`` which has several methods, -which you can list by typing ``latex.``, followed by the tab key +which you can list by typing ``latex.``, followed by the :kbd:`Tab` key (note the period). A good example is the ``latex.matrix_delimiters`` method. It can be diff --git a/src/doc/en/tutorial/tour_help.rst b/src/doc/en/tutorial/tour_help.rst index c66c24e470b..87bce8c60e1 100644 --- a/src/doc/en/tutorial/tour_help.rst +++ b/src/doc/en/tutorial/tour_help.rst @@ -94,12 +94,11 @@ question mark: [6 3 5 1 7 2 8 9 4] [4 9 1 8 5 6 7 2 3] -Sage also provides 'Tab completion': type the first few letters of -a function and then hit the tab key. For example, if you type ``ta`` -followed by ``TAB``, Sage will print -``tachyon, tan, tanh, -taylor``. This provides a good way to find -the names of functions and other structures in Sage. +Sage also provides 'Tab completion': type the first few letters of a +function and then hit the :kbd:`Tab` key. For example, if you type +``ta`` followed by :kbd:`Tab`, Sage will print ``tachyon, tan, tanh, +taylor``. This provides a good way to find the names of functions and +other structures in Sage. .. _section-functions: diff --git a/src/doc/ja/tutorial/latex.rst b/src/doc/ja/tutorial/latex.rst index 72fa3d0e162..e02d8507eb6 100644 --- a/src/doc/ja/tutorial/latex.rst +++ b/src/doc/ja/tutorial/latex.rst @@ -124,7 +124,7 @@ LaTeXコード生成のカスタマイズ .. There are several ways to customize the actual LaTeX code generated by .. the ``latex()`` command. In the notebook and at the Sage command-line .. there is a pre-defined object named ``latex`` which has several methods, -.. which you can list by typing ``latex.``, followed by the tab key +.. which you can list by typing ``latex.``, followed by the :kbd:`Tab` key .. (note the period). ここでは ``latex.matrix_delimiters`` メソッドに注目してみよう. diff --git a/src/sage/algebras/catalog.py b/src/sage/algebras/catalog.py index a3c8aa161ed..1ccf517e2c0 100644 --- a/src/sage/algebras/catalog.py +++ b/src/sage/algebras/catalog.py @@ -6,7 +6,7 @@ easy way to discover and quickly create the algebras that are available (as listed here). -Let ```` indicate pressing the tab key. So begin by typing +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing ``algebras.`` to the see the currently implemented named algebras. - :class:`algebras.AlternatingCentralExtensionQuantumOnsager diff --git a/src/sage/combinat/path_tableaux/catalog.py b/src/sage/combinat/path_tableaux/catalog.py index 8cb7f2d322d..0605c6da583 100644 --- a/src/sage/combinat/path_tableaux/catalog.py +++ b/src/sage/combinat/path_tableaux/catalog.py @@ -6,7 +6,7 @@ object is an easy way to discover and quickly create the path tableaux that are available (as listed here). -Let ```` indicate pressing the tab key. So begin by typing +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing ``path_tableaux.`` to the see the currently implemented path tableaux. - :class:`~sage.combinat.path_tableaux.path_tableau.CylindricalDiagram` diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 85974ec33e7..393782bf17e 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -283,7 +283,7 @@ class FiniteWord_list(WordDatatype_list, FiniteWord_class): r""" Finite word represented by a Python list. - For any word `w`, type ``w.`` and hit TAB key to see the list of + For any word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -304,7 +304,7 @@ class FiniteWord_str(WordDatatype_str, FiniteWord_class): r""" Finite word represented by a Python str. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -325,7 +325,7 @@ class FiniteWord_tuple(WordDatatype_tuple, FiniteWord_class): r""" Finite word represented by a Python tuple. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -346,7 +346,7 @@ class FiniteWord_iter_with_caching(WordDatatype_iter_with_caching, FiniteWord_cl r""" Finite word represented by an iterator (with caching). - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -372,7 +372,7 @@ class FiniteWord_iter(WordDatatype_iter, FiniteWord_class): r""" Finite word represented by an iterator. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -400,7 +400,7 @@ class FiniteWord_callable_with_caching(WordDatatype_callable_with_caching, Finit r""" Finite word represented by a callable (with caching). - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -451,7 +451,7 @@ class FiniteWord_callable(WordDatatype_callable, FiniteWord_class): r""" Finite word represented by a callable. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -482,7 +482,7 @@ class InfiniteWord_iter_with_caching(WordDatatype_iter_with_caching, InfiniteWor r""" Infinite word represented by an iterable (with caching). - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Infinite words behave like a Python list : they can be sliced using @@ -520,7 +520,7 @@ class InfiniteWord_iter(WordDatatype_iter, InfiniteWord_class): r""" Infinite word represented by an iterable. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Infinite words behave like a Python list : they can be sliced using @@ -558,7 +558,7 @@ class InfiniteWord_callable_with_caching(WordDatatype_callable_with_caching, Inf r""" Infinite word represented by a callable (with caching). - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Infinite words behave like a Python list : they can be sliced using @@ -588,7 +588,7 @@ class InfiniteWord_callable(WordDatatype_callable, InfiniteWord_class): r""" Infinite word represented by a callable. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Infinite words behave like a Python list : they can be sliced using @@ -622,7 +622,7 @@ class Word_iter_with_caching(WordDatatype_iter_with_caching, Word_class): Word of unknown length (finite or infinite) represented by an iterable (with caching). - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Words behave like a Python list : they can be sliced using @@ -658,7 +658,7 @@ class Word_iter(WordDatatype_iter, Word_class): Word of unknown length (finite or infinite) represented by an iterable. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Words behave like a Python list : they can be sliced using @@ -694,7 +694,7 @@ class FiniteWord_morphic(WordDatatype_morphic, FiniteWord_class): r""" Finite morphic word. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. EXAMPLES:: @@ -721,7 +721,7 @@ class InfiniteWord_morphic(WordDatatype_morphic, InfiniteWord_class): r""" Morphic word of infinite length. - For such word `w`, type ``w.`` and hit TAB key to see the list of + For such word `w`, type ``w.`` and hit :kbd:`Tab` key to see the list of functions defined on `w`. Infinite words behave like a Python list : they can be sliced using diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index e7110609d63..f68ce484b23 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -5,16 +5,16 @@ AUTHORS: - Franco Saliola (2008-12-17): merged into sage -- Sebastien Labbe (2008-12-17): merged into sage +- Sébastien Labbé (2008-12-17): merged into sage - Arnaud Bergeron (2008-12-17): merged into sage - Amy Glen (2008-12-17): merged into sage - Sébastien Labbé (2009-12-19): Added S-adic words (:trac:`7543`) USE: -To see a list of all word constructors, type ``words.`` and then press the tab -key. The documentation for each constructor includes information about each -word, which provides a useful reference. +To see a list of all word constructors, type ``words.`` and then press +the :kbd:`Tab` key. The documentation for each constructor includes +information about each word, which provides a useful reference. REFERENCES: @@ -22,11 +22,11 @@ numbers with a regular expansion, J. Number Theory 103 (2003) 27--37. -.. [BmBGL07] \A. Blondin-Masse, S. Brlek, A. Glen, and S. Labbe. On the +.. [BmBGL07] \A. Blondin-Massé, S. Brlek, A. Glen, and S. Labbé. On the critical exponent of generalized Thue-Morse words. *Discrete Math. Theor. Comput. Sci.* 9 (1):293--304, 2007. -.. [BmBGL09] \A. Blondin-Masse, S. Brlek, A. Garon, and S. Labbe. Christoffel +.. [BmBGL09] \A. Blondin-Massé, S. Brlek, A. Garon, and S. Labbé. Christoffel and Fibonacci Tiles, DGCI 2009, Montreal, to appear in LNCS. .. [Loth02] \M. Lothaire, Algebraic Combinatorics On Words, vol. 90 of @@ -351,7 +351,7 @@ class WordGenerator(): .. NOTE:: To see a list of all word constructors, type ``words.`` and then - hit the TAB key. The documentation for each constructor + hit the :kbd:`Tab` key. The documentation for each constructor includes information about each word, which provides a useful reference. diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py index 5e29cad2685..087c494ef39 100644 --- a/src/sage/databases/sql_db.py +++ b/src/sage/databases/sql_db.py @@ -1259,8 +1259,10 @@ def get_skeleton(self, check=False): def query(self, *args, **kwds): """ - Create a ``SQLQuery`` on this database. For full class details, - type ``SQLQuery?`` and press shift+enter. + Create a ``SQLQuery`` on this database. + + For full class details, + type ``SQLQuery?`` and press :kbd:`Shift` + :kbd:`Enter`. EXAMPLES:: diff --git a/src/sage/dynamics/cellular_automata/catalog.py b/src/sage/dynamics/cellular_automata/catalog.py index 480f073bf7a..44c28f07cb5 100644 --- a/src/sage/dynamics/cellular_automata/catalog.py +++ b/src/sage/dynamics/cellular_automata/catalog.py @@ -6,7 +6,7 @@ this object is an easy way to discover and quickly create the cellular automata that are available (as listed here). -Let ```` indicate pressing the tab key. So begin by typing +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing ``cellular_automata.`` to the see the currently implemented named cellular automata. diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index f416d7c04ee..3c9021bd8cc 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -967,7 +967,8 @@ def query(self, query_dict=None, display_cols=None, **kwds): """ Create a GraphQuery on this database. - For full class details, type ``GraphQuery?`` and press ``shift+enter``. + For full class details, type ``GraphQuery?`` + and press :kbd:`Shift` + :kdb:`Enter`. EXAMPLES:: diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 9a8c0877d3d..6987740a67b 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -484,7 +484,7 @@ class GraphGenerators(): A list of all graphs and graph structures (other than isomorphism class representatives) in this database is available via tab completion. Type - "graphs." and then hit the tab key to see which graphs are available. + "graphs." and then hit the :kbd:`Tab` key to see which graphs are available. The docstrings include educational information about each named graph with the hopes that this class can be used as a reference. diff --git a/src/sage/groups/groups_catalog.py b/src/sage/groups/groups_catalog.py index 1bdd1a46346..e3da7f10780 100644 --- a/src/sage/groups/groups_catalog.py +++ b/src/sage/groups/groups_catalog.py @@ -5,7 +5,7 @@ Using tab-completion on this object is an easy way to discover and quickly create the groups that are available (as listed here). -Let ```` indicate pressing the tab key. So begin by typing +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing ``groups.`` to the see primary divisions, followed by (for example) ``groups.matrix.`` to access various groups implemented as sets of matrices. diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 87ff828edec..98381afeea3 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -133,7 +133,7 @@ Another important feature of giac is its online help. We can access this through sage as well. After reading the description of -the command, you can press q to immediately get back to your +the command, you can press :kbd:`q` to immediately get back to your original prompt. Incidentally you can always get into a giac console by the diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 47ccd0cdbff..7e612f049f2 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -173,7 +173,9 @@ def set_seed(self, seed=None): def interact(self): r""" This allows you to interactively interact with the child - interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and + interpreter. + + Press :kbd:`Ctrl` + :kbd:`D` or type 'quit' or 'exit' to exit and return to Sage. .. note:: diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index b3818b73dec..50a2d803d25 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -105,7 +105,7 @@ Another important feature of maple is its online help. We can access this through sage as well. After reading the description of -the command, you can press q to immediately get back to your +the command, you can press :kbd:`q` to immediately get back to your original prompt. Incidentally you can always get into a maple console by the diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index d4b10353e0c..8adddead331 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -595,16 +595,15 @@ - Carl Witty (2008-03): initial version - Thierry Monteil (2015-07) repackaging + noncommutative doctests. """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Carl Witty # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** +import os from sage.env import SAGE_LOCAL import pexpect import re @@ -1676,10 +1675,9 @@ def qepcad(formula, assume=None, interact=False, solution=None, raise ValueError("Unknown solution type ({})".format(solution)) -import os def qepcad_console(memcells=None): r""" - Run QEPCAD directly. To exit early, press Control-C. + Run QEPCAD directly. To exit early, press :kbd:`Control` + :kbd:`C`. EXAMPLES:: diff --git a/src/sage/manifolds/catalog.py b/src/sage/manifolds/catalog.py index 62fc5710d6f..7dcdad7b113 100644 --- a/src/sage/manifolds/catalog.py +++ b/src/sage/manifolds/catalog.py @@ -4,7 +4,7 @@ A catalog of manifolds to rapidly create various simple manifolds. The current entries to the catalog are obtained by typing -``manifolds.``, where ```` indicates pressing the tab key. +``manifolds.``, where ```` indicates pressing the :kbd:`Tab` key. They are: - :class:`~sage.manifolds.differentiable.examples.euclidean.EuclideanSpace`: Euclidean space diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 11c1ae4bbbc..1fb2cd2b93e 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -34,9 +34,9 @@ For built-in matroids, do the following: -* Within a Sage session, type ``matroids.`` (Do not press "Enter", and do not - forget the final period ".") -* Hit "tab". +* Within a Sage session, type ``matroids.`` (Do not press :kbd:`Enter`, + and do not forget the final period ".") +* Hit :kbd:`Tab`. You will see a list of methods which will construct matroids. For example:: @@ -140,9 +140,9 @@ def Matroid(groundset=None, data=None, **kwds): There are two main entry points to Sage's matroid functionality. For built-in matroids, do the following: - * Within a Sage session, type "matroids." (Do not press "Enter", and do + * Within a Sage session, type "matroids." (Do not press :kbd:`Enter`, and do not forget the final period ".") - * Hit "tab". + * Hit :kbd:`Tab`. You will see a list of methods which will construct matroids. For example:: diff --git a/src/sage/matroids/matroids_catalog.py b/src/sage/matroids/matroids_catalog.py index 2c9e607cbbe..1fc55a58cf2 100644 --- a/src/sage/matroids/matroids_catalog.py +++ b/src/sage/matroids/matroids_catalog.py @@ -3,8 +3,8 @@ A module containing constructors for several common matroids. -A list of all matroids in this module is available via tab -completion. Let ```` indicate pressing the tab key. So begin by typing +A list of all matroids in this module is available via tab completion. +Let ```` indicate pressing the :kbd:`Tab` key. So begin by typing ``matroids.`` to see the various constructions available. Many special matroids can be accessed from the submenu ``matroids.named_matroids.``. diff --git a/src/sage/misc/trace.py b/src/sage/misc/trace.py index 241342a452b..2547426bc0a 100644 --- a/src/sage/misc/trace.py +++ b/src/sage/misc/trace.py @@ -28,7 +28,7 @@ def trace(code, preparse=True): sage: trace("factor(100)") # not tested - then at the (Pdb) prompt type ``s`` (or ``step``), then press return + then at the (Pdb) prompt type ``s`` (or ``step``), then press :kbd:`Return` over and over to step through every line of Python that is called in the course of the above computation. Type ``?`` at any time for help on how to use the debugger (e.g., ``l`` lists 11 lines around diff --git a/src/sage/sandpiles/examples.py b/src/sage/sandpiles/examples.py index b34129f3ed8..9ccc08d314f 100644 --- a/src/sage/sandpiles/examples.py +++ b/src/sage/sandpiles/examples.py @@ -11,7 +11,7 @@ The examples are accessible by typing ``sandpiles.NAME``, where ``NAME`` is the name of the example. You can get a list by typing -``sandpiles.`` and hitting the TAB key:: +``sandpiles.`` and hitting the :kbd:`Tab` key:: sandpiles.Complete sandpiles.Cycle diff --git a/src/sage/topology/delta_complex.py b/src/sage/topology/delta_complex.py index 8cbdcf5d293..420fd2fad5a 100644 --- a/src/sage/topology/delta_complex.py +++ b/src/sage/topology/delta_complex.py @@ -235,7 +235,7 @@ class DeltaComplex(GenericCellComplex): sage: delta_complexes.RealProjectivePlane() Delta complex with 2 vertices and 8 simplices - Type ``delta_complexes.`` and then hit the TAB key to get the + Type ``delta_complexes.`` and then hit the :kbd:`Tab` key to get the full list. """ def __init__(self, data=None, check_validity=True): diff --git a/src/sage/topology/simplicial_complex_catalog.py b/src/sage/topology/simplicial_complex_catalog.py index 07a0de43b4a..6e86db14cb5 100644 --- a/src/sage/topology/simplicial_complex_catalog.py +++ b/src/sage/topology/simplicial_complex_catalog.py @@ -49,7 +49,7 @@ - :meth:`~sage.topology.examples.ZieglerBall` You can also get a list by typing ``simplicial_complexes.`` and hitting the -TAB key. +:kbd:`Tab` key. EXAMPLES:: diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index a21391beab3..65914f47830 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -49,7 +49,7 @@ - :func:`ZieglerBall` You can also get a list by typing ``simplicial_complexes.`` and hitting the -TAB key. +:kbd:`Tab` key. EXAMPLES:: From fbf30830a63cfc099a86f99b9db7adfc26c6b9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 2 Oct 2022 21:58:52 +0200 Subject: [PATCH 254/350] a few more --- src/doc/en/prep/Advanced-2DPlotting.rst | 7 ++++--- src/doc/en/prep/Calculus.rst | 8 ++++---- src/doc/en/prep/Intro-Tutorial.rst | 5 +++-- src/doc/en/prep/Symbolics-and-Basic-Plotting.rst | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/doc/en/prep/Advanced-2DPlotting.rst b/src/doc/en/prep/Advanced-2DPlotting.rst index 337457afef4..633e33d68b3 100644 --- a/src/doc/en/prep/Advanced-2DPlotting.rst +++ b/src/doc/en/prep/Advanced-2DPlotting.rst @@ -39,9 +39,10 @@ following sections: - :ref:`Saving` -This tutorial assumes that one is familiar with the basics of Sage, such -as evaluating a cell by clicking the "evaluate" link, or by pressing -Shift\-Enter (hold down Shift while pressing the Enter key). +This tutorial assumes that one is familiar with the basics of Sage, +such as evaluating a cell by clicking the "evaluate" link, or by +pressing :kbd:`Shift` + :kbd:`Enter` (hold down :kbd:`Shift` while +pressing the :kbd:`Enter` key). .. fixme - if log plots are in by the time this makes it in, put them in!!! diff --git a/src/doc/en/prep/Calculus.rst b/src/doc/en/prep/Calculus.rst index 8c9ea73777b..af6902b9e04 100644 --- a/src/doc/en/prep/Calculus.rst +++ b/src/doc/en/prep/Calculus.rst @@ -29,10 +29,10 @@ the United States; the final section is a checkpoint of sorts. The tutorial assumes that one is familiar with the basics of Sage, such as outlined in the previous tutorials. -For a refresher, make sure the syntax below for defining a function and -getting a value makes sense; then evaluate the cell by clicking the -"evaluate" link, or by pressing Shift\-Enter (hold down Shift while -pressing the Enter key). +For a refresher, make sure the syntax below for defining a function +and getting a value makes sense; then evaluate the cell by clicking +the "evaluate" link, or by pressing :kbd:`Shift` + :kbd:`Enter` (hold +down :kbd:`Shift` while pressing the :kbd:`Enter` key). :: diff --git a/src/doc/en/prep/Intro-Tutorial.rst b/src/doc/en/prep/Intro-Tutorial.rst index cdd785df05f..69de4542142 100644 --- a/src/doc/en/prep/Intro-Tutorial.rst +++ b/src/doc/en/prep/Intro-Tutorial.rst @@ -75,8 +75,9 @@ To do math in a Jupyter cell, one must do two things. .. image:: media/RunCellIcon.png :align: center - Or one can use the keyboard shortcut of holding down the Shift key - while you press the Enter key. We call this "Shift\-Enter". + Or one can use the keyboard shortcut of holding down the :kbd:`Shift` key + while you press the :kbd:`Enter` key. + We call this :kbd:`Shift` + :kbd:`Enter`. Sage prints out its response just below the cell (that's the ``4`` below, so Sage confirms that :math:`2+2=4`). Note also that Sage has diff --git a/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst b/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst index c6da1f7c112..6e0ab69765a 100644 --- a/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst +++ b/src/doc/en/prep/Symbolics-and-Basic-Plotting.rst @@ -29,7 +29,8 @@ and evaluation in Sage. We provide a (very) brief refresher. value makes sense. #. Then evaluate the cell by clicking the "evaluate" link, or by - pressing Shift\-Enter (hold down Shift while pressing the Enter key). + pressing :kbd:`Shift` + :kbd:`Enter` (hold down :kbd:`Shift` + while pressing the :kbd:`Enter` key). :: From 78f9a47421039ac0905fe6391986f8d44e456c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 2 Oct 2022 22:04:15 +0200 Subject: [PATCH 255/350] again a few more :kbd: --- src/doc/en/prep/Intro-Tutorial.rst | 2 +- src/sage/graphs/digraph_generators.py | 2 +- src/sage/graphs/graph_generators.py | 2 +- src/sage/interfaces/kash.py | 7 +++---- src/sage/libs/singular/function.pyx | 6 +++--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/doc/en/prep/Intro-Tutorial.rst b/src/doc/en/prep/Intro-Tutorial.rst index 69de4542142..e3906bd0f56 100644 --- a/src/doc/en/prep/Intro-Tutorial.rst +++ b/src/doc/en/prep/Intro-Tutorial.rst @@ -450,7 +450,7 @@ The examples illustrate that the syntax requires ``f.integrate(x)`` and not just ``f.integrate()``. (After all, the latter could be ambiguous if several variables had already been defined). -To stop viewing the documentation after pressing tab, you can press the +To stop viewing the documentation after pressing :kbd:`Tab`, you can press the :kbd:`Escape` key, just like with the completion of options. If you would like the documentation to be visible longer\-term, you can diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index cceb89df765..f1d88178ebb 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -12,7 +12,7 @@ sage: p = digraphs.Circulant(10,[2,3]) More interestingly, one can get the list of all digraphs that Sage knows how to -build by typing ``digraphs.`` in Sage and then hitting tab. +build by typing ``digraphs.`` in Sage and then hitting :kbd:`Tab`. .. csv-table:: :class: contentstable diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 6987740a67b..ac9f329dfb3 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -13,7 +13,7 @@ sage: h = graphs.HouseGraph() More interestingly, one can get the list of all graphs that Sage knows how to -build by typing ``graphs.`` in Sage and then hitting tab. +build by typing ``graphs.`` in Sage and then hitting :kbd:`Tab`. """ import subprocess diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index ce837b87737..bc389c74a07 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -38,14 +38,13 @@ Issues ------ -For some reason hitting Control-C to interrupt a calculation -doesn't work correctly. (TODO) +For some reason hitting :kbd:`Control` + :kbd:`C` to interrupt a calculation +does not work correctly. (TODO) Tutorial -------- -The examples in this tutorial require that kash -be installed. +The examples in this tutorial require that kash be installed. Basics ~~~~~~ diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index d7255b34440..74595b7c367 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1200,8 +1200,8 @@ cdef class SingularFunction(SageObject): - ``args`` -- a list of arguments - ``ring`` -- a multivariate polynomial ring - - ``interruptible`` -- if ``True`` pressing Ctrl-C during the - execution of this function will interrupt the computation + - ``interruptible`` -- if ``True`` pressing :kbd:`Ctrl` + :kbd:`C` + during the execution of this function will interrupt the computation (default: ``True``) - ``attributes`` -- a dictionary of optional Singular @@ -1332,7 +1332,7 @@ INPUT: - ``args`` -- a list of arguments - ``ring`` -- a multivariate polynomial ring -- ``interruptible`` -- if ``True`` pressing Ctrl-C during the +- ``interruptible`` -- if ``True`` pressing :kbd:`Ctrl` + :kbd:`C` during the execution of this function will interrupt the computation (default: ``True``) - ``attributes`` -- a dictionary of optional Singular attributes From 156914a3dad38540e669fefe651247f5e46a3d00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 2 Oct 2022 17:54:00 +0200 Subject: [PATCH 256/350] refresh the file free_quadratic_module --- src/sage/modules/free_quadratic_module.py | 470 +++++++++++----------- 1 file changed, 233 insertions(+), 237 deletions(-) diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index 8710352f87a..b17a0b4eaa9 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -8,9 +8,9 @@ can specify and change. Create the free module of rank `n` over an arbitrary commutative ring `R` -using the command ``FreeModule(R,n)`` with a given inner_product_matrix. +using the command ``FreeModule(R,n)`` with a given ``inner_product_matrix``. -The following example illustrates the creation of both a vector spaces +The following example illustrates the creation of both a vector space and a free module over the integers and a submodule of it. Use the functions ``FreeModule``, ``span`` and member functions of free modules to create free modules. ''Do not use the ``FreeModule_xxx`` constructors @@ -56,7 +56,6 @@ - David Kohel (2008-06): First created (based on free_module.py) """ - # **************************************************************************** # Copyright (C) 2008 David Kohel # @@ -66,39 +65,38 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - import weakref import sage.matrix.matrix_space import sage.misc.latex as latex import sage.rings.ring as ring -import sage.rings.integer from sage.categories.principal_ideal_domains import PrincipalIdealDomains from . import free_module -############################################################################### +# ############################################################################# # # Constructor functions # -############################################################################### +# ############################################################################# _cache = {} -def FreeQuadraticModule( - base_ring, rank, inner_product_matrix, sparse=False, inner_product_ring=None): + +def FreeQuadraticModule(base_ring, rank, inner_product_matrix, + sparse=False, inner_product_ring=None): r""" Create the free quadratic module over the given commutative ring of the given rank. INPUT: - - base_ring -- a commutative ring + - ``base_ring`` -- a commutative ring - - rank -- a nonnegative integer + - ``rank`` -- a nonnegative integer - - inner_product_matrix -- the inner product matrix + - ``inner_product_matrix`` -- the inner product matrix - - sparse -- bool; (default False) + - ``sparse`` -- bool; (default ``False``) - - inner_product_ring -- the inner product codomain ring; (default None) + - ``inner_product_ring`` -- the inner product codomain ring; (default ``None``) OUTPUT: @@ -106,9 +104,9 @@ def FreeQuadraticModule( .. NOTE:: - In Sage it is the case that there is only one dense and one - sparse free ambient quadratic module of rank `n` over `R` and given - inner product matrix. + In Sage, it is the case that there is only one dense and one + sparse free ambient quadratic module of rank `n` over `R` and + given inner product matrix. EXAMPLES:: @@ -140,7 +138,7 @@ def FreeQuadraticModule( # In order to use coercion into the inner_product_ring we need to pass # this ring into the vector classes. if inner_product_ring is not None: - raise NotImplementedError("An inner_product_ring cannot currently be defined.") + raise NotImplementedError("an inner_product_ring cannot currently be defined") # We intentionally create a new matrix instead of using the given # inner_product_matrix. This ensures that the matrix has the correct @@ -162,11 +160,11 @@ def FreeQuadraticModule( if not base_ring.is_commutative(): raise TypeError("base_ring must be a commutative ring") - #elif not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): - # M = RealDoubleQuadraticSpace_class(rank, inner_product_matrix=inner_product_matrix, sparse=False) + # elif not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): + # M = RealDoubleQuadraticSpace_class(rank, inner_product_matrix=inner_product_matrix, sparse=False) - #elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class): - # M = ComplexDoubleQuadraticSpace_class(rank, inner_product_matrix=inner_product_matrix, sparse=False) + # elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class): + # M = ComplexDoubleQuadraticSpace_class(rank, inner_product_matrix=inner_product_matrix, sparse=False) elif base_ring.is_field(): M = FreeQuadraticModule_ambient_field( @@ -186,6 +184,7 @@ def FreeQuadraticModule( _cache[key] = weakref.ref(M) return M + def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): """ EXAMPLES: @@ -213,25 +212,27 @@ def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): sage: QuadraticSpace(ZZ,5,identity_matrix(ZZ,2)) Traceback (most recent call last): ... - TypeError: Argument K (= Integer Ring) must be a field. + TypeError: argument K (= Integer Ring) must be a field """ if not K.is_field(): - raise TypeError("Argument K (= %s) must be a field." % K) + raise TypeError(f"argument K (= {K}) must be a field") if sparse not in (True, False): raise TypeError("Argument sparse (= %s) must be a boolean." % sparse) return FreeQuadraticModule(K, rank=dimension, inner_product_matrix=inner_product_matrix, sparse=sparse) + InnerProductSpace = QuadraticSpace -############################################################################### + +# ############################################################################# # # Base class for all free modules # -############################################################################### +# ############################################################################# def is_FreeQuadraticModule(M): """ - Return True if `M` is a free quadratic module. + Return ``True`` if `M` is a free quadratic module. EXAMPLES:: @@ -248,6 +249,7 @@ def is_FreeQuadraticModule(M): """ return isinstance(M, FreeQuadraticModule_generic) + class FreeQuadraticModule_generic(free_module.FreeModule_generic): """ Base class for all free quadratic modules. @@ -302,13 +304,13 @@ class FreeQuadraticModule_generic(free_module.FreeModule_generic): """ def __init__(self, base_ring, rank, degree, inner_product_matrix, sparse=False): """ - Create the free module of given rank over the given base_ring. + Create the free module of given rank over the given ``base_ring``. INPUT: - - base_ring -- a commutative ring + - ``base_ring`` -- a commutative ring - - rank -- a non-negative integer + - ``rank`` -- a non-negative integer EXAMPLES:: @@ -326,9 +328,9 @@ def __init__(self, base_ring, rank, degree, inner_product_matrix, sparse=False): def _dense_module(self): """ - Creates a dense module with the same defining data as self. + Create a dense module with the same defining data as ``self``. - N.B. This function is for internal use only! See dense_module for use. + .. NOTE:: This function is for internal use only! See ``dense_module`` for use. EXAMPLES:: @@ -343,9 +345,9 @@ def _dense_module(self): def _sparse_module(self): """ - Creates a sparse module with the same defining data as self. + Create a sparse module with the same defining data as ``self``. - N.B. This function is for internal use only! See sparse_module for use. + .. NOTE:: This function is for internal use only! See ``sparse_module`` for use. EXAMPLES:: @@ -399,9 +401,10 @@ def determinant(self): def discriminant(self): """ - Return the discriminant of this free module, defined to be (-1)^r - of the determinant, where r = n/2 (n even) or (n-1)/2 (n odd) for - a module of rank n. + Return the discriminant of this free module. + + This is defined to be `(-1)^r` of the determinant, where `r = n/2` + (`n` even) or `(n-1)/2` (`n` odd) for a module of rank `n`. EXAMPLES:: @@ -417,23 +420,23 @@ def discriminant(self): TESTS:: - sage: M=FreeQuadraticModule(ZZ,2,matrix.identity(2)) + sage: M = FreeQuadraticModule(ZZ,2,matrix.identity(2)) sage: M.discriminant() -1 - sage: M=FreeQuadraticModule(QQ,3,matrix.identity(3)) + sage: M = FreeQuadraticModule(QQ,3,matrix.identity(3)) sage: M.discriminant() -1 - """ - n = self.rank() - r = n//2 - return (-1)**r*self.gram_matrix().determinant() + r = self.rank() // 2 + return (-1)**r * self.gram_matrix().determinant() def gram_matrix(self): """ - Return the gram matrix associated to this free module, defined to be - G = B*A*B.transpose(), where A is the inner product matrix (induced from - the ambient space), and B the basis matrix. + Return the Gram matrix associated to this free module. + + This is defined to be ``B*A*B.transpose()``, where ``A`` is the + inner product matrix (induced from the ambient space), and ``B`` + the basis matrix. EXAMPLES:: @@ -451,28 +454,30 @@ def gram_matrix(self): [1 1 1] [1 2 1] [1 1 2] - """ if self.is_ambient(): return self.inner_product_matrix() - else: - if self._gram_matrix is None: - A = self.inner_product_matrix() - B = self.basis_matrix() - self._gram_matrix = B*A*B.transpose() - return self._gram_matrix + if self._gram_matrix is None: + A = self.inner_product_matrix() + B = self.basis_matrix() + self._gram_matrix = B * A * B.transpose() + return self._gram_matrix def inner_product_matrix(self): """ - Return the inner product matrix associated to this module. By definition this - is the inner product matrix of the ambient space, hence may be of degree greater - than the rank of the module. + Return the inner product matrix associated to this module. + + By definition, this is the inner product matrix of the ambient + space, hence may be of degree greater than the rank of the + module. + + .. NOTE:: The inner product does not have to be symmetric (see examples). - N.B. The inner product does not have to be symmetric (see examples). + .. TODO:: - TODO: Differentiate the image ring of the inner product from the base ring of - the module and/or ambient space. E.g. On an integral module over ZZ the inner - product pairing could naturally take values in ZZ, QQ, RR, or CC. + Differentiate the image ring of the inner product from the base ring of + the module and/or ambient space. E.g. On an integral module over ZZ the inner + product pairing could naturally take values in ZZ, QQ, RR, or CC. EXAMPLES:: @@ -494,7 +499,7 @@ def inner_product_matrix(self): sage: v.inner_product(u) 2 - The inner product matrix is defined with respect to the ambient space. + The inner product matrix is defined with respect to the ambient space:: sage: V = QQ^3 sage: u = V([1/2,1,1]) @@ -509,15 +514,16 @@ def inner_product_matrix(self): sage: M.gram_matrix() [ 1/2 -3/4] [-3/4 13/4] - """ return self._inner_product_matrix def _inner_product_is_dot_product(self): """ Return whether or not the inner product on this module is induced by - the dot product on the ambient vector space. This is used internally - by the inner_product function for optimization. + the dot product on the ambient vector space. + + This is used internally by the ``inner_product`` function for + optimization. EXAMPLES:: @@ -538,12 +544,16 @@ def _inner_product_is_dot_product(self): def _inner_product_is_diagonal(self): """ Return whether or not the inner product on this module is induced by - the dot product on the ambient vector space. This is used internally - by the inner_product function for optimization. + the dot product on the ambient vector space. + + This is used internally by the ``inner_product`` function for + optimization. + + .. NOTE:: - N.B. The FreeModule classes have the identity inner product matrix, - while FreeQuadraticModules must have an inner_product_matrix, although - it can be diagonal. + The ``FreeModule`` classes have the identity inner product matrix, + while ``FreeQuadraticModules`` must have an ``inner_product_matrix``, although + it can be diagonal. EXAMPLES:: @@ -565,13 +575,12 @@ def _inner_product_is_diagonal(self): .. TODO:: Actually use the diagonal form of the inner product. """ A = self.inner_product_matrix() - D = sage.matrix.constructor.diagonal_matrix([A[i, i] - for i in range(A.nrows())]) + D = sage.matrix.constructor.diagonal_matrix(A.diagonal()) return A == D -class FreeQuadraticModule_generic_pid( - free_module.FreeModule_generic_pid, FreeQuadraticModule_generic): +class FreeQuadraticModule_generic_pid(free_module.FreeModule_generic_pid, + FreeQuadraticModule_generic): """ Class of all free modules over a PID. """ @@ -589,16 +598,17 @@ def __init__(self, base_ring, rank, degree, inner_product_matrix, sparse=False): """ free_module.FreeModule_generic_pid.__init__( self, base_ring=base_ring, rank=rank, degree=degree, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def span(self, gens, check=True, already_echelonized=False): """ Return the R-span of the given list of gens, where R - is the base ring of self. Note that this span need not - be a submodule of self, nor even of the ambient space. - It must, however, be contained in the ambient vector space, i.e., - the ambient space tensored with the fraction field of R. + is the base ring of ``self``. + + Note that this span need not be a submodule of self, nor even + of the ambient space. It must, however, be contained in the + ambient vector space, i.e., the ambient space tensored with + the fraction field of R. EXAMPLES:: @@ -620,10 +630,12 @@ def span(self, gens, check=True, already_echelonized=False): def span_of_basis(self, basis, check=True, already_echelonized=False): r""" Return the free R-module with the given basis, where R - is the base ring of self. Note that this R-module need not - be a submodule of self, nor even of the ambient space. It - must, however, be contained in the ambient vector space, i.e., - the ambient space tensored with the fraction field of R. + is the base ring of ``self``. + + Note that this R-module need not be a submodule of ``self``, nor + even of the ambient space. It must, however, be contained in + the ambient vector space, i.e., the ambient space tensored + with the fraction field of R. EXAMPLES:: @@ -673,14 +685,15 @@ def zero_submodule(self): return FreeQuadraticModule_submodule_pid( self.ambient_module(), [], self.inner_product_matrix(), check=False) -class FreeQuadraticModule_generic_field( - free_module.FreeModule_generic_field, FreeQuadraticModule_generic_pid): + +class FreeQuadraticModule_generic_field(free_module.FreeModule_generic_field, + FreeQuadraticModule_generic_pid): """ Base class for all free modules over fields. """ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=False): """ - Creates a vector space over a field. + Create a vector space over a field. EXAMPLES:: @@ -701,26 +714,27 @@ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=F [0 0 0 0 0 0 1] """ if not isinstance(base_field, ring.Field): - raise TypeError("The base_field (=%s) must be a field" % base_field) + raise TypeError("the base_field (=%s) must be a field" % base_field) free_module.FreeModule_generic_field.__init__( self, base_field=base_field, dimension=dimension, degree=degree, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def span(self, gens, check=True, already_echelonized=False): """ Return the K-span of the given list of gens, where K is the - base field of self. Note that this span is a subspace of the - ambient vector space, but need not be a subspace of self. + base field of ``self``. + + Note that this span is a subspace of the ambient vector space, + but need not be a subspace of ``self``. INPUT: - - gens -- list of vectors + - ``gens`` -- list of vectors - - check -- bool (default: True): whether or not to coerce + - ``check`` -- bool (default: ``True``): whether or not to coerce entries of gens into base field - - already_echelonized -- bool (default: False): set this if + - ``already_echelonized`` -- bool (default: ``False``): set this if you know the gens are already in echelon form EXAMPLES:: @@ -738,7 +752,7 @@ def span(self, gens, check=True, already_echelonized=False): if free_module.is_FreeModule(gens): gens = gens.gens() if not isinstance(gens, (list, tuple)): - raise TypeError("gens (=%s) must be a list or tuple"%gens) + raise TypeError("gens (=%s) must be a list or tuple" % gens) return FreeQuadraticModule_submodule_field( self.ambient_module(), gens, @@ -748,18 +762,19 @@ def span(self, gens, check=True, already_echelonized=False): def span_of_basis(self, basis, check=True, already_echelonized=False): r""" Return the free K-module with the given basis, where K - is the base field of self. Note that this span is - a subspace of the ambient vector space, but need - not be a subspace of self. + is the base field of ``self``. + + Note that this span is a subspace of the ambient vector space, + but need not be a subspace of ``self``. INPUT: - - basis -- list of vectors + - ``basis`` -- list of vectors - - check -- bool (default: True): whether or not to coerce + - ``check`` -- bool (default: ``True``): whether or not to coerce entries of gens into base field - - already_echelonized -- bool (default: False): set this if + - ``already_echelonized`` -- bool (default: ``False``): set this if you know the gens are already in echelon form EXAMPLES:: @@ -788,40 +803,39 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): inner_product_matrix=self.inner_product_matrix(), check=check, already_echelonized=already_echelonized) -############################################################################### + +# ############################################################################# # # Generic ambient free modules, i.e., of the form R^n for some commutative ring R. # -############################################################################### +# ############################################################################# -class FreeQuadraticModule_ambient( - free_module.FreeModule_ambient, FreeQuadraticModule_generic): +class FreeQuadraticModule_ambient(free_module.FreeModule_ambient, + FreeQuadraticModule_generic): """ Ambient free module over a commutative ring. """ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): """ - The free module of given rank over the given base_ring. + The free module of given rank over the given ``base_ring``. INPUT: - - base_ring -- a commutative ring + - ``base_ring`` -- a commutative ring - - rank -- a non-negative integer + - ``rank`` -- a non-negative integer EXAMPLES:: sage: FreeModule(ZZ, 4) Ambient free module of rank 4 over the principal ideal domain Integer Ring - """ free_module.FreeModule_ambient.__init__(self, base_ring=base_ring, rank=rank, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -848,11 +862,10 @@ def _repr_(self): Ambient sparse free module of rank 12 over Ring of integers modulo 12 """ if self.is_sparse(): - return "Ambient sparse free quadratic module of rank %s over %s\n" % ( self.rank(), self.base_ring() ) + \ - "Inner product matrix:\n%s" % self.inner_product_matrix() - else: - return "Ambient free quadratic module of rank %s over %s\n" % ( self.rank(), self.base_ring() ) + \ + return "Ambient sparse free quadratic module of rank %s over %s\n" % (self.rank(), self.base_ring()) + \ "Inner product matrix:\n%s" % self.inner_product_matrix() + return "Ambient free quadratic module of rank %s over %s\n" % (self.rank(), self.base_ring()) + \ + "Inner product matrix:\n%s" % self.inner_product_matrix() def _latex_(self): r""" @@ -871,16 +884,18 @@ def _latex_(self): sage: V = QuadraticSpace(QQ,3,inner_product_matrix=[[2,1,0],[1,4,1],[0,1,8]]) sage: latex(V) - None + Traceback (most recent call last): + ... + NotImplementedError """ # How do we want to represent this object? - NotImplementedError + raise NotImplementedError def _dense_module(self): """ - Creates a dense module with the same defining data as self. + Create a dense module with the same defining data as ``self``. - N.B. This function is for internal use only! See dense_module for use. + .. NOTE:: This function is for internal use only! See dense_module for use. EXAMPLES:: @@ -890,14 +905,15 @@ def _dense_module(self): sage: M is S._dense_module() True """ - return FreeQuadraticModule(base_ring=self.base_ring(), rank = self.rank(), - inner_product_matrix = self.inner_product_matrix(), sparse=False) + return FreeQuadraticModule(base_ring=self.base_ring(), rank=self.rank(), + inner_product_matrix=self.inner_product_matrix(), + sparse=False) def _sparse_module(self): """ - Creates a sparse module with the same defining data as self. + Create a sparse module with the same defining data as ``self``. - N.B. This function is for internal use only! See sparse_module for use. + .. NOTE:: This function is for internal use only! See sparse_module for use. EXAMPLES:: @@ -907,17 +923,18 @@ def _sparse_module(self): sage: M._sparse_module() is S True """ - return FreeQuadraticModule(base_ring = self.base_ring(), rank = self.rank(), - inner_product_matrix = self.inner_product_matrix(), sparse=True) + return FreeQuadraticModule(base_ring=self.base_ring(), rank=self.rank(), + inner_product_matrix=self.inner_product_matrix(), sparse=True) -############################################################################### + +# ############################################################################# # # Ambient free modules over an integral domain. # -############################################################################### +# ############################################################################# -class FreeQuadraticModule_ambient_domain( - free_module.FreeModule_ambient_domain, FreeQuadraticModule_ambient): +class FreeQuadraticModule_ambient_domain(free_module.FreeModule_ambient_domain, + FreeQuadraticModule_ambient): """ Ambient free quadratic module over an integral domain. """ @@ -930,12 +947,11 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): Univariate Polynomial Ring in x over Finite Field of size 5 """ free_module.FreeModule_ambient.__init__(self, base_ring=base_ring, rank=rank, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -975,17 +991,16 @@ def _repr_(self): -b^2 + 4*a*c """ if self.is_sparse(): - return "Ambient sparse free quadratic module of rank %s over the integral domain %s\n"%( - self.rank(), self.base_ring() ) + \ - "Inner product matrix:\n%s" % self.inner_product_matrix() - else: - return "Ambient free quadratic module of rank %s over the integral domain %s\n"%( - self.rank(), self.base_ring() ) + \ + return "Ambient sparse free quadratic module of rank %s over the integral domain %s\n" % ( + self.rank(), self.base_ring()) + \ "Inner product matrix:\n%s" % self.inner_product_matrix() + return "Ambient free quadratic module of rank %s over the integral domain %s\n" % ( + self.rank(), self.base_ring()) + \ + "Inner product matrix:\n%s" % self.inner_product_matrix() def ambient_vector_space(self): """ - Returns the ambient vector space, which is this free module tensored + Return the ambient vector space, which is this free module tensored with its fraction field. EXAMPLES:: @@ -1001,31 +1016,33 @@ def ambient_vector_space(self): inner_product_matrix=self.inner_product_matrix(), sparse=self.is_sparse()) return self.__ambient_vector_space -############################################################################### + +# ############################################################################# # # Ambient free modules over a principal ideal domain. # -############################################################################### +# ############################################################################# -class FreeQuadraticModule_ambient_pid( - free_module.FreeModule_ambient_pid, FreeQuadraticModule_generic_pid, FreeQuadraticModule_ambient_domain): +class FreeQuadraticModule_ambient_pid(free_module.FreeModule_ambient_pid, + FreeQuadraticModule_generic_pid, + FreeQuadraticModule_ambient_domain): """ Ambient free quadratic module over a principal ideal domain. """ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): """ Create the ambient free module of given rank over the given - principal ideal domain + principal ideal domain. INPUT: - - base_ring -- a principal ideal domain + - ``base_ring`` -- a principal ideal domain - - rank -- a non-negative integer + - ``rank`` -- a non-negative integer - - sparse -- bool (default: False) + - ``sparse`` -- bool (default: ``False``) - - inner_product_matrix -- bool (default: None) + - ``inner_product_matrix`` -- bool (default: ``None``) EXAMPLES:: @@ -1039,12 +1056,11 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): [ 0 -1 2] """ free_module.FreeModule_ambient_pid.__init__(self, base_ring=base_ring, rank=rank, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -1078,26 +1094,25 @@ def _repr_(self): sage: N = FreeModule(ZZ,7,sparse=True) sage: N Ambient sparse free module of rank 7 over the principal ideal domain Integer Ring - """ if self.is_sparse(): - return "Ambient sparse free quadratic module of rank %s over the principal ideal domain %s\n"%( - self.rank(), self.base_ring() ) + \ - "Inner product matrix:\n%s" % self.inner_product_matrix() - else: - return "Ambient free quadratic module of rank %s over the principal ideal domain %s\n"%( + return "Ambient sparse free quadratic module of rank %s over the principal ideal domain %s\n" % ( self.rank(), self.base_ring()) + \ "Inner product matrix:\n%s" % self.inner_product_matrix() + return "Ambient free quadratic module of rank %s over the principal ideal domain %s\n" % ( + self.rank(), self.base_ring()) + \ + "Inner product matrix:\n%s" % self.inner_product_matrix() + -############################################################################### +# ############################################################################# # # Ambient free modules over a field (i.e., a vector space). # -############################################################################### +# ############################################################################# -class FreeQuadraticModule_ambient_field( - free_module.FreeModule_ambient_field, - FreeQuadraticModule_generic_field, FreeQuadraticModule_ambient_pid): +class FreeQuadraticModule_ambient_field(free_module.FreeModule_ambient_field, + FreeQuadraticModule_generic_field, + FreeQuadraticModule_ambient_pid): def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): """ @@ -1105,11 +1120,11 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): INPUT: - - base_field -- a field + - ``base_field`` -- a field - - dimension -- a non-negative integer + - ``dimension`` -- a non-negative integer - - sparse -- bool (default: False) + - ``sparse`` -- bool (default: ``False``) EXAMPLES:: @@ -1135,12 +1150,11 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): """ free_module.FreeModule_ambient_field.__init__( self, base_field=base_field, dimension=dimension, sparse=sparse) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -1166,21 +1180,21 @@ def _repr_(self): Sparse vector space of dimension 7 over Rational Field """ if self.is_sparse(): - return "Ambient sparse free quadratic space of dimension %s over %s\n" % ( self.rank(), self.base_ring() ) + \ - "Inner product matrix:\n%s" % self.inner_product_matrix() - else: - return "Ambient quadratic space of dimension %s over %s\n" % ( self.rank(), self.base_ring() ) + \ + return "Ambient sparse free quadratic space of dimension %s over %s\n" % (self.rank(), self.base_ring()) + \ "Inner product matrix:\n%s" % self.inner_product_matrix() + return "Ambient quadratic space of dimension %s over %s\n" % (self.rank(), self.base_ring()) + \ + "Inner product matrix:\n%s" % self.inner_product_matrix() + -############################################################################### +# ############################################################################# # # R-Submodule of K^n where K is the fraction field of a principal ideal domain R. # -############################################################################### +# ############################################################################# -class FreeQuadraticModule_submodule_with_basis_pid( - free_module.FreeModule_submodule_with_basis_pid, FreeQuadraticModule_generic_pid): +class FreeQuadraticModule_submodule_with_basis_pid(free_module.FreeModule_submodule_with_basis_pid, + FreeQuadraticModule_generic_pid): r""" An `R`-submodule of `K^n` with distinguished basis, where `K` is the fraction field of a principal ideal domain `R`. @@ -1218,7 +1232,8 @@ class FreeQuadraticModule_submodule_with_basis_pid( False """ def __init__(self, ambient, basis, inner_product_matrix, - check=True, echelonize=False, echelonized_basis=None, already_echelonized=False): + check=True, echelonize=False, echelonized_basis=None, + already_echelonized=False): """ Create a free module with basis over a PID. @@ -1250,21 +1265,20 @@ def __init__(self, ambient, basis, inner_product_matrix, We test that :trac:`23703` is fixed:: - sage: A=FreeQuadraticModule(ZZ,1,matrix.identity(1)) - sage: B=A.span([[1/2]]) - sage: C=B.span([[1]]) - sage: B.intersection(C)==C.intersection(B) + sage: A = FreeQuadraticModule(ZZ,1,matrix.identity(1)) + sage: B = A.span([[1/2]]) + sage: C = B.span([[1]]) + sage: B.intersection(C) == C.intersection(B) True """ free_module.FreeModule_submodule_with_basis_pid.__init__( self, ambient=ambient, basis=basis, check=check, echelonize=echelonize, echelonized_basis=echelonized_basis, already_echelonized=already_echelonized) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -1295,12 +1309,12 @@ def _repr_(self): [-1 0 0 0 0 0 0 1] """ if self.is_sparse(): - s = "Sparse free quadratic module of degree %s and rank %s over %s\n"%( + s = "Sparse free quadratic module of degree %s and rank %s over %s\n" % ( self.degree(), self.rank(), self.base_ring()) + \ "Basis matrix:\n%r\n" % self.basis_matrix() + \ "Inner product matrix:\n%r" % self.inner_product_matrix() else: - s = "Free quadratic module of degree %s and rank %s over %s\n"%( + s = "Free quadratic module of degree %s and rank %s over %s\n" % ( self.degree(), self.rank(), self.base_ring()) + \ "Basis matrix:\n%r\n" % self.basis_matrix() + \ "Inner product matrix:\n%r" % self.inner_product_matrix() @@ -1317,14 +1331,16 @@ def _latex_(self): sage: M._latex_() '\\mathrm{RowSpan}_{\\Bold{Z}}\\left(\\begin{array}{rrr}\n1 & 2 & 3 \\\\\n4 & 5 & 6\n\\end{array}\\right)' """ - return "\\mathrm{RowSpan}_{%s}%s"%(latex.latex(self.base_ring()), latex.latex(self.basis_matrix())) + return "\\mathrm{RowSpan}_{%s}%s" % (latex.latex(self.base_ring()), + latex.latex(self.basis_matrix())) def change_ring(self, R): """ Return the free module over R obtained by coercing each - element of self into a vector over the fraction field of R, - then taking the resulting R-module. Raises a TypeError - if coercion is not possible. + element of ``self`` into a vector over the fraction field of R, + then taking the resulting R-module. + + This raises a ``TypeError`` if coercion is not possible. INPUT: @@ -1358,15 +1374,15 @@ def change_ring(self, R): K = R.fraction_field() A = self.inner_product_matrix() V = QuadraticSpace(K, self.degree(), inner_product_matrix=A) - B = [ V(b) for b in self.basis() ] + B = [V(b) for b in self.basis()] M = FreeQuadraticModule(R, self.degree(), inner_product_matrix=A) if self.has_user_basis(): return M.span_of_basis(B) - else: - return M.span(B) + return M.span(B) -class FreeQuadraticModule_submodule_pid( - free_module.FreeModule_submodule_pid, FreeQuadraticModule_submodule_with_basis_pid): + +class FreeQuadraticModule_submodule_pid(free_module.FreeModule_submodule_pid, + FreeQuadraticModule_submodule_with_basis_pid): """ An `R`-submodule of `K^n` where `K` is the fraction field of a principal ideal domain `R`. @@ -1404,12 +1420,11 @@ def __init__(self, ambient, gens, inner_product_matrix, check=True, already_eche """ free_module.FreeModule_submodule_pid.__init__( self, ambient=ambient, gens=gens, check=check, already_echelonized=already_echelonized) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -1427,18 +1442,19 @@ def _repr_(self): [ 0 0 0 0 0 0 1 -1] """ if self.is_sparse(): - s = "Sparse free module of degree %s and rank %s over %s\n"%( + s = "Sparse free module of degree %s and rank %s over %s\n" % ( self.degree(), self.rank(), self.base_ring()) + \ - "Echelon basis matrix:\n%s"%self.basis_matrix() + "Echelon basis matrix:\n%s" % self.basis_matrix() else: - s = "Free module of degree %s and rank %s over %s\n"%( + s = "Free module of degree %s and rank %s over %s\n" % ( self.degree(), self.rank(), self.base_ring()) + \ - "Echelon basis matrix:\n%s"%self.basis_matrix() + "Echelon basis matrix:\n%s" % self.basis_matrix() return s -class FreeQuadraticModule_submodule_with_basis_field( - free_module.FreeModule_submodule_with_basis_field, - FreeQuadraticModule_generic_field, FreeQuadraticModule_submodule_with_basis_pid): + +class FreeQuadraticModule_submodule_with_basis_field(free_module.FreeModule_submodule_with_basis_field, + FreeQuadraticModule_generic_field, + FreeQuadraticModule_submodule_with_basis_pid): """ An embedded vector subspace with a distinguished user basis. @@ -1512,12 +1528,11 @@ def __init__(self, ambient, basis, inner_product_matrix, free_module.FreeModule_submodule_with_basis_field.__init__( self, ambient=ambient, basis=basis, check=check, echelonize=echelonize, echelonized_basis=echelonized_basis, already_echelonized=already_echelonized) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The printing representation of self. + The printing representation of ``self``. EXAMPLES:: @@ -1565,25 +1580,25 @@ def _repr_(self): [ 0 0 0 1 -1] """ if self.is_sparse(): - return "Sparse quadratic space of degree %s and dimension %s over %s\n"%( - self.degree(), self.dimension(), self.base_field()) + \ - "Basis matrix:\n%r" % self.basis_matrix() + \ - "Inner product matrix:\n%r" % self.inner_product_matrix() - else: - return "Quadratic space of degree %s and dimension %s over %s\n"%( - self.degree(), self.dimension(), self.base_field()) + \ - "Basis matrix:\n%r\n" % self.basis_matrix() + \ - "Inner product matrix:\n%r" % self.inner_product_matrix() + return "Sparse quadratic space of degree %s and dimension %s over %s\n" % ( + self.degree(), self.dimension(), self.base_field()) + \ + "Basis matrix:\n%r" % self.basis_matrix() + \ + "Inner product matrix:\n%r" % self.inner_product_matrix() + return "Quadratic space of degree %s and dimension %s over %s\n" % ( + self.degree(), self.dimension(), self.base_field()) + \ + "Basis matrix:\n%r\n" % self.basis_matrix() + \ + "Inner product matrix:\n%r" % self.inner_product_matrix() -class FreeQuadraticModule_submodule_field( - free_module.FreeModule_submodule_field, FreeQuadraticModule_submodule_with_basis_field): + +class FreeQuadraticModule_submodule_field(free_module.FreeModule_submodule_field, + FreeQuadraticModule_submodule_with_basis_field): """ An embedded vector subspace with echelonized basis. EXAMPLES: Since this is an embedded vector subspace with echelonized basis, - the echelon_coordinates() and user coordinates() agree:: + the methods ``echelon_coordinates`` and user ``coordinates`` agree:: sage: V = QQ^3 sage: W = V.span([[1,2,3],[4,5,6]]) @@ -1621,12 +1636,11 @@ def __init__(self, ambient, gens, inner_product_matrix, check=True, already_eche """ free_module.FreeModule_submodule_field.__init__( self, ambient=ambient, gens=gens, check=check, already_echelonized=already_echelonized) - #self._FreeQuadraticModule_generic_inner_product_matrix = inner_product_matrix self._inner_product_matrix = inner_product_matrix def _repr_(self): """ - The default printing representation of self. + The default printing representation of ``self``. EXAMPLES:: @@ -1674,29 +1688,11 @@ def _repr_(self): [ 0 0 0 1 -1] """ if self.is_sparse(): - return "Sparse quadratic space of degree %s and dimension %s over %s\n"%( - self.degree(), self.dimension(), self.base_field()) + \ - "Basis matrix:\n%r\n" % self.basis_matrix() + \ - "Inner product matrix:\n%r" % self.inner_product_matrix() - else: - return "Quadratic space of degree %s and dimension %s over %s\n"%( + return "Sparse quadratic space of degree %s and dimension %s over %s\n" % ( self.degree(), self.dimension(), self.base_field()) + \ "Basis matrix:\n%r\n" % self.basis_matrix() + \ "Inner product matrix:\n%r" % self.inner_product_matrix() - -#class RealDoubleQuadraticSpace_class(free_module.RealDoubleVectorSpace_class, FreeQuadraticModule_ambient_field): -# def __init__(self, dimension, inner_product_matrix, sparse=False): -# if sparse: -# raise NotImplementedError, "Sparse matrices over RDF not implemented yet" -# free_module.RealDoubleVectorSpace_class.__init__(self, dimension=dimension, sparse=False) -# self._inner_product_matrix = inner_product_matrix - -#class ComplexDoubleQuadraticSpace_class( -# free_module.ComplexDoubleVectorSpace_class, FreeQuadraticModule_generic): #FreeQuadraticModule_ambient_field): -# def __init__(self, dimension, inner_product_matrix, sparse=False): -# if sparse: -# raise NotImplementedError, "Sparse matrices over CDF not implemented yet" -# free_module.ComplexDoubleVectorSpace_class.__init__(self, dimension=dimension, sparse=False) -# self._inner_product_matrix = inner_product_matrix - -###################################################### + return "Quadratic space of degree %s and dimension %s over %s\n" % ( + self.degree(), self.dimension(), self.base_field()) + \ + "Basis matrix:\n%r\n" % self.basis_matrix() + \ + "Inner product matrix:\n%r" % self.inner_product_matrix() From add35c4283823f03756465793040d2362fd14ba9 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 3 Oct 2022 10:12:23 +0100 Subject: [PATCH 257/350] allow Homebrew's cddlib --- build/pkgs/cddlib/distros/homebrew.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/pkgs/cddlib/distros/homebrew.txt b/build/pkgs/cddlib/distros/homebrew.txt index 11ade1bfb9a..f9afcc0b330 100644 --- a/build/pkgs/cddlib/distros/homebrew.txt +++ b/build/pkgs/cddlib/distros/homebrew.txt @@ -1,3 +1 @@ -# Until https://trac.sagemath.org/ticket/29413 is done, we cannot use homebrew's cddlib, -# which already uses the new upstream include header locations. -#cddlib +cddlib From 8a56793b7c09664442e1d0b373009d176ebb3187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Mon, 3 Oct 2022 11:54:17 +0200 Subject: [PATCH 258/350] 33680: moving regex from header module to methods --- src/sage/doctest/parsing.py | 63 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 8e82c3fe779..804009a6780 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -29,35 +29,8 @@ from sage.repl.preparse import preparse, strip_string_literals from functools import reduce - from .external import available_software -float_regex = re.compile(r'\s*([+-]?\s*((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?)') -optional_regex = re.compile(r'(arb216|arb218|py2|long time|not implemented|not tested|known bug)|([^ a-z]\s*optional\s*[:-]*((\s|\w|[.])*))') -# Version 4.65 of glpk prints the warning "Long-step dual simplex will -# be used" frequently. When Sage uses a system installation of glpk -# which has not been patched, we need to ignore that message. -# See :trac:`29317`. -glpk_simplex_warning_regex = re.compile(r'(Long-step dual simplex will be used)') -# :trac:`31204` -- suppress warning about ld and OS version for dylib files. -ld_warning_regex = re.compile(r'^.*dylib.*was built for newer macOS version.*than being linked.*') -# :trac:`30845` -- suppress warning on conda about ld -ld_pie_warning_regex = re.compile(r'ld: warning: -pie being ignored. It is only used when linking a main executable') -# :trac:`34533` -- suppress warning on OS X 12.6 about chained fixups -chained_fixup_warning_regex = re.compile(r'ld: warning: -undefined dynamic_lookup may not work with chained fixups') -sympow_cache_warning_regex = re.compile(r'\*\*WARNING\*\* /var/cache/sympow/datafiles/le64 yields insufficient permissions') -find_sage_prompt = re.compile(r"^(\s*)sage: ", re.M) -find_sage_continuation = re.compile(r"^(\s*)\.\.\.\.:", re.M) -find_python_continuation = re.compile(r"^(\s*)\.\.\.([^\.])", re.M) -python_prompt = re.compile(r"^(\s*)>>>", re.M) -# The following are used to allow ... at the beginning of output -ellipsis_tag = "" -continuation_tag = "" -random_marker = re.compile('.*random', re.I) -tolerance_pattern = re.compile(r'\b((?:abs(?:olute)?)|(?:rel(?:ative)?))? *?tol(?:erance)?\b( +[0-9.e+-]+)?') -backslash_replacer = re.compile(r"""(\s*)sage:(.*)\\\ * -\ *(((\.){4}:)|((\.){3}))?\ *""") - _RIFtol = None @@ -164,6 +137,8 @@ def parse_optional_tags(string): # strip_string_literals replaces comments comment = "#" + (literals[comment]).lower() + optional_regex = re.compile(r'(arb216|arb218|py2|long time|not implemented|not tested|known bug)|([^ a-z]\s*optional\s*[:-]*((\s|\w|[.])*))') + tags = [] for m in optional_regex.finditer(comment): cmd = m.group(1) @@ -205,6 +180,10 @@ def parse_tolerance(source, want): sage: marked.abs_tol 0.010000000000000000000...? """ + # regular expressions + random_marker = re.compile('.*random', re.I) + tolerance_pattern = re.compile(r'\b((?:abs(?:olute)?)|(?:rel(?:ative)?))? *?tol(?:erance)?\b( +[0-9.e+-]+)?') + safe, literals, state = strip_string_literals(source) first_line = safe.split('\n', 1)[0] if '#' not in first_line: @@ -618,6 +597,17 @@ def parse(self, string, *args): sage: dte.want '...00010\n' """ + # Regular expressions + find_sage_prompt = re.compile(r"^(\s*)sage: ", re.M) + find_sage_continuation = re.compile(r"^(\s*)\.\.\.\.:", re.M) + find_python_continuation = re.compile(r"^(\s*)\.\.\.([^\.])", re.M) + python_prompt = re.compile(r"^(\s*)>>>", re.M) + backslash_replacer = re.compile(r"""(\s*)sage:(.*)\\\ * +\ *(((\.){4}:)|((\.){3}))?\ *""") + + # The following are used to allow ... at the beginning of output + ellipsis_tag = "" + # Hack for non-standard backslash line escapes accepted by the current # doctest system. m = backslash_replacer.search(string) @@ -916,6 +906,9 @@ def check_output(self, want, got, optionflags): sage: OC.check_output(ex.want, 'Long-step dual simplex will be used\n1.3090169943749475', optflag) True """ + # Regular expression for floats + float_regex = re.compile(r'\s*([+-]?\s*((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?)') + got = self.human_readable_escape_sequences(got) if isinstance(want, MarkedOutput): @@ -1015,22 +1008,35 @@ def do_fixup(self, want, got): # and/or actual output to determine if a fixup should be applied. if "Long-step" in got: + # Version 4.65 of glpk prints the warning "Long-step dual + # simplex will be used" frequently. When Sage uses a system + # installation of glpk which has not been patched, we need to + # ignore that message. See :trac:`29317`. + glpk_simplex_warning_regex = re.compile(r'(Long-step dual simplex will be used)') got = glpk_simplex_warning_regex.sub('', got) did_fixup = True if "chained fixups" in got: + # :trac:`34533` -- suppress warning on OS X 12.6 about chained fixups + chained_fixup_warning_regex = re.compile(r'ld: warning: -undefined dynamic_lookup may not work with chained fixups') got = chained_fixup_warning_regex.sub('', got) did_fixup = True if "insufficient permissions" in got: + sympow_cache_warning_regex = re.compile(r'\*\*WARNING\*\* /var/cache/sympow/datafiles/le64 yields insufficient permissions') got = sympow_cache_warning_regex.sub('', g) did_fixup = True if "dylib" in got: + # :trac:`31204` -- suppress warning about ld and OS version for + # dylib files. + ld_warning_regex = re.compile(r'^.*dylib.*was built for newer macOS version.*than being linked.*') got = ld_warning_regex.sub('', got) did_fixup = True if "pie being ignored" in got: + # :trac:`30845` -- suppress warning on conda about ld + ld_pie_warning_regex = re.compile(r'ld: warning: -pie being ignored. It is only used when linking a main executable') got = ld_pie_warning_regex.sub('', got) did_fixup = True @@ -1165,6 +1171,9 @@ def output_difference(self, example, got, optionflags): Tolerance exceeded: 0.0 vs 10.05, tolerance +infinity > 1e-1 """ + # Regular expression for floats + float_regex = re.compile(r'\s*([+-]?\s*((\d*\.?\d+)|(\d+\.?))([eE][+-]?\d+)?)') + got = self.human_readable_escape_sequences(got) want = example.want diff = doctest.OutputChecker.output_difference(self, example, got, optionflags) From 5b539c5320ce284ad2da8326fc4bea04d8388c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Mon, 3 Oct 2022 11:55:15 +0200 Subject: [PATCH 259/350] 33680: fixed a typo in the code: g -> got --- src/sage/doctest/parsing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 804009a6780..27fb25a273a 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -1024,7 +1024,7 @@ def do_fixup(self, want, got): if "insufficient permissions" in got: sympow_cache_warning_regex = re.compile(r'\*\*WARNING\*\* /var/cache/sympow/datafiles/le64 yields insufficient permissions') - got = sympow_cache_warning_regex.sub('', g) + got = sympow_cache_warning_regex.sub('', got) did_fixup = True if "dylib" in got: From 3900ab7480f32ea4cff97b03f0279c2b6241c917 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Sun, 2 Oct 2022 17:07:18 -0700 Subject: [PATCH 260/350] trac 34629: more :kbd: --- src/doc/en/faq/faq-usage.rst | 4 ++-- src/doc/en/prep/Intro-Tutorial.rst | 2 +- src/doc/en/thematic_tutorials/group_theory.rst | 2 +- src/doc/en/tutorial/interactive_shell.rst | 4 ++-- src/sage/graphs/digraph.py | 2 +- src/sage/graphs/graph.py | 2 +- src/sage/graphs/graph_database.py | 2 +- src/sage/knots/knotinfo.py | 4 ++-- src/sage/topology/simplicial_set.py | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index d072057189e..40e4be5ddec 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -233,9 +233,9 @@ characters, hit the :kbd:`Tab` key, and see if the command you want appears in the list of tab autocompletion. If you have a command called ``mycmd``, then type ``mycmd.`` and hit the :kbd:`Tab` key to get a list of functionalities that are supported by that command. To read the -documentation of ``mycmd``, type ``mycmd?`` and press the enter key to +documentation of ``mycmd``, type ``mycmd?`` and press the :kbd:`Enter` key to read the documentation for that command. Similarly, type ``mycmd??`` -and hit the enter key to get the source code of that command. You are +and hit the :kbd:`Enter` key to get the source code of that command. You are also encouraged to search through the source code and documentation of the Sage library. To search through the source code of the Sage library, use the command ``search_src("")`` where you diff --git a/src/doc/en/prep/Intro-Tutorial.rst b/src/doc/en/prep/Intro-Tutorial.rst index e3906bd0f56..7ab0a4ad97d 100644 --- a/src/doc/en/prep/Intro-Tutorial.rst +++ b/src/doc/en/prep/Intro-Tutorial.rst @@ -366,7 +366,7 @@ Here's an example. - Still, it seems reasonable that the command might start with ``pl``. -- Then one can type ``pl`` in an input cell, and then press the :kdb:`Tab` key +- Then one can type ``pl`` in an input cell, and then press the :kbd:`Tab` key to see all the commands that start with the letters ``pl``. Try tabbing after the ``pl`` in the following cell to see all the diff --git a/src/doc/en/thematic_tutorials/group_theory.rst b/src/doc/en/thematic_tutorials/group_theory.rst index 8323abb26f2..9a4edca73c2 100644 --- a/src/doc/en/thematic_tutorials/group_theory.rst +++ b/src/doc/en/thematic_tutorials/group_theory.rst @@ -365,7 +365,7 @@ to scroll down to see the whole list). As before, Here is another couple of ways to experiment and explore. Find a function that looks interesting, say ``is_abelian()``. Type -``H.is_abelian?`` (note the question mark) followed by the enter key. +``H.is_abelian?`` (note the question mark) followed by the :kbd:`Enter` key. This will display a portion of the source code for the ``is_abelian()`` function, describing the inputs and output, possibly illustrated with example uses. diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index 7ae821e416d..4c06c6a6255 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -549,7 +549,7 @@ You can also use the following more concise notation: sage: V = QQ^3 Then it is easy to list all member functions for :math:`V` using tab -completion. Just type ``V.``, then type the ``[tab key]`` key on your +completion. Just type ``V.``, then type the :kbd:`Tab` key on your keyboard: .. skip @@ -567,7 +567,7 @@ keyboard: ... V.zero_vector -If you type the first few letters of a function, then ``[tab key]``, +If you type the first few letters of a function, then the :kbd:`Tab` key, you get only functions that begin as indicated. .. skip diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 7e2a59e4abc..3cccf81c956 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -192,7 +192,7 @@ class DiGraph(GenericGraph): pre-defined digraphs, see the :mod:`~sage.graphs.digraph_generators` module. A :class:`DiGraph` object has many methods whose list can be obtained by - typing ``g.`` (i.e. hit the 'tab' key) or by reading the documentation + typing ``g.`` (i.e. hit the :kbd:`Tab` key) or by reading the documentation of :mod:`~sage.graphs.digraph`, :mod:`~sage.graphs.generic_graph`, and :mod:`~sage.graphs.graph`. diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index af93c60a7a2..3bd3983579e 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -440,7 +440,7 @@ class Graph(GenericGraph): pre-defined graphs, see the :mod:`~sage.graphs.graph_generators` module. A :class:`Graph` object has many methods whose list can be obtained by - typing ``g.`` (i.e. hit the 'tab' key) or by reading the documentation + typing ``g.`` (i.e. hit the :kbd:`Tab` key) or by reading the documentation of :mod:`~sage.graphs.graph`, :mod:`~sage.graphs.generic_graph`, and :mod:`~sage.graphs.digraph`. diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index 3c9021bd8cc..a875f00396d 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -968,7 +968,7 @@ def query(self, query_dict=None, display_cols=None, **kwds): Create a GraphQuery on this database. For full class details, type ``GraphQuery?`` - and press :kbd:`Shift` + :kdb:`Enter`. + and press :kbd:`Shift` + :kbd:`Enter`. EXAMPLES:: diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index df893a488f6..8173cdc7ead 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -188,12 +188,12 @@ True To see all the properties available in this interface you can use "tab-completion". -For example type ``K.items.`` and than hit the "tab-key". You can select the item +For example type ``K.items.`` and than hit the :kbd:`Tab` key. You can select the item you want from the list. If you know some first letters type them first to obtain a reduced selection list. In a similar way you may select the knots and links. Here you have to type ``KnotInfo.`` -or ``KnotInfo.L7`` before stroking the "tab-key". In the latter case the selection list +or ``KnotInfo.L7`` before stroking the :kbd:`Tab` key. In the latter case the selection list will be reduced to proper links with 7 crossings. Finally there is a method :meth:`Link.get_knotinfo` of class :class:`Link` to find an instance diff --git a/src/sage/topology/simplicial_set.py b/src/sage/topology/simplicial_set.py index 0fa0e6495d9..836a13da05d 100644 --- a/src/sage/topology/simplicial_set.py +++ b/src/sage/topology/simplicial_set.py @@ -62,7 +62,7 @@ sage: simplicial_sets.ClassifyingSpace(Sigma4) Classifying space of Symmetric group of order 4! as a permutation group -Type ``simplicial_sets.`` and hit the ``TAB`` key to get a full list +Type ``simplicial_sets.`` and hit the :kbd:`Tab` key to get a full list of the predefined simplicial sets. You can construct new simplicial sets from old by taking quotients, From b9b8743611ee3212df34abf0057eb1fce62eed65 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 4 Oct 2022 08:28:05 +0200 Subject: [PATCH 261/350] 33969: fix typo --- src/sage/knots/knotinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 529c74bfc35..efe26ee7e27 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1692,7 +1692,7 @@ def conway_polynomial(self, var='t', original=False): def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): r""" Return the Khovanov polynomial according to the value of column - ``khovnov_polynomial`` for this knot or link as an instance of + ``khovanov_polynomial`` for this knot or link as an instance of :class:`~sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair`. INPUT: From cd0fb01afe3d90a12b09a81d5db5dff5d72cb5a4 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Fri, 30 Sep 2022 12:14:37 +0200 Subject: [PATCH 262/350] #34632 wrappers for acb_poly_[rl]gamma_series --- .../polynomial/polynomial_complex_arb.pyx | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/sage/rings/polynomial/polynomial_complex_arb.pyx b/src/sage/rings/polynomial/polynomial_complex_arb.pyx index ed4617dd951..5fc4ff1f6af 100644 --- a/src/sage/rings/polynomial/polynomial_complex_arb.pyx +++ b/src/sage/rings/polynomial/polynomial_complex_arb.pyx @@ -717,6 +717,44 @@ cdef class Polynomial_complex_arb(Polynomial): sig_off() return res + def _lgamma_series(self, long n): + r""" + Return the series expansion of the log-gamma function composed + with this polynomial, truncated before degree ``n``. + + EXAMPLES:: + + sage: Pol. = CBF[] + sage: (1000 + x)._lgamma_series(3) + ([0.00050025008333331...])*x^2 + ([6.9072551956488...])*x + [5905.2204232091...] + """ + cdef Polynomial_complex_arb res = self._new() + if n < 0: + n = 0 + sig_on() + acb_poly_lgamma_series(res.__poly, self.__poly, n, prec(self)) + sig_off() + return res + + def _rgamma_series(self, long n): + r""" + Return the series expansion of the reciprocal gamma function composed + with this polynomial, truncated before degree ``n``. + + EXAMPLES:: + + sage: Pol. = CBF[] + sage: (-1 + x)._rgamma_series(4) + ([1.23309373642178...])*x^3 + ([0.422784335098467...])*x^2 - x + """ + cdef Polynomial_complex_arb res = self._new() + if n < 0: + n = 0 + sig_on() + acb_poly_rgamma_series(res.__poly, self.__poly, n, prec(self)) + sig_off() + return res + def _lambert_w_series(self, long n, branch=0): r""" Return the series expansion of the specified branch of the Lambert W From a0e1d3b434dee8b6c8659426b24cac43587b917f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 4 Oct 2022 08:56:57 +0200 Subject: [PATCH 263/350] adding kbd to authorized roles --- src/tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tox.ini b/src/tox.ini index b54938f74e3..c7fe61423c3 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -196,6 +196,7 @@ rst-roles = data, exc, func, + kbd, meth, mod, obj, From 561f6694a3ae136e97e3f62b1e155cc0474f661d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 5 Oct 2022 18:32:23 +0900 Subject: [PATCH 264/350] More edits --- src/sage/modules/free_quadratic_module.py | 34 ++++++++++++----------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index b17a0b4eaa9..b512db6ffbc 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -420,10 +420,10 @@ def discriminant(self): TESTS:: - sage: M = FreeQuadraticModule(ZZ,2,matrix.identity(2)) + sage: M = FreeQuadraticModule(ZZ, 2, matrix.identity(2)) sage: M.discriminant() -1 - sage: M = FreeQuadraticModule(QQ,3,matrix.identity(3)) + sage: M = FreeQuadraticModule(QQ, 3, matrix.identity(3)) sage: M.discriminant() -1 """ @@ -602,13 +602,13 @@ def __init__(self, base_ring, rank, degree, inner_product_matrix, sparse=False): def span(self, gens, check=True, already_echelonized=False): """ - Return the R-span of the given list of gens, where R + Return the `R`-span of the given list of gens, where `R` is the base ring of ``self``. - Note that this span need not be a submodule of self, nor even + Note that this span need not be a submodule of ``self``, nor even of the ambient space. It must, however, be contained in the ambient vector space, i.e., the ambient space tensored with - the fraction field of R. + the fraction field of `R`. EXAMPLES:: @@ -629,13 +629,13 @@ def span(self, gens, check=True, already_echelonized=False): def span_of_basis(self, basis, check=True, already_echelonized=False): r""" - Return the free R-module with the given basis, where R + Return the free `R`-module with the given basis, where `R` is the base ring of ``self``. - Note that this R-module need not be a submodule of ``self``, nor + Note that this `R`-module need not be a submodule of ``self``, nor even of the ambient space. It must, however, be contained in the ambient vector space, i.e., the ambient space tensored - with the fraction field of R. + with the fraction field of `R`. EXAMPLES:: @@ -721,7 +721,7 @@ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=F def span(self, gens, check=True, already_echelonized=False): """ - Return the K-span of the given list of gens, where K is the + Return the `K`-span of the given list of gens, where `K` is the base field of ``self``. Note that this span is a subspace of the ambient vector space, @@ -761,7 +761,7 @@ def span(self, gens, check=True, already_echelonized=False): def span_of_basis(self, basis, check=True, already_echelonized=False): r""" - Return the free K-module with the given basis, where K + Return the free `K`-module with the given basis, where `K` is the base field of ``self``. Note that this span is a subspace of the ambient vector space, @@ -924,7 +924,8 @@ def _sparse_module(self): True """ return FreeQuadraticModule(base_ring=self.base_ring(), rank=self.rank(), - inner_product_matrix=self.inner_product_matrix(), sparse=True) + inner_product_matrix=self.inner_product_matrix(), + sparse=True) # ############################################################################# @@ -1265,7 +1266,7 @@ def __init__(self, ambient, basis, inner_product_matrix, We test that :trac:`23703` is fixed:: - sage: A = FreeQuadraticModule(ZZ,1,matrix.identity(1)) + sage: A = FreeQuadraticModule(ZZ, 1, matrix.identity(1)) sage: B = A.span([[1/2]]) sage: C = B.span([[1]]) sage: B.intersection(C) == C.intersection(B) @@ -1336,9 +1337,9 @@ def _latex_(self): def change_ring(self, R): """ - Return the free module over R obtained by coercing each - element of ``self`` into a vector over the fraction field of R, - then taking the resulting R-module. + Return the free module over `R` obtained by coercing each + element of ``self`` into a vector over the fraction field of `R`, + then taking the resulting `R`-module. This raises a ``TypeError`` if coercion is not possible. @@ -1598,7 +1599,8 @@ class FreeQuadraticModule_submodule_field(free_module.FreeModule_submodule_field EXAMPLES: Since this is an embedded vector subspace with echelonized basis, - the methods ``echelon_coordinates`` and user ``coordinates`` agree:: + the methods :meth:`echelon_coordinates` and :meth:`coordinates` return the same + coordinates:: sage: V = QQ^3 sage: W = V.span([[1,2,3],[4,5,6]]) From 4a8c2b2dd933b82ce3ecc2953dcc5347ed7dd2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Wed, 5 Oct 2022 22:55:38 +1300 Subject: [PATCH 265/350] update sphinxcontrib_websupport to latest --- build/pkgs/sphinxcontrib_websupport/checksums.ini | 6 +++--- build/pkgs/sphinxcontrib_websupport/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/sphinxcontrib_websupport/checksums.ini b/build/pkgs/sphinxcontrib_websupport/checksums.ini index 5fd49b7e2ac..6291f2e8e03 100644 --- a/build/pkgs/sphinxcontrib_websupport/checksums.ini +++ b/build/pkgs/sphinxcontrib_websupport/checksums.ini @@ -1,5 +1,5 @@ tarball=sphinxcontrib-websupport-VERSION.tar.gz -sha1=313f4b764872d36f890e76579985e6aaa732f4ca -md5=4fe4d07afe1556c65182d0437228d7bb -cksum=1830011133 +sha1=39f6170825895ffeb0e06d52e351932b5f0c0147 +md5=eecfd8dc4933bd28c07ffb5e64fa2444 +cksum=431532871 upstream_url=https://pypi.io/packages/source/s/sphinxcontrib-websupport/sphinxcontrib-websupport-VERSION.tar.gz diff --git a/build/pkgs/sphinxcontrib_websupport/package-version.txt b/build/pkgs/sphinxcontrib_websupport/package-version.txt index 6085e946503..e8ea05db814 100644 --- a/build/pkgs/sphinxcontrib_websupport/package-version.txt +++ b/build/pkgs/sphinxcontrib_websupport/package-version.txt @@ -1 +1 @@ -1.2.1 +1.2.4 From 9ee86aed6363aeead54a4076641e774d5f4e1232 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 5 Oct 2022 13:51:20 +0100 Subject: [PATCH 266/350] reflect the progress on #29413 in comments --- build/pkgs/cddlib/spkg-configure.m4 | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/build/pkgs/cddlib/spkg-configure.m4 b/build/pkgs/cddlib/spkg-configure.m4 index ad227f032ed..5a710c72610 100644 --- a/build/pkgs/cddlib/spkg-configure.m4 +++ b/build/pkgs/cddlib/spkg-configure.m4 @@ -40,15 +40,9 @@ EOF AC_MSG_RESULT([yes]) ]) ]) - dnl Recent versions (>= 0.94k) of cddlib put these headers in + dnl Recent versions (>= 0.94k) of cddlib put cddlib's headers in dnl a "cddlib" subdirectory, and Debian currently relocates them - dnl under "cdd". But for now they're at the top-level, in e.g. - dnl /usr/include/cdd.h. The lattE and gfan packages within - dnl SageMath both look for them there, so that's where we have to - dnl check, passing up a chance to detect cddlib on Fedora and Debian - dnl for now. Once all of cddlib's consumers know about the new (or - dnl both) locations, we can update this check to support them. - dnl See https://trac.sagemath.org/ticket/29413 + dnl under "cdd". See trac #34634 for the latter. AC_CHECK_HEADER([cddlib/cdd.h],[],[sage_spkg_install_cddlib=yes],[ #include #include From 0c27c4f85247e7af526a5c4bb0fbb378c5ff1c2c Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 5 Oct 2022 20:44:42 +0100 Subject: [PATCH 267/350] all good on Debian --- build/pkgs/cddlib/spkg-configure.m4 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/pkgs/cddlib/spkg-configure.m4 b/build/pkgs/cddlib/spkg-configure.m4 index 5a710c72610..8508f28512d 100644 --- a/build/pkgs/cddlib/spkg-configure.m4 +++ b/build/pkgs/cddlib/spkg-configure.m4 @@ -41,8 +41,7 @@ EOF ]) ]) dnl Recent versions (>= 0.94k) of cddlib put cddlib's headers in - dnl a "cddlib" subdirectory, and Debian currently relocates them - dnl under "cdd". See trac #34634 for the latter. + dnl a "cddlib" subdirectory. AC_CHECK_HEADER([cddlib/cdd.h],[],[sage_spkg_install_cddlib=yes],[ #include #include From c4aab9f9dc11d787945fad21be16beee4b025456 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Thu, 6 Oct 2022 12:14:43 +0800 Subject: [PATCH 268/350] 32686: Remove unused imports and variables --- src/sage/schemes/projective/proj_bdd_height.py | 3 --- src/sage/schemes/projective/projective_space.py | 1 - 2 files changed, 4 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 0cc57507158..c36ca173fd9 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -195,7 +195,6 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): else: K_degree = K.degree() - K_embeddings = K.places(prec=prec) roots_of_unity = K.roots_of_unity() unit_tuples = list(itertools.product(roots_of_unity, repeat=dim)) @@ -204,8 +203,6 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): Reals = RealField(prec) logB = Reals(bound).log() - points_of_bdd_height = [] - class_group_ideals = [c.ideal() for c in K.class_group()] class_number = len(class_group_ideals) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 117e071a67b..e4d100caa1e 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -80,7 +80,6 @@ # **************************************************************************** from sage.arith.misc import gcd, binomial -from sage.arith.srange import srange from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.integer import Integer From 8e95731eaec4211fd8e08d7ef3799a4640e5c107 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 7 Oct 2022 13:46:25 +0900 Subject: [PATCH 269/350] Minor edits mostly on spaces Minor edits --- .../elliptic_curves/ell_curve_isogeny.py | 23 ++----- src/sage/schemes/elliptic_curves/hom.py | 10 +-- .../schemes/elliptic_curves/hom_composite.py | 19 ++++-- .../schemes/elliptic_curves/hom_velusqrt.py | 66 +++++++++---------- 4 files changed, 52 insertions(+), 66 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index f6a90401f01..3a18e7d4a38 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -18,14 +18,18 @@ sage: Q = E(6,5) sage: phi = E.isogeny(Q) sage: phi - Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 to Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11 + Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x + 1 over + Finite Field of size 11 to Elliptic Curve defined by y^2 = x^3 + 7*x + 8 + over Finite Field of size 11 sage: P = E(4,5) sage: phi(P) (10 : 0 : 1) sage: phi.codomain() Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11 sage: phi.rational_maps() - ((x^7 + 4*x^6 - 3*x^5 - 2*x^4 - 3*x^3 + 3*x^2 + x - 2)/(x^6 + 4*x^5 - 4*x^4 - 5*x^3 + 5*x^2), (x^9*y - 5*x^8*y - x^7*y + x^5*y - x^4*y - 5*x^3*y - 5*x^2*y - 2*x*y - 5*y)/(x^9 - 5*x^8 + 4*x^6 - 3*x^4 + 2*x^3)) + ((x^7 + 4*x^6 - 3*x^5 - 2*x^4 - 3*x^3 + 3*x^2 + x - 2)/(x^6 + 4*x^5 - 4*x^4 + - 5*x^3 + 5*x^2), (x^9*y - 5*x^8*y - x^7*y + x^5*y - x^4*y - 5*x^3*y - + 5*x^2*y - 2*x*y - 5*y)/(x^9 - 5*x^8 + 4*x^6 - 3*x^4 + 2*x^3)) The methods directly accessible from an elliptic curve ``E`` over a field are @@ -337,7 +341,6 @@ def compute_vw_kohel_even_deg3(b2, b4, s1, s2, s3): w = 3*(s1**3 - 3*s1*s2 + 3*s3) + (b2*temp1 + b4*s1)/2 return v, w - def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): r""" Compute Vélu's `(v,w)` using Kohel's formulas for isogenies of odd @@ -374,7 +377,6 @@ def compute_vw_kohel_odd(b2, b4, b6, s1, s2, s3, n): w = 10*(s1**3 - 3*s1*s2 + 3*s3) + 2*b2*(s1**2 - 2*s2) + 3*b4*s1 + n*b6 return v, w - def compute_codomain_kohel(E, kernel): r""" Compute the codomain from the kernel polynomial using Kohel's @@ -481,7 +483,6 @@ def compute_codomain_kohel(E, kernel): return compute_codomain_formula(E, v, w) - def two_torsion_part(E, psi): r""" Return the greatest common divisor of ``psi`` and the 2-torsion @@ -516,6 +517,7 @@ def two_torsion_part(E, psi): psi_2 = E.two_division_polynomial(x) return psi.gcd(psi_2) + class EllipticCurveIsogeny(EllipticCurveHom): r""" This class implements separable isogenies of elliptic curves. @@ -1739,7 +1741,6 @@ def __setup_post_isomorphism(self, codomain, model): post_isom = oldE2.isomorphism_to(codomain) self.__set_post_isomorphism(codomain, post_isom) - ########################### # Velu's Formula Functions ########################### @@ -1873,7 +1874,6 @@ def __compute_codomain_via_velu(self): """ return compute_codomain_formula(self._domain, self.__v, self.__w) - @staticmethod def __velu_sum_helper(xQ, Qvalues, a1, a3, x, y): r""" @@ -1922,7 +1922,6 @@ def __velu_sum_helper(xQ, Qvalues, a1, a3, x, y): return tX, tY - def __compute_via_velu_numeric(self, xP, yP): r""" Private function that sorts the list of points in the kernel @@ -1952,7 +1951,6 @@ def __compute_via_velu_numeric(self, xP, yP): return self.__compute_via_velu(xP,yP) - def __compute_via_velu(self, xP, yP): r""" Private function for Vélu's formulas, to perform the summation. @@ -2018,7 +2016,6 @@ def __compute_via_velu(self, xP, yP): return X, Y - def __initialize_rational_maps_via_velu(self): r""" Private function for Vélu's formulas, helper function to @@ -2040,7 +2037,6 @@ def __initialize_rational_maps_via_velu(self): y = self.__mpoly_ring.gen(1) return self.__compute_via_velu(x,y) - def __init_kernel_polynomial_velu(self): r""" Private function for Vélu's formulas, helper function to @@ -2070,7 +2066,6 @@ def __init_kernel_polynomial_velu(self): self.__kernel_polynomial = psi - ################################### # Kohel's Variant of Velu's Formula ################################### @@ -2262,7 +2257,6 @@ def __init_even_kernel_polynomial(self, E, psi_G): return phi, omega, v, w, n, d - def __init_odd_kernel_polynomial(self, E, psi): r""" Return the isogeny parameters for a cyclic isogeny of odd degree. @@ -2363,7 +2357,6 @@ def __init_odd_kernel_polynomial(self, E, psi): return phi, omega, v, w, n, d - # # This is the fast omega computation that works when characteristic is not 2 # @@ -3246,7 +3239,6 @@ def split_kernel_polynomial(poly): from sage.misc.misc_c import prod return prod([p for p,e in poly.squarefree_decomposition()]) - def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm="starks"): r""" Return the kernel polynomial of an isogeny of degree ``ell`` @@ -3487,7 +3479,6 @@ def compute_sequence_of_maps(E1, E2, ell): return pre_isom, post_isom, E1pr, E2pr, ker_poly - # Utility functions for manipulating isogeny degree matrices def fill_isogeny_matrix(M): diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 76087e95c7f..f69c6ead9b3 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -20,7 +20,6 @@ - Lorenz Panny (2021): Refactor isogenies and isomorphisms into the common :class:`EllipticCurveHom` interface. """ - from sage.misc.cachefunc import cached_method from sage.structure.richcmp import richcmp_not_equal, richcmp, op_EQ, op_NE @@ -93,7 +92,6 @@ def _composition_(self, other, homset): from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite return EllipticCurveHom_composite.from_factors([other, self]) - @staticmethod def _comparison_impl(left, right, op): """ @@ -194,7 +192,6 @@ def _richcmp_(self, other, op): return richcmp(self.rational_maps(), other.rational_maps(), op) - def degree(self): r""" Return the degree of this elliptic-curve morphism. @@ -327,11 +324,10 @@ def x_rational_map(self): ... NotImplementedError: ... """ - #TODO: could have a default implementation that simply - # returns the first component of rational_maps() + # TODO: could have a default implementation that simply + # returns the first component of rational_maps() raise NotImplementedError('children must implement') - def scaling_factor(self): r""" Return the Weierstrass scaling factor associated to this @@ -409,7 +405,6 @@ def formal(self, prec=20): assert th.valuation() == +1, f"th has valuation {th.valuation()} (should be +1)" return th - def is_normalized(self): r""" Determine whether this morphism is a normalized isogeny. @@ -489,7 +484,6 @@ def is_normalized(self): """ return self.scaling_factor() == 1 - def is_separable(self): r""" Determine whether or not this morphism is separable. diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 1e2ca2658b0..5d0b546488e 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -24,7 +24,9 @@ sage: EllipticCurveHom_composite(E, P) Composite morphism of degree 11150372599265311570767859136324180752990208 = 2^143: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 - To: Elliptic Curve defined by y^2 = x^3 + (18676616716352953484576727486205473216172067*z2+32690199585974925193292786311814241821808308)*x + (3369702436351367403910078877591946300201903*z2+15227558615699041241851978605002704626689722) over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 + To: Elliptic Curve defined by y^2 = x^3 + (18676616716352953484576727486205473216172067*z2+32690199585974925193292786311814241821808308)*x + + (3369702436351367403910078877591946300201903*z2+15227558615699041241851978605002704626689722) + over Finite Field in z2 of size 33451117797795934712303577408972542258970623^2 Yet, the interface provided by :class:`EllipticCurveHom_composite` is identical to :class:`EllipticCurveIsogeny` and other instantiations @@ -40,10 +42,15 @@ sage: psi(E.lift_x(11)) (352 : 73 : 1) sage: psi.rational_maps() - ((x^35 + 162*x^34 + 186*x^33 + 92*x^32 - ... + 44*x^3 + 190*x^2 + 80*x - 72)/(x^34 + 162*x^33 - 129*x^32 + 41*x^31 + ... + 66*x^3 - 191*x^2 + 119*x + 21), - (x^51*y - 176*x^50*y + 115*x^49*y - 120*x^48*y + ... + 72*x^3*y + 129*x^2*y + 163*x*y + 178*y)/(x^51 - 176*x^50 + 11*x^49 + 26*x^48 - ... - 77*x^3 + 185*x^2 + 169*x - 128)) + ((x^35 + 162*x^34 + 186*x^33 + 92*x^32 - ... + 44*x^3 + 190*x^2 + 80*x - + 72)/(x^34 + 162*x^33 - 129*x^32 + 41*x^31 + ... + 66*x^3 - 191*x^2 + 119*x + + 21), (x^51*y - 176*x^50*y + 115*x^49*y - 120*x^48*y + ... + 72*x^3*y + + 129*x^2*y + 163*x*y + 178*y)/(x^51 - 176*x^50 + 11*x^49 + 26*x^48 - ... - + 77*x^3 + 185*x^2 + 169*x - 128)) sage: psi.kernel_polynomial() - x^17 + 81*x^16 + 7*x^15 + 82*x^14 + 49*x^13 + 68*x^12 + 109*x^11 + 326*x^10 + 117*x^9 + 136*x^8 + 111*x^7 + 292*x^6 + 55*x^5 + 389*x^4 + 175*x^3 + 43*x^2 + 149*x + 373 + x^17 + 81*x^16 + 7*x^15 + 82*x^14 + 49*x^13 + 68*x^12 + 109*x^11 + 326*x^10 + + 117*x^9 + 136*x^8 + 111*x^7 + 292*x^6 + 55*x^5 + 389*x^4 + 175*x^3 + + 43*x^2 + 149*x + 373 sage: psi.dual() Composite morphism of degree 35 = 7*5: From: Elliptic Curve defined by y^2 = x^3 + 101*x + 285 over Finite Field of size 419 @@ -82,7 +89,7 @@ from sage.schemes.elliptic_curves.ell_curve_isogeny import EllipticCurveIsogeny from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism -#TODO: implement sparse strategies? (cf. the SIKE cryptosystem) +# TODO: Implement sparse strategies? (cf. the SIKE cryptosystem) def _eval_factored_isogeny(phis, P): """ @@ -468,7 +475,6 @@ def factors(self): """ return self._phis - # EllipticCurveHom methods @staticmethod @@ -765,7 +771,6 @@ def is_injective(self): """ return all(phi.is_injective() for phi in self._phis) - @staticmethod def make_default(): r""" diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 1c93950e6db..45a582782db 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -1,23 +1,18 @@ r""" -√élu Algorithm for Elliptic-Curve Isogenies - -The √élu algorithm computes isogenies of elliptic curves in time -`\tilde O(\sqrt\ell)` rather than naïvely `O(\ell)`, where `\ell` -is the degree. - -The core idea is to reindex the points in the kernel subgroup in -a baby-step-giant-step manner, then use fast resultant computations -to evaluate "elliptic polynomials" -(see :class:`FastEllipticPolynomial`) -in essentially square-root time. - -Based on experiments with Sage version 9.7, -the isogeny degree where -:class:`EllipticCurveHom_velusqrt` -begins to outperform +√élu algorithm for elliptic-curve isogenies + +The √élu algorithm computes isogenies of elliptic curves in time `\tilde +O(\sqrt\ell)` rather than naïvely `O(\ell)`, where `\ell` is the degree. + +The core idea is to reindex the points in the kernel subgroup in a +baby-step-giant-step manner, then use fast resultant computations to evaluate +"elliptic polynomials" (see :class:`FastEllipticPolynomial`) in essentially +square-root time. + +Based on experiments with Sage version 9.7, the isogeny degree where +:class:`EllipticCurveHom_velusqrt` begins to outperform :class:`~sage.schemes.elliptic_curves.ell_curve_isogeny.EllipticCurveIsogeny` -can be as low as `\approx 100`, -but is typically closer to `\approx 1000`, +can be as low as `\approx 100`, but is typically closer to `\approx 1000`, depending on the exact situation. REFERENCES: [BDLS2020]_ @@ -135,7 +130,7 @@ from sage.schemes.elliptic_curves.hom import EllipticCurveHom, compare_via_evaluation -#TODO: This is general. It should be elsewhere. +# TODO: This is general. It should be elsewhere. class ProductTree: r""" A simple product tree. @@ -264,7 +259,7 @@ def remainders(self, x): X = [X[i//2] % V[i] for i in range(len(V))] return X -#TODO: This is general. It should be elsewhere. +# TODO: This is general. It should be elsewhere. def prod_with_derivative(pairs): r""" Given a list of pairs `(f, \partial f)` of ring elements, return @@ -328,7 +323,6 @@ def __iter__(self): return tuple(prod(_aux(*tup) for tup in pairs)) - def _choose_IJK(n): r""" Helper function to choose an "index system" for the set @@ -408,6 +402,7 @@ def _points_range(rr, P, Q=None): for _ in range(a+s, b, s): yield (R := R + sP) + class FastEllipticPolynomial: r""" A class to represent and evaluate an *elliptic polynomial*, @@ -736,7 +731,7 @@ def _point_outside_subgroup(P): F = E.base_field().extension(d) E = E.base_extend(F) P = E(P) -# assert E.cardinality() > n + # assert E.cardinality() > n for _ in range(1000): Q = E.random_point() if n*Q or not P.weil_pairing(Q,n).is_one(): @@ -744,6 +739,7 @@ def _point_outside_subgroup(P): else: raise NotImplementedError('could not find a point outside the kernel') + class EllipticCurveHom_velusqrt(EllipticCurveHom): r""" This class implements separable odd-degree isogenies of elliptic @@ -1224,9 +1220,9 @@ def kernel_polynomial(self): sage: phi.kernel_polynomial().parent() Univariate Polynomial Ring in x over Finite Field in a of size 65537^2 """ - R,x = self._domain.base_ring()['x'].objgen() - h = self._h0(x) - h = h(self._pre_iso.x_rational_map()) + R, x = self._domain.base_ring()['x'].objgen() + h0 = self._h0(x) + h = h0(self._pre_iso.x_rational_map()) return R(h).monic() @cached_method @@ -1241,8 +1237,8 @@ def dual(self): EXAMPLES:: - sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) - sage: K = E.cardinality()//11 * E.gens()[0] + sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) + sage: K = E.cardinality() // 11 * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi Elliptic-curve isogeny (using √élu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 @@ -1254,7 +1250,7 @@ def dual(self): sage: phi * phi.dual() == phi.codomain().multiplication_by_m_isogeny(11) True """ - #FIXME This code fails if the degree is divisible by the characteristic. + # FIXME: This code fails if the degree is divisible by the characteristic. F = self._raw_domain.base_ring() from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism isom = ~WeierstrassIsomorphism(self._raw_domain, (~F(self._degree), 0, 0, 0)) @@ -1274,8 +1270,8 @@ def rational_maps(self): EXAMPLES:: - sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) - sage: K = E.cardinality()//11 * E.gens()[0] + sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) + sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi Elliptic-curve isogeny (using √élu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 @@ -1303,7 +1299,7 @@ def rational_maps(self): def x_rational_map(self): r""" Return the `x`-coordinate rational map of this √élu isogeny - as a univariate rational expression in `x`. + as a univariate rational function in `x`. .. NOTE:: @@ -1311,8 +1307,8 @@ def x_rational_map(self): EXAMPLES:: - sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) - sage: K = E.cardinality()//11 * E.gens()[0] + sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) + sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi Elliptic-curve isogeny (using √élu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 @@ -1348,8 +1344,8 @@ def scaling_factor(self): EXAMPLES:: - sage: E = EllipticCurve(GF(101^2), [1,1,1,1,1]) - sage: K = E.cardinality()//11 * E.gens()[0] + sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) + sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt', model='montgomery'); phi Elliptic-curve isogeny (using √élu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 From df1024d2b46e5a4d4af577ab215eae8dab7158ab Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 7 Oct 2022 14:03:30 +0900 Subject: [PATCH 270/350] Move as_morphism() --- .../elliptic_curves/ell_curve_isogeny.py | 30 ----------------- src/sage/schemes/elliptic_curves/hom.py | 33 +++++++++++++++++-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 3a18e7d4a38..d03346deacc 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2685,36 +2685,6 @@ def scaling_factor(self): sc *= self.__post_isomorphism.scaling_factor() return sc - def as_morphism(self): - r""" - Return this isogeny as a morphism of projective schemes. - - EXAMPLES:: - - sage: k = GF(11) - sage: E = EllipticCurve(k, [1,1]) - sage: Q = E(6,5) - sage: phi = E.isogeny(Q) - sage: mor = phi.as_morphism() - sage: mor.domain() == E - True - sage: mor.codomain() == phi.codomain() - True - sage: mor(Q) == phi(Q) - True - - TESTS:: - - sage: mor(0*Q) - (0 : 1 : 0) - sage: mor(1*Q) - (0 : 1 : 0) - """ - from sage.schemes.curves.constructor import Curve - X_affine = Curve(self.domain()).affine_patch(2) - Y_affine = Curve(self.codomain()).affine_patch(2) - return X_affine.hom(self.rational_maps(), Y_affine).homogenize(2) - def kernel_polynomial(self): r""" Return the kernel polynomial of this isogeny. diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index f69c6ead9b3..9bc6e6bfd47 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -651,6 +651,36 @@ def __hash__(self): """ return hash((self.domain(), self.codomain(), self.kernel_polynomial())) + def as_morphism(self): + r""" + Return ``self`` as a morphism of projective schemes. + + EXAMPLES:: + + sage: k = GF(11) + sage: E = EllipticCurve(k, [1,1]) + sage: Q = E(6,5) + sage: phi = E.isogeny(Q) + sage: mor = phi.as_morphism() + sage: mor.domain() == E + True + sage: mor.codomain() == phi.codomain() + True + sage: mor(Q) == phi(Q) + True + + TESTS:: + + sage: mor(0*Q) + (0 : 1 : 0) + sage: mor(1*Q) + (0 : 1 : 0) + """ + from sage.schemes.curves.constructor import Curve + X_affine = Curve(self.domain()).affine_patch(2) + Y_affine = Curve(self.codomain()).affine_patch(2) + return X_affine.hom(self.rational_maps(), Y_affine).homogenize(2) + def compare_via_evaluation(left, right): r""" @@ -707,7 +737,6 @@ def compare_via_evaluation(left, right): EE = E.base_extend(F.extension(e)) Ps = EE.gens() return all(left._eval(P) == right._eval(P) for P in Ps) - elif isinstance(F, number_field_base.NumberField): for _ in range(100): P = E.lift_x(F.random_element(), extend=True) @@ -715,6 +744,6 @@ def compare_via_evaluation(left, right): return left._eval(P) == right._eval(P) else: assert False, "couldn't find a point of infinite order" - else: raise NotImplementedError('not implemented for this base field') + From 10df9a648550ddf79315e9a6c9843eed01415d08 Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 7 Oct 2022 14:41:46 +0800 Subject: [PATCH 271/350] 32686: Correct example outputs in various files --- .../arithmetic_dynamics/projective_ds.py | 26 ++++++++++--------- .../schemes/projective/projective_homset.py | 2 +- .../projective/projective_rational_point.py | 3 +-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index cdfc11a9e52..f6d811f972a 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -3072,13 +3072,18 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: g = f.affine_preperiodic_model(0, 1); g Dynamical System of Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z) to - (-x^2 : 2*x^2 + 2*x*y + y^2 : 2*x^2 + 2*x*y + 2*y^2 - 2*y*z + z^2) + (-x^2 : -2*x^2 + 2*x*y - y^2 : 2*x^2 - 2*x*y + 2*y^2 + 2*y*z + z^2) We can check that ``g`` has affine fixed points:: sage: g.periodic_points(1) - [(-1 : 1 : 1), (-1/2 : 1/2 : 1), (-1/2 : 1 : 1), (-1/3 : 2/3 : 1), (0 : 0 : 1), - (0 : 1/2 : 1), (0 : 1 : 1)] + [(-1 : -1 : 1), + (-1/2 : -1 : 1), + (-1/2 : -1/2 : 1), + (-1/3 : -2/3 : 1), + (0 : -1 : 1), + (0 : -1/2 : 1), + (0 : 0 : 1)] :: @@ -3087,8 +3092,8 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: f.affine_preperiodic_model(0, 1) Dynamical System of Projective Space of dimension 2 over Finite Field in z2 of size 3^2 Defn: Defined on coordinates by sending (x : y : z) to - ((z2 + 1)*x^2 : (z2 + 1)*x^2 + (z2 + 1)*x*y + (-z2 - 1)*y^2 : - (z2 - 1)*x^2 + (z2 - 1)*x*y - y^2 + (-z2)*y*z + z^2) + ((-z2)*x^2 : z2*x^2 + (-z2)*x*y + (-z2)*y^2 : + (-z2)*x^2 + z2*x*y + (z2 + 1)*y^2 - y*z + z^2) :: @@ -3099,9 +3104,8 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Projective Space of dimension 2 over Univariate Polynomial Ring in c over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to - ((2*c^4 + c^3)*x^2 : (2*c^4 + c^3)*x^2 + (2*c^4 + c^3)*x*y + (c^4 + 2*c^3)*y^2 : - c^3*x^2 + c^3*x*y + (2*c^3 + 2*c^2)*y^2 + (c^3 + 2*c^2)*y*z + (2*c^4 + 2*c^3 + - 2*c^2)*z^2) + (2*c^3*x^2 : c^3*x^2 + 2*c^3*x*y + 2*c^3*y^2 : + 2*c^3*x^2 + c^3*x*y + (c^3 + c^2)*y^2 + 2*c^2*y*z + c^2*z^2) :: @@ -3112,8 +3116,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Projective Space of dimension 2 over Cyclotomic Field of order 3 and degree 2 Defn: Defined on coordinates by sending (x : y : z) to - (x^2 + y^2 + (-k + 2)*x*z - 2*y*z + (-k + 3)*z^2 : - -2*x^2 + (k - 4)*x*z + (k - 3)*z^2 : -x^2 + (k - 2)*x*z + (k - 2)*z^2) + (-y^2 : x^2 : x^2 + (-k)*x*z + z^2) :: @@ -3132,8 +3135,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): Dynamical System of Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: 2*y - z Defn: Defined on coordinates by sending (x : y : z) to - (2*x^2 + y^2 + 4*x*z - 2*y*z + 4*z^2 : -x^2 - y^2 - 2*x*z + 2*y*z - 3*z^2 : - -x^2 - 2*x*z - 2*z^2) + (-x^2 - y^2 : y^2 : x^2 + z^2) TESTS:: diff --git a/src/sage/schemes/projective/projective_homset.py b/src/sage/schemes/projective/projective_homset.py index 0f7b6abce52..f9a8e69bd4b 100644 --- a/src/sage/schemes/projective/projective_homset.py +++ b/src/sage/schemes/projective/projective_homset.py @@ -124,7 +124,7 @@ def points(self, **kwds): sage: K. = NumberField(u^2 + 3) sage: P. = ProjectiveSpace(K,2) sage: len(P(K).points(bound=1.8)) - 381 + 309 :: diff --git a/src/sage/schemes/projective/projective_rational_point.py b/src/sage/schemes/projective/projective_rational_point.py index 93789be8d65..cb12e30c873 100644 --- a/src/sage/schemes/projective/projective_rational_point.py +++ b/src/sage/schemes/projective/projective_rational_point.py @@ -191,8 +191,7 @@ def enum_projective_number_field(X, **kwds): sage: P. = ProjectiveSpace(K, 2) sage: X = P.subscheme([x - y]) sage: enum_projective_number_field(X(K), bound=RR(5^(1/3)), prec=2^10) - [(0 : 0 : 1), (-1 : -1 : 1), (1 : 1 : 1), (-1/5*v^2 : -1/5*v^2 : 1), (-v : -v : 1), - (1/5*v^2 : 1/5*v^2 : 1), (v : v : 1), (1 : 1 : 0)] + [(0 : 0 : 1), (1 : 1 : 0), (-1 : -1 : 1), (1 : 1 : 1)] :: From 8cb0f29aa2cd5be18506e1d65eac954481d1ec8a Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 7 Oct 2022 18:31:30 +0800 Subject: [PATCH 272/350] explain "output has linear size" remarks --- src/sage/schemes/elliptic_curves/hom_velusqrt.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 45a582782db..144b5400970 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -99,6 +99,14 @@ ... NotImplementedError: only implemented for elliptic curves over finite fields +.. NOTE:: + + Some of the methods inherited from :class:`EllipticCurveHom` compute data + whose size is linear in the degree; this includes kernel polynomial and + rational maps. In consequence, those methods cannot possibly run in the + otherwise advertised square-root complexity, as merely storing the result + already takes linear time. + AUTHORS: - Lorenz Panny (2022) From c053c2ac5367b08f553d6dd3d4fa86dec14bc09d Mon Sep 17 00:00:00 2001 From: Jing Guo Date: Fri, 7 Oct 2022 18:42:27 +0800 Subject: [PATCH 273/350] 32686: Format according to lint result --- src/sage/schemes/projective/proj_bdd_height.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index c36ca173fd9..33d5ec1d3bc 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -78,6 +78,7 @@ def QQ_points_of_bounded_height(dim, bound): points_of_bounded_height.add(point) yield point + def IQ_points_of_bounded_height(PN, K, dim, bound): r""" Return an iterator of the points in ``self`` of absolute multiplicative @@ -151,6 +152,7 @@ def IQ_points_of_bounded_height(PN, K, dim, bound): points_in_class_a.add(point) yield point + def points_of_bounded_height(PN, K, dim, bound, prec=53): r""" Return an iterator of the points in ``K`` with dimension ``dim`` of @@ -218,9 +220,9 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53): test_matrix = mat try: - test_matrix.change_ring(QQ) + test_matrix.change_ring(QQ) except ValueError: - raise ValueError('prec too low.') + raise ValueError('prec too low.') cut_fund_unit_logs = mat.delete_rows([r]) lll_fund_units = [] From 6fec49af9b5fc2e916a87984f9f77984892a1e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 8 Oct 2022 22:01:27 +0200 Subject: [PATCH 274/350] pep8 for ribbon_tableau --- src/sage/combinat/ribbon_tableau.py | 203 ++++++++++++++-------------- 1 file changed, 98 insertions(+), 105 deletions(-) diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index 8b703ee721b..273bc3d0688 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -15,6 +15,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** +import functools from sage.structure.parent import Parent from sage.structure.element import parent @@ -29,10 +30,9 @@ from sage.combinat.skew_tableau import SkewTableau, SkewTableaux, SemistandardSkewTableaux from sage.combinat.tableau import Tableaux from sage.combinat.partition import Partition, _Partitions -from . import permutation -import functools - from sage.combinat.permutation import to_standard +from sage.misc.persist import register_unpickle_override +from . import permutation class RibbonTableau(SkewTableau): @@ -76,8 +76,8 @@ class RibbonTableau(SkewTableau): sage: RibbonTableau([[0, 0, 3, 0], [1, 1, 0], [2, 0, 4]]).evaluation() [2, 1, 1, 1] """ - #The following method is private and will only get called - #when calling RibbonTableau() directly, and not via element_class + # The following method is private and will only get called + # when calling RibbonTableau() directly, and not via element_class @staticmethod def __classcall_private__(cls, rt=None, expr=None): """ @@ -98,7 +98,7 @@ def __classcall_private__(cls, rt=None, expr=None): raise TypeError("each element of the ribbon tableau must be an iterable") if not all(row for row in rt): raise TypeError("a ribbon tableau cannot have empty rows") - #calls the inherited __init__ method (of SkewTableau ) + # calls the inherited __init__ method (of SkewTableau ) return RibbonTableaux()(rt) def length(self): @@ -146,9 +146,9 @@ def to_word(self): from sage.combinat.words.word import Word return Word([letter for row in reversed(self) for letter in row]) -##################### -# Ribbon Tableaux # -##################### +# #################### +# Ribbon Tableaux # +# #################### class RibbonTableaux(UniqueRepresentation, Parent): @@ -213,7 +213,7 @@ def __classcall_private__(cls, shape=None, weight=None, length=None): True """ if shape is None and weight is None and length is None: - return super(RibbonTableaux, cls).__classcall__(cls) + return super().__classcall__(cls) return RibbonTableaux_shape_weight_length(shape, weight, length) @@ -293,7 +293,7 @@ def __classcall_private__(cls, shape, weight, length): else: shape = SkewPartition(shape) - if shape.size() != length*sum(weight): + if shape.size() != length * sum(weight): raise ValueError("Incompatible shape and weight") return super(RibbonTableaux, cls).__classcall__(cls, shape, tuple(weight), length) @@ -305,7 +305,7 @@ def __init__(self, shape, weight, length): sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1) sage: TestSuite(R).run() """ - self._shape = shape + self._shape = shape self._weight = weight self._length = length Parent.__init__(self, category=FiniteEnumeratedSets()) @@ -355,8 +355,8 @@ def __contains__(self, x): return False return x in self.list() - #return x.is_ribbon() and x.shape() == self._shape \ - #and tuple(x.weight()) == self._weight and x in list(self) + # return x.is_ribbon() and x.shape() == self._shape \ + # and tuple(x.weight()) == self._weight and x in list(self) def cardinality(self): """ @@ -449,14 +449,14 @@ def insertion_tableau(skp, perm, evaluation, tableau, length): [[1], [[1, 0], [0]]] """ psave = Partition(skp[1]) - partc = skp[1] + [0]*(len(skp[0])-len(skp[1])) + partc = skp[1] + [0] * (len(skp[0]) - len(skp[1])) tableau = SkewTableau(expr=tableau).to_expr()[1] for k in range(len(tableau)): - tableau[-(k+1)] += [0] * ( skp[0][k] - partc[k] - len(tableau[-(k+1)])) + tableau[-(k + 1)] += [0] * (skp[0][k] - partc[k] - len(tableau[-(k + 1)])) - ## We construct a tableau from the southwest corner to the northeast one + # We construct a tableau from the southwest corner to the northeast one tableau = [[0] * (skp[0][k] - partc[k]) for k in reversed(range(len(tableau), len(skp[0])))] + tableau @@ -464,16 +464,17 @@ def insertion_tableau(skp, perm, evaluation, tableau, length): tableau = tableau.to_expr()[1] skp = SkewPartition(skp).conjugate().to_list() - skp[1].extend( [0]*(len(skp[0])-len(skp[1])) ) + skp[1].extend([0] * (len(skp[0]) - len(skp[1]))) if len(perm) > len(skp[0]): return None - for k in range(len(perm)): - if perm[ -(k+1) ] !=0: - tableau[len(tableau)-len(perm)+k][ skp[0][len(perm)-(k+1)] - skp[1][ len(perm)-(k+1) ] - 1 ] = evaluation + lp = len(perm) + for k in range(lp): + if perm[-(k + 1)] != 0: + tableau[len(tableau) - lp + k][skp[0][lp - (k + 1)] - skp[1][lp - (k + 1)] - 1] = evaluation - return SkewTableau(expr=[psave.conjugate(),tableau]).conjugate().to_expr() + return SkewTableau(expr=[psave.conjugate(), tableau]).conjugate().to_expr() def count_rec(nexts, current, part, weight, length): @@ -547,30 +548,28 @@ def list_rec(nexts, current, part, weight, length): [[[], [[2, 2], [1, 1]]]] """ if current == [] and nexts == [] and weight == []: - return [[part[1],[]]] + return [[part[1], []]] - ## Test if the current nodes is not an empty node + # Test if the current nodes is not an empty node if not current: return [] - ## Test if the current nodes drive us to new solutions + # Test if the current nodes drive us to new solutions if nexts: - res = [] - for i in range(len(current)): - for j in range(len(nexts[i])): - res.append( insertion_tableau(part, current[i][1], len(weight), nexts[i][j], length) ) - return res - else: - ## The current nodes are at the bottom of the tree - res = [] - for i in range(len(current)): - res.append( insertion_tableau(part, current[i][1], len(weight), [[],[]], length) ) - return res + return [insertion_tableau(part, curr_i[1], len(weight), + nexts_ij, length) + for nexts_i, curr_i in zip(nexts, current) + for nexts_ij in nexts_i] + + # The current nodes are at the bottom of the tree + return [insertion_tableau(part, curr_i[1], + len(weight), [[], []], length) + for curr_i in current] -############################# -#Spin and Cospin Polynomials# -############################# +# ############################# +# Spin and Cospin Polynomials # +# ############################# def spin_rec(t, nexts, current, part, weight, length): """ Routine used for constructing the spin polynomial. @@ -606,19 +605,18 @@ def spin_rec(t, nexts, current, part, weight, length): partp = part[0].conjugate() ell = len(partp) - #compute the contribution of the ribbons added at - #the current node + # compute the contribution of the ribbons added at + # the current node for val in current: perms = val[1] perm = [partp[i] + ell - (i + 1) - perms[i] for i in reversed(range(ell))] perm = to_standard(perm) - tmp.append( weight[-1]*(length-1) - perm.number_of_inversions() ) + tmp.append(weight[-1] * (length - 1) - perm.number_of_inversions()) if nexts: - return [ sum(sum(t**tval * nval for nval in nexts[i]) - for i, tval in enumerate(tmp)) ] - else: - return [ sum(t**val for val in tmp) ] + return [sum(sum(t**tval * nval for nval in nexts[i]) + for i, tval in enumerate(tmp))] + return [sum(t**val for val in tmp)] def spin_polynomial_square(part, weight, length): @@ -647,15 +645,16 @@ def spin_polynomial_square(part, weight, length): R = ZZ['t'] if part in _Partitions: - part = SkewPartition([part,_Partitions([])]) + part = SkewPartition([part, _Partitions([])]) elif part in SkewPartitions(): part = SkewPartition(part) - if part == [[],[]] and weight == []: + if part == [[], []] and not weight: return R.one() t = R.gen() - return R(graph_implementation_rec(part, weight, length, functools.partial(spin_rec,t))[0]) + return R(graph_implementation_rec(part, weight, length, + functools.partial(spin_rec, t))[0]) def spin_polynomial(part, weight, length): @@ -685,7 +684,7 @@ def spin_polynomial(part, weight, length): sp = spin_polynomial_square(part, weight, length) t = SR.var('t') coeffs = sp.list() - return sum(c * t**(QQ(i)/2) for i,c in enumerate(coeffs)) + return sum(c * t**(QQ(i) / 2) for i, c in enumerate(coeffs)) def cospin_polynomial(part, weight, length): @@ -720,22 +719,22 @@ def cospin_polynomial(part, weight, length): if sp == 0: return R.zero() - coeffs = [c for c in sp.list() if c != 0] + coeffs = [c for c in sp.list() if c] d = len(coeffs) - 1 t = R.gen() - return R( sum(c * t**(d-i) for i,c in enumerate(coeffs)) ) + return R(sum(c * t**(d - i) for i, c in enumerate(coeffs))) -## ////////////////////////////////////////////////////////////////////////////////////////// -## // Generic function for driving into the graph of partitions coding all ribbons -## // tableaux of a given shape and weight -## ////////////////////////////////////////////////////////////////////////////////////////// -## //This function construct the graph of the set of k-ribbon tableaux -## //of a given skew shape and a given weight. -## //The first argument is always a skew partition. -## //In the case where the inner partition is empty there is no branch without solutions -## //In the other cases there is in average a lot of branches without solutions -## ///////////////////////////////////////////////////////////////////////////////////////// +# ////////////////////////////////////////////////////////////////////////////////////////// +# // Generic function for driving into the graph of partitions coding all ribbons +# // tableaux of a given shape and weight +# ////////////////////////////////////////////////////////////////////////////////////////// +# // This function constructs the graph of the set of k-ribbon tableaux +# // of a given skew shape and a given weight. +# // The first argument is always a skew partition. +# // In the case where the inner partition is empty, there is no branch without solutions. +# // In the other cases, there is in average a lot of branches without solutions. +# ///////////////////////////////////////////////////////////////////////////////////////// def graph_implementation_rec(skp, weight, length, function): @@ -760,16 +759,16 @@ def graph_implementation_rec(skp, weight, length, function): # Some tests in order to know if the shape and the weight are compatible. if weight and weight[-1] <= len(partp): - perms = permutation.Permutations([0]*(len(partp)-weight[-1]) + [length]*(weight[-1])).list() + perms = permutation.Permutations([0] * (len(partp) - weight[-1]) + [length] * (weight[-1])).list() else: return function([], [], skp, weight, length) selection = [] for j in range(len(perms)): - retire = [(val + ell - (i+1) - perms[j][i]) for i,val in enumerate(partp)] + retire = [(val + ell - (i + 1) - perms[j][i]) for i, val in enumerate(partp)] retire.sort(reverse=True) - retire = [val - ell + (i+1) for i,val in enumerate(retire)] + retire = [val - ell + (i + 1) for i, val in enumerate(retire)] if retire[-1] >= 0 and retire == sorted(retire, reverse=True): retire = Partition(retire).conjugate() @@ -784,13 +783,13 @@ def graph_implementation_rec(skp, weight, length, function): if append: selection.append([retire, perms[j]]) - #selection contains the list of current nodes + # selection contains the list of current nodes if len(weight) == 1: return function([], selection, skp, weight, length) else: - #The recursive calls permit us to construct the list of the sons - #of all current nodes in selection + # The recursive calls permit us to construct the list of the sons + # of all current nodes in selection a = [graph_implementation_rec([p[0], outer], weight[:-1], length, function) for p in selection] return function(a, selection, skp, weight, length) @@ -828,12 +827,13 @@ def __classcall_private__(cls, x): """ if isinstance(x, MultiSkewTableau): return x - - return MultiSkewTableaux()([SkewTableau(i) for i in x] ) + return MultiSkewTableaux()([SkewTableau(i) for i in x]) def size(self): """ - Return the size of ``self``, which is the sum of the sizes of the skew + Return the size of ``self``. + + This is the sum of the sizes of the skew tableaux in ``self``. EXAMPLES:: @@ -858,7 +858,7 @@ def weight(self): """ weights = [x.weight() for x in self] m = max([len(x) for x in weights]) - weight = [0]*m + weight = [0] * m for w in weights: for i in range(len(w)): weight[i] += w[i] @@ -896,7 +896,7 @@ def inversion_pairs(self): inv = [] for k in range(len(self)): for b in self[k].cells(): - inv += self._inversion_pairs_from_position(k,b) + inv += self._inversion_pairs_from_position(k, b) return inv def inversions(self): @@ -937,25 +937,25 @@ def _inversion_pairs_from_position(self, k, ij): [((1, (0, 1)), (2, (0, 0)))] """ pk = k - pi,pj = ij + pi, pj = ij c = pi - pj value = self[pk][pi][pj] pk_cells = self[pk].cells_by_content(c) - same_diagonal = [ t.cells_by_content(c) for t in self[pk+1:] ] - above_diagonal = [ t.cells_by_content(c+1) for t in self[pk+1:] ] + same_diagonal = [t.cells_by_content(c) for t in self[pk + 1:]] + above_diagonal = [t.cells_by_content(c + 1) for t in self[pk + 1:]] res = [] - for i,j in pk_cells: + for i, j in pk_cells: if pi < i and value > self[pk][i][j]: - res.append( ((pk,(pi,pj)), (pk,(i,j))) ) + res.append(((pk, (pi, pj)), (pk, (i, j)))) for k in range(len(same_diagonal)): - for i,j in same_diagonal[k]: - if value > self[pk+k+1][i][j]: - res.append( ((pk,(pi,pj)), (pk+k+1,(i,j))) ) + for i, j in same_diagonal[k]: + if value > self[pk + k + 1][i][j]: + res.append(((pk, (pi, pj)), (pk + k + 1, (i, j)))) for k in range(len(above_diagonal)): - for i,j in above_diagonal[k]: - if value < self[pk+k+1][i][j]: - res.append( ((pk,(pi,pj)), (pk+k+1,(i,j))) ) + for i, j in above_diagonal[k]: + if value < self[pk + k + 1][i][j]: + res.append(((pk, (pi, pj)), (pk + k + 1, (i, j)))) return res @@ -1042,7 +1042,7 @@ def __classcall_private__(cls, shape, weight): if sum(weight) != sum(s.size() for s in shape): raise ValueError("the sum of weight must be the sum of the sizes of shape") - return super(SemistandardMultiSkewTableaux, cls).__classcall__(cls, shape, weight) + return super().__classcall__(cls, shape, weight) def __init__(self, shape, weight): """ @@ -1051,7 +1051,7 @@ def __init__(self, shape, weight): sage: S = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2]) sage: TestSuite(S).run() """ - self._shape = shape + self._shape = shape self._weight = weight MultiSkewTableaux.__init__(self, category=FiniteEnumeratedSets()) @@ -1080,14 +1080,9 @@ def __contains__(self, x): return False if x.weight() != list(self._weight): return False - if x.shape() != list(self._shape): return False - - if not all( x[i].is_semistandard() for i in range(len(x)) ): - return False - - return True + return all(xi.is_semistandard() for xi in x) def __iter__(self): """ @@ -1097,8 +1092,6 @@ def __iter__(self): sage: SemistandardMultiSkewTableaux([SkewPartition([[1, 1, 1], []]), SkewPartition([[3], []])],[2,2,2]).list() [[[[1], [2], [3]], [[1, 2, 3]]]] - :: - sage: a = SkewPartition([[8,7,6,5,1,1],[2,1,1]]) sage: weight = [3,3,2] sage: k = 3 @@ -1120,21 +1113,21 @@ def __iter__(self): for i in range(1, len(parts)): trans = parttmp[0][0] current_part = parts[i] - current_part[1] += [0]*(len(current_part[0])-len(current_part[1])) - inner_current = [ trans + j for j in current_part[1] ] - outer_current = [ trans + j for j in current_part[0] ] - parttmp = [ outer_current + parttmp[0], inner_current + parttmp[1] ] + current_part[1] += [0] * (len(current_part[0]) - len(current_part[1])) + inner_current = [trans + j for j in current_part[1]] + outer_current = [trans + j for j in current_part[0]] + parttmp = [outer_current + parttmp[0], inner_current + parttmp[1]] # List the corresponding skew tableaux - l = [ st.to_word() for st in SemistandardSkewTableaux(parttmp, mu) ] + l = (st.to_word() for st in SemistandardSkewTableaux(parttmp, mu)) S = SkewTableaux() - for k in range(len(l)): - pos = 0 #Double check this - restmp = [ S.from_shape_and_word(parts[0], [l[k][j] for j in range(s[0])]) ] + for lk in l: + pos = 0 # Double check this + restmp = [S.from_shape_and_word(parts[0], [lk[j] for j in range(s[0])])] for i in range(1, len(parts)): - w = [l[k][j] for j in range(pos+s[i-1], pos+s[i-1]+s[i])] - restmp.append( S.from_shape_and_word(parts[i], w) ) + w = [lk[j] for j in range(pos + s[i - 1], pos + s[i - 1] + s[i])] + restmp.append(S.from_shape_and_word(parts[i], w)) yield self.element_class(self, restmp) @@ -1156,7 +1149,7 @@ def __setstate__(self, state): self.__class__ = RibbonTableau self.__init__(RibbonTableaux(), state['_list']) -from sage.misc.persist import register_unpickle_override + register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableau_class', RibbonTableau_class) register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableaux_shapeweightlength', RibbonTableaux) register_unpickle_override('sage.combinat.ribbon_tableau', 'SemistandardMultiSkewTtableaux_shapeweight', SemistandardMultiSkewTableaux) From e76b77aa21ac863922db119572e0eb4868f5e086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 9 Oct 2022 09:48:58 +0200 Subject: [PATCH 275/350] one more detail about super --- src/sage/combinat/ribbon_tableau.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index 273bc3d0688..31b4fd2e2e2 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -294,9 +294,9 @@ def __classcall_private__(cls, shape, weight, length): shape = SkewPartition(shape) if shape.size() != length * sum(weight): - raise ValueError("Incompatible shape and weight") + raise ValueError("incompatible shape and weight") - return super(RibbonTableaux, cls).__classcall__(cls, shape, tuple(weight), length) + return super().__classcall__(cls, shape, tuple(weight), length) def __init__(self, shape, weight, length): """ From f948791311cb5bd47d22d5476180c93b2e529a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 9 Oct 2022 14:06:42 +0200 Subject: [PATCH 276/350] fix some W605 in pyx files in rings/ --- src/sage/rings/finite_rings/element_base.pyx | 4 +-- .../rings/finite_rings/element_ntl_gf2e.pyx | 2 +- .../rings/finite_rings/finite_field_base.pyx | 2 +- src/sage/rings/finite_rings/integer_mod.pyx | 32 ++++++++----------- src/sage/rings/finite_rings/residue_field.pyx | 4 +-- .../number_field/number_field_element.pyx | 6 ++-- .../number_field_element_quadratic.pyx | 18 +++++------ .../number_field/number_field_morphisms.pyx | 11 +++---- .../rings/polynomial/laurent_polynomial.pyx | 5 +-- .../rings/polynomial/multi_polynomial.pyx | 15 +++++---- .../multi_polynomial_libsingular.pyx | 14 ++++---- .../polynomial/ore_polynomial_element.pyx | 8 ++--- src/sage/rings/polynomial/plural.pyx | 3 +- .../rings/polynomial/polynomial_element.pyx | 15 +++++---- src/sage/rings/polynomial/polynomial_gf2x.pyx | 4 +-- .../polynomial_integer_dense_flint.pyx | 4 +-- .../polynomial/polynomial_modn_dense_ntl.pyx | 9 +++--- .../polynomial/polynomial_zmod_flint.pyx | 2 +- src/sage/rings/polynomial/real_roots.pyx | 12 ++++--- .../rings/polynomial/symmetric_reduction.pyx | 9 +++--- 20 files changed, 88 insertions(+), 91 deletions(-) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index d4dd6b22ee4..ec8d50d4f07 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -983,9 +983,10 @@ cdef class FinitePolyExtElement(FiniteRingElement): return self.pth_power(k=k) + cdef class Cache_base(SageObject): cpdef FinitePolyExtElement fetch_int(self, number): - """ + r""" Given an integer less than `p^n` with base `2` representation `a_0 + a_1 \cdot 2 + \cdots + a_k 2^k`, this returns `a_0 + a_1 x + \cdots + a_k x^k`, where `x` is the @@ -998,4 +999,3 @@ cdef class Cache_base(SageObject): a^33 + a + 1 """ raise NotImplementedError("this must be implemented by subclasses") - diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index a9c85582af7..96e4e3df8d9 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -401,7 +401,7 @@ cdef class Cache_ntl_gf2e(Cache_base): raise ValueError("Cannot coerce element %s to this field." % e) cpdef FiniteField_ntl_gf2eElement fetch_int(self, number): - """ + r""" Given an integer less than `p^n` with base `2` representation `a_0 + a_1 \cdot 2 + \cdots + a_k 2^k`, this returns `a_0 + a_1 x + \cdots + a_k x^k`, where `x` is the diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index caeadff7ae2..c91126649f1 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1021,7 +1021,7 @@ cdef class FiniteField(Field): return self._modulus def polynomial(self, name=None): - """ + r""" Return the minimal polynomial of the generator of ``self`` over the prime finite field. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 400bf154522..58218d9a193 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -116,8 +116,9 @@ from sage.groups.generic import discrete_log cdef Integer one_Z = Integer(1) + def Mod(n, m, parent=None): - """ + r""" Return the equivalence class of `n` modulo `m` as an element of `\ZZ/m\ZZ`. @@ -1598,7 +1599,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): return [a for a in self.parent() if a**n == self] def _balanced_abs(self): - """ + r""" This function returns `x` or `-x`, whichever has a positive representative in `-n/2 < x \leq n/2`. @@ -1608,8 +1609,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): """ if self.lift() > self.__modulus.sageInteger >> 1: return -self - else: - return self + return self def rational_reconstruction(self): """ @@ -1947,7 +1947,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): cdef class IntegerMod_gmp(IntegerMod_abstract): - """ + r""" Elements of `\ZZ/n\ZZ` for n not small enough to be operated on in word size. @@ -2354,7 +2354,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): @coerce_binop def gcd(self, IntegerMod_gmp other): - """ + r""" Greatest common divisor Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal @@ -2387,7 +2387,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): cdef class IntegerMod_int(IntegerMod_abstract): - """ + r""" Elements of `\ZZ/n\ZZ` for n small enough to be operated on in 32 bits @@ -3022,20 +3022,18 @@ cdef class IntegerMod_int(IntegerMod_abstract): # Either it failed but extend was True, or the generic algorithm is better return IntegerMod_abstract.sqrt(self, extend=extend, all=all) - def _balanced_abs(self): - """ + r""" This function returns `x` or `-x`, whichever has a positive representative in `-n/2 < x \leq n/2`. """ if self.ivalue > self.__modulus.int32 / 2: return -self - else: - return self + return self @coerce_binop def gcd(self, IntegerMod_int other): - """ + r""" Greatest common divisor Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal @@ -3213,7 +3211,7 @@ cdef int jacobi_int(int_fast32_t a, int_fast32_t m) except -2: ###################################################################### cdef class IntegerMod_int64(IntegerMod_abstract): - """ + r""" Elements of `\ZZ/n\ZZ` for n small enough to be operated on in 64 bits @@ -3688,22 +3686,20 @@ cdef class IntegerMod_int64(IntegerMod_abstract): sage: hash(a) 8943 """ - return hash(self.ivalue) def _balanced_abs(self): - """ + r""" This function returns `x` or `-x`, whichever has a positive representative in `-n/2 < x \leq n/2`. """ if self.ivalue > self.__modulus.int64 / 2: return -self - else: - return self + return self @coerce_binop def gcd(self, IntegerMod_int64 other): - """ + r""" Greatest common divisor Returns the "smallest" generator in `\ZZ / N\ZZ` of the ideal diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 7596f2a3028..dbef75e9fe6 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -1,4 +1,4 @@ -""" +r""" Finite residue fields We can take the residue field of maximal ideals in the ring of integers @@ -1846,7 +1846,7 @@ class ResidueFiniteField_ntl_gf2e(ResidueField_generic, FiniteField_ntl_gf2e): """ # we change the order for consistency with FiniteField_ntl_gf2e's __cinit__ def __init__(self, q, name, modulus, repr, p, to_vs, to_order, PB): - """ + r""" INPUT: - ``p`` -- the prime ideal defining this residue field diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 784c239dc10..b78bc33078c 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -493,7 +493,7 @@ cdef class NumberFieldElement(FieldElement): return codomain(f(im_gens[0])) def _latex_(self): - """ + r""" Returns the latex representation for this element. EXAMPLES:: @@ -3988,8 +3988,8 @@ cdef class NumberFieldElement(FieldElement): return ht def global_height_non_arch(self, prec=None): - """ - Returns the total non-archimedean component of the height of self. + r""" + Return the total non-archimedean component of the height of ``self``. INPUT: diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index 24fc7db909e..04224f2f208 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -4,7 +4,7 @@ # distutils: library_dirs = NTL_LIBDIR # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -""" +r""" Optimized Quadratic Number Field Elements This file defines a Cython class ``NumberFieldElement_quadratic`` to speed up @@ -23,16 +23,15 @@ AUTHORS: The ``_new()`` method should be overridden in this class to copy the ``D`` and ``standard_embedding`` attributes """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Robert Bradshaw # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** include "sage/libs/ntl/decl.pxi" from cpython.object cimport Py_EQ, Py_NE, Py_LE, Py_GE, Py_LT, Py_GT @@ -1634,7 +1633,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): ################################################################################# def __hash__(self): - """ + r""" Return hash of this number field element. For elements in `\ZZ` or `\QQ` the hash coincides with the one in the @@ -2019,10 +2018,11 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): mpq_canonicalize(res.value) return res - def norm(self, K=None): - """ - Return the norm of self. If the second argument is None, this is the + r""" + Return the norm of ``self``. + + If the second argument is ``None``, this is the norm down to `\QQ`. Otherwise, return the norm down to K (which had better be either `\QQ` or this number field). diff --git a/src/sage/rings/number_field/number_field_morphisms.pyx b/src/sage/rings/number_field/number_field_morphisms.pyx index 605026be684..9f77c9e3949 100644 --- a/src/sage/rings/number_field/number_field_morphisms.pyx +++ b/src/sage/rings/number_field/number_field_morphisms.pyx @@ -4,8 +4,7 @@ Embeddings into ambient fields This module provides classes to handle embeddings of number fields into ambient fields (generally `\RR` or `\CC`). """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Robert Bradshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -17,8 +16,8 @@ fields (generally `\RR` or `\CC`). # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.rings.complex_double @@ -345,7 +344,7 @@ cpdef matching_root(poly, target, ambient_field=None, margin=1, max_prec=None): target best approximates as compared in ambient_field. If the parent of target is exact, the equality is required, otherwise - find closest root (with respect to the \code{abs} function) in the + find closest root (with respect to the ``abs`` function) in the ambient field to the target, and return the root of poly (if any) that approximates it best. @@ -405,7 +404,7 @@ cpdef matching_root(poly, target, ambient_field=None, margin=1, max_prec=None): cpdef closest(target, values, margin=1): """ This is a utility function that returns the item in values closest to - target (with respect to the \code{abs} function). If margin is greater + target (with respect to the ``abs`` function). If margin is greater than 1, and x and y are the first and second closest elements to target, then only return x if x is margin times closer to target than y, i.e. margin * abs(target-x) < abs(target-y). diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index c82cf65eb0f..bf14caabff9 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -294,10 +294,11 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): R = R.change_ring(new_base_ring) elif isinstance(f, Map): R = R.change_ring(f.codomain()) - return R(dict([(k,f(v)) for (k,v) in self.dict().items()])) + return R(dict([(k, f(v)) for (k, v) in self.dict().items()])) + cdef class LaurentPolynomial_univariate(LaurentPolynomial): - """ + r""" A univariate Laurent polynomial in the form of `t^n \cdot f` where `f` is a polynomial in `t`. diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index ce14319f63a..1a80a2cbb1f 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -196,12 +196,12 @@ cdef class MPolynomial(CommutativeRingElement): var = R.variable_name() if var in self._parent.variable_names(): return R(self.polynomial(self._parent(var))) - else: - return R([self]) + return R([self]) def coefficients(self): - """ + r""" Return the nonzero coefficients of this polynomial in a list. + The returned list is decreasingly ordered by the term ordering of ``self.parent()``, i.e. the list of coefficients matches the list of monomials returned by @@ -1315,11 +1315,12 @@ cdef class MPolynomial(CommutativeRingElement): return R(dict([(k,f(v)) for (k,v) in self.dict().items()])) def _norm_over_nonprime_finite_field(self): - """ + r""" Given a multivariate polynomial over a nonprime finite field - `\GF{p**e}`, compute the norm of the polynomial down to `\GF{p}`, which - is the product of the conjugates by the Frobenius action on - coefficients, where Frobenius acts by p-th power. + `\GF{p^e}`, compute the norm of the polynomial down to `\GF{p}`. + + This is the product of the conjugates by the Frobenius action + on coefficients, where Frobenius acts by p-th power. This is (currently) an internal function used in factoring over finite fields. diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 2109c516a1c..4dad016b33f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -1984,7 +1984,6 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: R. = QQ[] sage: x._new_constant_poly(2/1,R) 2 - """ if not x: return new_MP(P, NULL) @@ -1993,7 +1992,7 @@ cdef class MPolynomial_libsingular(MPolynomial): return new_MP(P, _p) def __call__(self, *x, **kwds): - """ + r""" Evaluate this multi-variate polynomial at ``x``, where ``x`` is either the tuple of values to substitute in, or one can use functional notation ``f(a_0,a_1,a_2, \ldots)`` to evaluate @@ -2261,7 +2260,7 @@ cdef class MPolynomial_libsingular(MPolynomial): return new_MP((left)._parent,_p) cpdef _div_(left, right_ringelement): - """ + r""" Divide left by right EXAMPLES:: @@ -4576,7 +4575,7 @@ cdef class MPolynomial_libsingular(MPolynomial): return Sequence(l, check=False, immutable=True) def reduce(self,I): - """ + r""" Return a remainder of this polynomial modulo the polynomials in ``I``. @@ -5288,15 +5287,14 @@ cdef class MPolynomial_libsingular(MPolynomial): return new_MP(self._parent,p) def integral(self, MPolynomial_libsingular var): - """ - Integrates this polynomial with respect to the provided - variable. + r""" + Integrate this polynomial with respect to the provided variable. One requires that `\QQ` is contained in the ring. INPUT: - - ``variable`` - the integral is taken with respect to variable + - ``variable`` -- the integral is taken with respect to variable EXAMPLES:: diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pyx b/src/sage/rings/polynomial/ore_polynomial_element.pyx index d1492a35946..858ec02cbfa 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pyx +++ b/src/sage/rings/polynomial/ore_polynomial_element.pyx @@ -1705,11 +1705,11 @@ cdef class OrePolynomial(AlgebraElement): var = "|%s"%name else: var = "" - s += "%s %s"%(x,var) + s += "%s %s" % (x, var) s = s.replace(" + -", " - ") - s = re.sub(" 1(\.0+)? \|"," ", s) - s = re.sub(" -1(\.0+)? \|", " -", s) - s = s.replace("|","") + s = re.sub(r" 1(\.0+)? \|", " ", s) + s = re.sub(r" -1(\.0+)? \|", " -", s) + s = s.replace("|", "") if s == " ": return "0" return s[1:].lstrip().rstrip() diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 92e70f25343..9a996550975 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -250,10 +250,9 @@ cdef class NCPolynomialRing_plural(Ring): sage: H. = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y}) sage: x*y == y*x True - """ def __init__(self, base_ring, names, c, d, order, category, check=True): - """ + r""" Construct a noncommutative polynomial G-algebra subject to the following conditions: INPUT: diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 69cb4e8bded..cea15d34764 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -2749,9 +2749,9 @@ cdef class Polynomial(CommutativeAlgebraElement): var = "" s += "%s %s" % (x, var) s = s.replace(" + -", " - ") - s = re.sub(" 1(\.0+)? \|"," ", s) - s = re.sub(" -1(\.0+)? \|", " -", s) - s = s.replace("|","") + s = re.sub(r" 1(\.0+)? \|", " ", s) + s = re.sub(r" -1(\.0+)? \|", " -", s) + s = s.replace("|", "") if s == " ": return "0" return s[1:].lstrip().rstrip() @@ -2850,7 +2850,7 @@ cdef class Polynomial(CommutativeAlgebraElement): raise IndexError("polynomials are immutable") cpdef _floordiv_(self, right): - """ + r""" Quotient of division of self by other. This is denoted //. If self = quotient \* right + remainder, this function returns @@ -4959,9 +4959,10 @@ cdef class Polynomial(CommutativeAlgebraElement): return ~(q.leading_coefficient())*q # make monic (~ is inverse in python) def is_primitive(self, n=None, n_prime_divs=None): - """ - Return ``True`` if the polynomial is primitive. The semantics of - "primitive" depend on the polynomial coefficients. + r""" + Return ``True`` if the polynomial is primitive. + + The semantics of "primitive" depend on the polynomial coefficients. - (field theory) A polynomial of degree `m` over a finite field `\GF{q}` is primitive if it is irreducible and its root in diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index 3c90a42e033..284e319be99 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -100,14 +100,14 @@ cdef class Polynomial_GF2X(Polynomial_template): sage: pari(f) Mod(1, 2)*x^3 + Mod(1, 2)*x^2 + Mod(1, 2) """ - #TODO: put this in a superclass + # TODO: put this in a superclass parent = self._parent if variable is None: variable = parent.variable_name() return pari(self.list()).Polrev(variable) * pari(1).Mod(2) def modular_composition(Polynomial_GF2X self, Polynomial_GF2X g, Polynomial_GF2X h, algorithm=None): - """ + r""" Compute `f(g) \pmod h`. Both implementations use Brent-Kung's Algorithm 2.1 (*Fast Algorithms diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx index 38a8324fde1..bde23684615 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx @@ -4,7 +4,7 @@ # distutils: library_dirs = NTL_LIBDIR # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -""" +r""" Dense univariate polynomials over `\ZZ`, implemented using FLINT AUTHORS: @@ -1394,7 +1394,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): return smallInteger(fmpz_poly_degree(self.__poly)) def pseudo_divrem(self, B): - """ + r""" Write ``A = self``. This function computes polynomials `Q` and `R` and an integer `d` such that diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 643ef81027a..2b55a681a32 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -4,7 +4,7 @@ # distutils: library_dirs = NTL_LIBDIR # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -""" +r""" Dense univariate polynomials over `\ZZ/n\ZZ`, implemented using NTL This implementation is generally slower than the FLINT implementation in @@ -22,16 +22,15 @@ AUTHORS: - Robert Bradshaw: Split off from polynomial_element_generic.py (2007-09) - Robert Bradshaw: Major rewrite to use NTL directly (2007-09) """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.memory cimport sig_malloc, sig_free from cysignals.signals cimport sig_on, sig_off diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 001ace2194c..fd92a626555 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -4,7 +4,7 @@ # distutils: library_dirs = NTL_LIBDIR # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -""" +r""" Dense univariate polynomials over `\ZZ/n\ZZ`, implemented using FLINT This module gives a fast implementation of `(\ZZ/n\ZZ)[x]` whenever `n` is at diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index 1315d68c4a9..b939908ef92 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -1258,8 +1258,9 @@ def de_casteljau_intvec(Vector_integer_dense c, int c_bitsize, Rational x, int u # double-rounding on x86 PCs. cdef double half_ulp = ldexp(1.0 * 65/64, -54) + def intvec_to_doublevec(Vector_integer_dense b, long err): - """ + r""" Given a vector of integers A = [a1, ..., an], and an integer error bound E, returns a vector of floating-point numbers B = [b1, ..., bn], lower and upper error bounds F1 and F2, and @@ -2139,19 +2140,22 @@ cdef int subsample_vec(int a, int slen, int llen): sage: [subsample_vec_doctest(a, 3, 4) for a in range(3)] [1, 2, 3] """ - # round((a + 0.5) * (llen - 1) / slen) # round((2*a + 1) * (llen - 1) / (2 * slen) # floor(((2*a + 1) * (llen - 1) + slen) / (2 * slen)) return ((2*a + 1) * (llen - 1) + slen) // (2 * slen) + def subsample_vec_doctest(a, slen, llen): return subsample_vec(a, slen, llen) + def maximum_root_first_lambda(p): - """ + r""" Given a polynomial with real coefficients, computes an upper bound - on its largest real root, using the first-\lambda algorithm from + on its largest real root. + + This is using the first-\lambda algorithm from "Implementations of a New Theorem for Computing Bounds for Positive Roots of Polynomials", by Akritas, Strzebo\'nski, and Vigklas. diff --git a/src/sage/rings/polynomial/symmetric_reduction.pyx b/src/sage/rings/polynomial/symmetric_reduction.pyx index c8c08e1c61f..25213e1318a 100644 --- a/src/sage/rings/polynomial/symmetric_reduction.pyx +++ b/src/sage/rings/polynomial/symmetric_reduction.pyx @@ -1,4 +1,4 @@ -""" +r""" Symmetric Reduction of Infinite Polynomials :class:`~sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy` @@ -102,7 +102,7 @@ Symmetric Reduction Strategy is created:: """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Simon King # # Distributed under the terms of the GNU General Public License (GPL) @@ -114,9 +114,8 @@ Symmetric Reduction Strategy is created:: # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** import copy import operator import sys From aaefd0aa8ee09d4632e304b7a0453e2acc15a0df Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Tue, 30 Aug 2022 20:45:10 +0200 Subject: [PATCH 277/350] Fix tests with ipywidgets 8 --- .../cluster_algebra_quiver/cluster_seed.py | 2 +- .../cluster_algebra_quiver/interact.py | 4 +- .../combinat/cluster_algebra_quiver/quiver.py | 2 +- .../dynamics/complex_dynamics/mandel_julia.py | 8 ++-- src/sage/interacts/library.py | 46 +++++++++---------- src/sage/plot/plot3d/plot3d.py | 4 +- src/sage/repl/display/formatter.py | 3 +- src/sage/repl/ipython_kernel/interact.py | 46 +++++++++---------- .../repl/ipython_kernel/widgets_sagenb.py | 9 ---- 9 files changed, 57 insertions(+), 67 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index e65d605fad1..d7c4d849e0c 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -1062,7 +1062,7 @@ def interact(self, fig_size=1, circular=True): sage: S = ClusterSeed(['A',4]) sage: S.interact() - VBox(children=... + ...VBox(children=... """ return cluster_interact(self, fig_size, circular, kind='seed') diff --git a/src/sage/combinat/cluster_algebra_quiver/interact.py b/src/sage/combinat/cluster_algebra_quiver/interact.py index 4e54c64e179..1c88e613b4c 100644 --- a/src/sage/combinat/cluster_algebra_quiver/interact.py +++ b/src/sage/combinat/cluster_algebra_quiver/interact.py @@ -27,7 +27,7 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'): sage: S = ClusterSeed(['A',4]) sage: S.interact() # indirect doctest - VBox(children=... + ...VBox(children=... """ if kind not in ['seed', 'quiver']: raise ValueError('kind must be "seed" or "quiver"') @@ -107,7 +107,7 @@ def do_mutation(*args, **kwds): show_lastmutation.observe(refresh, 'value') which_plot.observe(refresh, 'value') - mut_buttons.on_displayed(refresh) + mut_buttons.on_widget_constructed(refresh) if kind == 'seed': top = widgets.HBox([show_seq, show_vars]) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index 4f6e16bf0fe..14a176c479a 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -699,7 +699,7 @@ def interact(self, fig_size=1, circular=True): sage: S = ClusterQuiver(['A',4]) sage: S.interact() - VBox(children=... + ...VBox(children=... """ return cluster_interact(self, fig_size, circular, kind="quiver") diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index 224a484c7bb..ce67274c293 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -130,7 +130,7 @@ def mandelbrot_plot(f=None, **kwds): ``interact`` to ``True``. (This is only implemented for ``z^2 + c``):: sage: mandelbrot_plot(interact=True) - interactive(children=(FloatSlider(value=0.0, description='Real center', max=1.0, min=-1.0, step=1e-05), + ...interactive(children=(FloatSlider(value=0.0, description='Real center', max=1.0, min=-1.0, step=1e-05), FloatSlider(value=0.0, description='Imag center', max=1.0, min=-1.0, step=1e-05), FloatSlider(value=4.0, description='Width', max=4.0, min=1e-05, step=1e-05), IntSlider(value=500, description='Iterations', max=1000), @@ -144,7 +144,7 @@ def mandelbrot_plot(f=None, **kwds): sage: mandelbrot_plot(interact=True, x_center=-0.75, y_center=0.25, ....: image_width=1/2, number_of_colors=75) - interactive(children=(FloatSlider(value=-0.75, description='Real center', max=1.0, min=-1.0, step=1e-05), + ...interactive(children=(FloatSlider(value=-0.75, description='Real center', max=1.0, min=-1.0, step=1e-05), FloatSlider(value=0.25, description='Imag center', max=1.0, min=-1.0, step=1e-05), FloatSlider(value=0.5, description='Width', max=4.0, min=1e-05, step=1e-05), IntSlider(value=500, description='Iterations', max=1000), @@ -600,14 +600,14 @@ def julia_plot(f=None, **kwds): the form ``f = z^2 + c``):: sage: julia_plot(interact=True) - interactive(children=(FloatSlider(value=-1.0, description='Real c'... + ...interactive(children=(FloatSlider(value=-1.0, description='Real c'... :: sage: R. = CC[] sage: f = z^2 + 1/2 sage: julia_plot(f,interact=True) - interactive(children=(FloatSlider(value=0.5, description='Real c'... + ...interactive(children=(FloatSlider(value=0.5, description='Real c'... To return the Julia set of a random `c` value with (formal) cycle structure `(2,3)`, set ``period = [2,3]``:: diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 06d680109a0..bb6dfbcf8f4 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -12,7 +12,7 @@ HTML and Sage code which creates the mathlet:: sage: interacts.calculus.taylor_polynomial() - Interactive function with 3 widgets + ...Interactive function with 3 widgets title: HTMLText(value='

Taylor polynomial

') f: EvalText(value='e^(-x)*sin(x)', description='$f(x)=$', layout=Layout(max_width='81em')) order: SelectionSlider(description='order', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), value=1) @@ -101,7 +101,7 @@ def library_interact( ....: def f(n): ....: print(n) sage: f() # an interact appears if using the notebook, else code - Interactive function with 1 widget + ...Interactive function with 1 widget n: TransformIntSlider(value=5, description='n', max=15, min=-5) TESTS: @@ -117,7 +117,7 @@ def library_interact( DeprecationWarning: Use decorator factory @library_interact(widgets) instead of @library_interact without any arguments. See https://trac.sagemath.org/33382 for details. sage: f() # an interact appears if using the notebook, else code - Interactive function with 1 widget + ...Interactive function with 1 widget n: TransformIntSlider(value=5, description='n', max=15, min=-5) .. NOTE:: @@ -183,7 +183,7 @@ def demo(n: int, m: int): creates the mathlet:: sage: interacts.demo() - Interactive function with 2 widgets + ...Interactive function with 2 widgets n: SelectionSlider(description='n', options=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), value=0) m: SelectionSlider(description='m', options=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), value=0) """ @@ -213,7 +213,7 @@ def taylor_polynomial(title, f, order: int): creates the mathlet:: sage: interacts.calculus.taylor_polynomial() - Interactive function with 3 widgets + ...Interactive function with 3 widgets title: HTMLText(value='

Taylor polynomial

') f: EvalText(value='e^(-x)*sin(x)', description='$f(x)=$', layout=Layout(max_width='81em')) order: SelectionSlider(description='order', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), value=1) @@ -259,7 +259,7 @@ def definite_integral(title, f, g, interval, x_range, selection): creates the mathlet:: sage: interacts.calculus.definite_integral() - Interactive function with 6 widgets + ...Interactive function with 6 widgets title: HTMLText(value='

Definite integral

') f: EvalText(value='3*x', description='$f(x)=$', layout=Layout(max_width='81em')) g: EvalText(value='x^2', description='$g(x)=$', layout=Layout(max_width='81em')) @@ -345,7 +345,7 @@ def function_derivative(title, function, x_range, y_range): creates the mathlet:: sage: interacts.calculus.function_derivative() - Interactive function with 4 widgets + ...Interactive function with 4 widgets title: HTMLText(value='

Derivative grapher

') function: EvalText(value='x^5-3*x^3+1', description='Function:', layout=Layout(max_width='81em')) x_range: FloatRangeSlider(value=(-2.0, 2.0), description='Range (x)', max=15.0, min=-15.0) @@ -393,7 +393,7 @@ def difference_quotient(title, f, interval, a, x0): creates the mathlet:: sage: interacts.calculus.difference_quotient() - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Difference quotient

') f: EvalText(value='sin(x)', description='f(x)', layout=Layout(max_width='81em')) interval: FloatRangeSlider(value=(0.0, 10.0), description='Range', max=10.0) @@ -458,7 +458,7 @@ def quadratic_equation(A, B, C): creates the mathlet:: sage: interacts.calculus.quadratic_equation() - Interactive function with 3 widgets + ...Interactive function with 3 widgets A: IntSlider(value=1, description='A', max=7, min=-7) B: IntSlider(value=1, description='B', max=7, min=-7) C: IntSlider(value=-2, description='C', max=7, min=-7) @@ -520,7 +520,7 @@ def trigonometric_properties_triangle(a0, a1, a2): creates the mathlet:: sage: interacts.geometry.trigonometric_properties_triangle() - Interactive function with 3 widgets + ...Interactive function with 3 widgets a0: IntSlider(value=30, description='A', max=360) a1: IntSlider(value=180, description='B', max=360) a2: IntSlider(value=300, description='C', max=360) @@ -601,7 +601,7 @@ def unit_circle(function, x): creates the mathlet:: sage: interacts.geometry.unit_circle() - Interactive function with 2 widgets + ...Interactive function with 2 widgets function: Dropdown(description='function', options=(('sin(x)', 0), ('cos(x)', 1), ('tan(x)', 2)), value=0) x: TransformFloatSlider(value=0.0, description='x', max=6.283185307179586, step=0.015707963267948967) """ @@ -702,7 +702,7 @@ def special_points( creates the mathlet:: sage: interacts.geometry.special_points() - Interactive function with 10 widgets + ...Interactive function with 10 widgets title: HTMLText(value='

Special points in triangle

') a0: IntSlider(value=30, description='A', max=360) a1: IntSlider(value=180, description='B', max=360) @@ -875,7 +875,7 @@ def coin(n, interval): creates the mathlet:: sage: interacts.statistics.coin() - Interactive function with 2 widgets + ...Interactive function with 2 widgets n: IntSlider(value=1000, description='Number of Tosses', max=10000, min=2, step=100) interval: IntRangeSlider(value=(0, 0), description='Plotting range (y)', max=1) """ @@ -915,7 +915,7 @@ def bisection_method(title, f, interval, d, maxn): creates the mathlet:: sage: interacts.calculus.secant_method() - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Secant method for numerical root finding

') f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em')) interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5) @@ -995,7 +995,7 @@ def secant_method(title, f, interval, d, maxn): creates the mathlet:: sage: interacts.calculus.secant_method() - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Secant method for numerical root finding

') f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em')) interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5) @@ -1068,7 +1068,7 @@ def newton_method(title, f, c, d, maxn, interval, list_steps): creates the mathlet:: sage: interacts.calculus.newton_method() - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Newton method

') f: EvalText(value='x^2 - 2', description='f', layout=Layout(max_width='81em')) c: IntSlider(value=6, description='Start ($x$)', max=10, min=-10) @@ -1152,7 +1152,7 @@ def trapezoid_integration( creates the mathlet:: sage: interacts.calculus.trapezoid_integration() - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Trapezoid integration

') f: EvalText(value='x^2-5*x + 10', description='$f(x)=$', layout=Layout(max_width='81em')) n: IntSlider(value=5, description='# divisions', min=1) @@ -1285,7 +1285,7 @@ def simpson_integration( creates the mathlet:: sage: interacts.calculus.simpson_integration() - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Simpson integration

') f: EvalText(value='x*sin(x)+x+1', description='$f(x)=$', layout=Layout(max_width='81em')) n: IntSlider(value=6, description='# divisions', min=2, step=2) @@ -1549,7 +1549,7 @@ def function_tool(f, g, xrange, yrange, a, action, do_plot): creates the mathlet:: sage: interacts.calculus.function_tool() - Interactive function with 7 widgets + ...Interactive function with 7 widgets f: EvalText(value='sin(x)', description='f') g: EvalText(value='cos(x)', description='g') xrange: IntRangeSlider(value=(0, 1), description='x-range', max=3, min=-3) @@ -1679,7 +1679,7 @@ def julia(expo, c_real, c_imag, iterations, zoom_x, zoom_y, plot_points, dpi): creates the mathlet:: sage: interacts.fractals.julia() - Interactive function with 8 widgets + ...Interactive function with 8 widgets expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0) c_real: FloatSlider(value=0.5, description='real part const.', max=2.0, min=-2.0, step=0.01) c_imag: FloatSlider(value=0.5, description='imag part const.', max=2.0, min=-2.0, step=0.01) @@ -1731,7 +1731,7 @@ def mandelbrot(expo, iterations, zoom_x, zoom_y, plot_points, dpi): creates the mathlet:: sage: interacts.fractals.mandelbrot() - Interactive function with 6 widgets + ...Interactive function with 6 widgets expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0) iterations: IntSlider(value=20, description='# iterations', min=1) zoom_x: FloatRangeSlider(value=(-2.0, 1.0), description='Zoom X', max=2.0, min=-2.0, step=0.01) @@ -1776,7 +1776,7 @@ def cellular_automaton(N, rule_number, size): creates the mathlet:: sage: interacts.fractals.cellular_automaton() - Interactive function with 3 widgets + ...Interactive function with 3 widgets N: IntSlider(value=100, description='Number of iterations', max=500, min=1) rule_number: IntSlider(value=110, description='Rule number', max=255) size: IntSlider(value=6, description='size of graphic', max=11, min=1) @@ -1835,7 +1835,7 @@ def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, creates the mathlet:: sage: sage.interacts.algebra.polar_prime_spiral() - Interactive function with 6 widgets + ...Interactive function with 6 widgets interval: IntRangeSlider(value=(1, 1000), description='range', max=4000, min=1, step=10) show_factors: Checkbox(value=True, description='show_factors') highlight_primes: Checkbox(value=True, description='highlight_primes') diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index a2bddd8a3a0..64b11a0442a 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -1300,7 +1300,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): sage: @interact ....: def _(which_plot=[A,B,C,D,E]): ....: show(which_plot) - Interactive function with 1 widget + ...Interactive function with 1 widget which_plot: Dropdown(description='which_plot', options=(Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object), value=Graphics3d Object) Now plot a function:: @@ -1314,7 +1314,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds): sage: @interact ....: def _(which_plot=[F, G, H, I, J]): ....: show(which_plot) - Interactive function with 1 widget + ...Interactive function with 1 widget which_plot: Dropdown(description='which_plot', options=(Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object), value=Graphics3d Object) TESTS: diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py index 2910fb8ee19..488f0bf2791 100644 --- a/src/sage/repl/display/formatter.py +++ b/src/sage/repl/display/formatter.py @@ -169,8 +169,7 @@ def format(self, obj, include=None, exclude=None): sage: shell.run_cell('import ipywidgets') sage: shell.run_cell('slider = ipywidgets.IntSlider()') sage: shell.run_cell('get_ipython().display_formatter.format(slider)') - IntSlider(value=0) - ({}, {}) + ...IntSlider(value=0)..., {}) sage: shell.run_cell('%display default') sage: shell.quit() diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 4a6960ece3a..4f96a212ab7 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -18,7 +18,7 @@ sage: @interact ....: def f(x=(0, 10)): ....: pass - Interactive function with 1 widget + ...Interactive function with 1 widget x: IntSlider(value=5, description='x', max=10) sage: f.widget.children (IntSlider(value=5, description='x', max=10), Output()) @@ -69,7 +69,7 @@ class sage_interactive(interactive): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(x=10, y="hello", z=None): pass sage: sage_interactive(myfunc, x=(0,100), z=["one", "two", "three"]) - Interactive function with 3 widgets + ...Interactive function with 3 widgets x: IntSlider(value=10, description='x') y: Text(value='hello', description='y') z: Dropdown(description='z', options=('one', 'two', 'three'), value=None) @@ -99,10 +99,10 @@ def __init__(self, *args, **kwds): sage: def myfunc(auto_update=False): pass sage: sage_interactive(myfunc) - Manual interactive function with 0 widgets + ...Manual interactive function with 0 widgets sage: def myfunc(auto_update=None): pass sage: sage_interactive(myfunc) - Interactive function with 0 widgets + ...Interactive function with 0 widgets """ # Use *args to avoid name clash with keyword arguments if len(args) < 2: @@ -126,7 +126,7 @@ def __init__(self, *args, **kwds): super().__init__(f, options, **kwds) if self.manual: # In Sage, manual interacts are always run once - self.on_displayed(self.update) + self.on_widget_constructed(self.update) else: # In automatic mode, clicking on a ToggleButtons button # should also run the interact @@ -143,7 +143,7 @@ def __repr__(self): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(): pass sage: sage_interactive(myfunc) - Interactive function with 0 widgets + ...Interactive function with 0 widgets """ s = "Manual interactive" if self.manual else "Interactive" widgets = [w for w in self.children if isinstance(w, ValueWidget)] @@ -164,7 +164,7 @@ def signature(self): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(x=[1,2,3], auto_update=False): pass sage: sage_interactive(myfunc).signature().parameters - mappingproxy({'x': }) + ...mappingproxy({'x': }) """ return self.__signature @@ -181,14 +181,14 @@ def widget_from_single_value(cls, abbrev, *args, **kwds): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_single_value("sin(x)") - Text(value='sin(x)') + ...Text(value='sin(x)') sage: sage_interactive.widget_from_single_value(sin(x)) - EvalText(value='sin(x)') + ...EvalText(value='sin(x)') sage: from sage.plot.colors import Color sage: sage_interactive.widget_from_single_value(matrix([[1, 2], [3, 4]])) - Grid(value=[[1, 2], [3, 4]], children=(Label(value=''), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='2', layout=Layout(max_width='5em')), EvalText(value='4', layout=Layout(max_width='5em')))))) + ...Grid(value=[[1, 2], [3, 4]], children=(Label(value=''), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='2', layout=Layout(max_width='5em')), EvalText(value='4', layout=Layout(max_width='5em')))))) sage: sage_interactive.widget_from_single_value(Color('cornflowerblue')) - SageColorPicker(value='#6495ed') + ...SageColorPicker(value='#6495ed') """ # Support Sage matrices and colors if isinstance(abbrev, Matrix): @@ -219,15 +219,15 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_tuple( (0, 10) ) - IntSlider(value=5, max=10) + ...IntSlider(value=5, max=10) sage: sage_interactive.widget_from_tuple( ("number", (0, 10)) ) - IntSlider(value=5, description='number', max=10) + ...IntSlider(value=5, description='number', max=10) sage: sage_interactive.widget_from_tuple( (3, (0, 10)) ) - IntSlider(value=3, max=10) - sage: sage_interactive.widget_from_tuple((2, dict(one=1, two=2, three=3))) - Dropdown(index=1, options={'one': 1, 'two': 2, 'three': 3}, value=2) + ...IntSlider(value=3, max=10) + sage: sage_interactive.widget_from_tuple((2, [('one', 1), ('two', 2), ('three', 3)])) + ...Dropdown(index=1, options=(('one', 1), ('two', 2), ('three', 3)), value=2) sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) - FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) + ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) TESTS: @@ -235,7 +235,7 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): sage: SCR = SR.subring(no_variables=True) sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) ) - FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) + ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) """ # Support (description, abbrev) if len(abbrev) == 2 and isinstance(abbrev[0], str): @@ -269,17 +269,17 @@ def widget_from_iterable(cls, abbrev, *args, **kwds): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_iterable([1..5]) - Dropdown(options=(1, 2, 3, 4, 5), value=1) + ...Dropdown(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable(iter([1..5])) - SelectionSlider(options=(1, 2, 3, 4, 5), value=1) + ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable((1..5)) - SelectionSlider(options=(1, 2, 3, 4, 5), value=1) + ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: sage_interactive.widget_from_iterable(x for x in [1..5]) - SelectionSlider(options=(1, 2, 3, 4, 5), value=1) + ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1) sage: def gen(): ....: yield 1; yield 2; yield 3; yield 4; yield 5 sage: sage_interactive.widget_from_iterable(gen()) - SelectionSlider(options=(1, 2, 3, 4, 5), value=1) + ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1) """ if isinstance(abbrev, Iterator): return SelectionSlider(options=list(abbrev)) diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 2ce59d79a3b..76f4f52ac4a 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -470,15 +470,6 @@ def selector(values, label=None, default=None, nrows=None, ncols=None, width=Non sage: selector([(1,"one"), (2,"two"), (3,"three")], buttons=True) ToggleButtons(options=(('one', 1), ('two', 2), ('three', 3)), value=1) - A dict of ``label:value`` pairs is also allowed. Since a ``dict`` - is not ordered, it is better to use an :class:`OrderedDict`:: - - sage: from collections import OrderedDict - sage: selector(OrderedDict(one=1, two=2, three=3)) - Dropdown(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1) - sage: selector(OrderedDict(one=1, two=2, three=3), buttons=True) - ToggleButtons(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1) - The values can be any kind of object: sage: selector([sin(x^2), GF(29), EllipticCurve('37a1')]) From f4e415bd2894950eee8c4c73a90af08a2ad9dc8b Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 24 Sep 2022 10:21:44 +0200 Subject: [PATCH 278/350] Fix tests in sage.interacts.test_jupyter.rst --- src/sage/interacts/test_jupyter.rst | 43 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/sage/interacts/test_jupyter.rst b/src/sage/interacts/test_jupyter.rst index 0228ea227c1..3335a7423c3 100644 --- a/src/sage/interacts/test_jupyter.rst +++ b/src/sage/interacts/test_jupyter.rst @@ -40,7 +40,7 @@ This is just to test that failures in the interact are actually seen:: Test all interacts from the Sage interact library:: sage: test(interacts.algebra.polar_prime_spiral) # long time - Interactive function with 6 widgets + ...Interactive function with 6 widgets interval: IntRangeSlider(value=(1, 1000), description='range', max=4000, min=1, step=10) show_factors: Checkbox(value=True, description='show_factors') highlight_primes: Checkbox(value=True, description='highlight_primes') @@ -53,7 +53,7 @@ Test all interacts from the Sage interact library:: Green Curve: \(n^2 + n + -1\) sage: test(interacts.calculus.taylor_polynomial) - Interactive function with 3 widgets + ...Interactive function with 3 widgets title: HTMLText(value='

Taylor polynomial

') f: EvalText(value='e^(-x)*sin(x)', description='$f(x)=$', layout=Layout(max_width='81em')) order: SelectionSlider(description='order', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), value=1) @@ -61,7 +61,7 @@ Test all interacts from the Sage interact library:: \(\hat{f}(x;0)\;=\;x+\mathcal{O}(x^{2})\) sage: test(interacts.calculus.definite_integral) - Interactive function with 6 widgets + ...Interactive function with 6 widgets title: HTMLText(value='

Definite integral

') f: EvalText(value='3*x', description='$f(x)=$', layout=Layout(max_width='81em')) g: EvalText(value='x^2', description='$g(x)=$', layout=Layout(max_width='81em')) @@ -71,7 +71,7 @@ Test all interacts from the Sage interact library:: \(\int_{0.00}^{3.00}(\color{Blue}{f(x)})\,\mathrm{d}x=\int_{0.00}^{3.00}(3 \, x)\,\mathrm{d}x=13.50\)
\(\int_{0.00}^{3.00}(\color{Green}{g(x)})\,\mathrm{d}x=\int_{0.00}^{3.00}(x^{2})\,\mathrm{d}x=9.00\) sage: test(interacts.calculus.function_derivative) - Interactive function with 4 widgets + ...Interactive function with 4 widgets title: HTMLText(value='

Derivative grapher

') function: EvalText(value='x^5-3*x^3+1', description='Function:', layout=Layout(max_width='81em')) x_range: FloatRangeSlider(value=(-2.0, 2.0), description='Range (x)', max=15.0, min=-15.0) @@ -81,7 +81,7 @@ Test all interacts from the Sage interact library::
\(\color{Red}{f''(x) = 20 \, x^{3} - 18 \, x}\)
sage: test(interacts.calculus.difference_quotient) - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Difference quotient

') f: EvalText(value='sin(x)', description='f(x)', layout=Layout(max_width='81em')) interval: FloatRangeSlider(value=(0.0, 10.0), description='Range', max=10.0) @@ -96,7 +96,7 @@ Test all interacts from the Sage interact library:: \(k = \frac{f(x_0)-f(a)}{x_0-a} = -0.62274\)
sage: test(interacts.calculus.quadratic_equation) - Interactive function with 3 widgets + ...Interactive function with 3 widgets A: IntSlider(value=1, description='A', max=7, min=-7) B: IntSlider(value=1, description='B', max=7, min=-7) C: IntSlider(value=-2, description='C', max=7, min=-7) @@ -106,7 +106,7 @@ Test all interacts from the Sage interact library:: \(x = \frac{-B\pm\sqrt{B^2-4AC}}{2A} = \frac{-1\pm\sqrt{1^2-4*1*-2}}{2*1} = \frac{-1\pm\sqrt{\color{Green}{9}}}{2} = \begin{cases}1\\-2\end{cases}\) sage: test(interacts.calculus.secant_method) - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Secant method for numerical root finding

') f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em')) interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5) @@ -118,7 +118,7 @@ Test all interacts from the Sage interact library:: \(6 \text{ iterations}\) sage: test(interacts.calculus.newton_method) - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Newton method

') f: EvalText(value='x^2 - 2', description='f', layout=Layout(max_width='81em')) c: IntSlider(value=6, description='Start ($x$)', max=10, min=-10) @@ -132,7 +132,7 @@ Test all interacts from the Sage interact library:: \(6 \text{ iterations}\) sage: test(interacts.calculus.trapezoid_integration) - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Trapezoid integration

') f: EvalText(value='x^2-5*x + 10', description='$f(x)=$', layout=Layout(max_width='81em')) n: IntSlider(value=5, description='# divisions', min=1) @@ -155,7 +155,7 @@ Test all interacts from the Sage interact library:: sage: test(interacts.calculus.simpson_integration) - Interactive function with 7 widgets + ...Interactive function with 7 widgets title: HTMLText(value='

Simpson integration

') f: EvalText(value='x*sin(x)+x+1', description='$f(x)=$', layout=Layout(max_width='81em')) n: IntSlider(value=6, description='# divisions', min=2, step=2) @@ -178,7 +178,7 @@ Test all interacts from the Sage interact library:: sage: test(interacts.calculus.bisection_method) - Interactive function with 5 widgets + ...Interactive function with 5 widgets title: HTMLText(value='

Bisection method

') f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em')) interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5) @@ -190,7 +190,7 @@ Test all interacts from the Sage interact library:: \(9 \text{ iterations}\) sage: test(interacts.calculus.riemann_sum) - Manual interactive function with 9 widgets + ...Manual interactive function with 9 widgets title: HTMLText(value='

Riemann integral with random sampling

') f: EvalText(value='x^2+1', description='$f(x)=$', layout=Layout(max_width='41em')) n: IntSlider(value=5, description='# divisions', max=30, min=1) @@ -206,7 +206,7 @@ Test all interacts from the Sage interact library:: 1\,\mathrm{d}x=4.666666666666668\) sage: test(interacts.calculus.function_tool) - Interactive function with 7 widgets + ...Interactive function with 7 widgets f: EvalText(value='sin(x)', description='f') g: EvalText(value='cos(x)', description='g') xrange: IntRangeSlider(value=(0, 1), description='x-range', max=3, min=-3) @@ -219,7 +219,7 @@ Test all interacts from the Sage interact library::
\(h = f = \sin\left(x\right)\)
sage: test(interacts.fractals.mandelbrot) - Interactive function with 6 widgets + ...Interactive function with 6 widgets expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0) iterations: IntSlider(value=20, description='# iterations', min=1) zoom_x: FloatRangeSlider(value=(-2.0, 1.0), description='Zoom X', max=2.0, min=-2.0, step=0.01) @@ -230,7 +230,7 @@ Test all interacts from the Sage interact library:: Recursive Formula: \(z \leftarrow z^{2.00} + c\) for \(c \in \mathbb{C}\) sage: test(interacts.fractals.julia) - Interactive function with 8 widgets + ...Interactive function with 8 widgets expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0) c_real: FloatSlider(value=0.5, description='real part const.', max=2.0, min=-2.0, step=0.01) c_imag: FloatSlider(value=0.5, description='imag part const.', max=2.0, min=-2.0, step=0.01) @@ -243,20 +243,20 @@ Test all interacts from the Sage interact library:: Recursive Formula: \(z \leftarrow z^{2.00} + (0.50+0.50*\mathbb{I})\) sage: test(interacts.fractals.cellular_automaton) - Interactive function with 3 widgets + ...Interactive function with 3 widgets N: IntSlider(value=100, description='Number of iterations', max=500, min=1) rule_number: IntSlider(value=110, description='Rule number', max=255) size: IntSlider(value=6, description='size of graphic', max=11, min=1)

Cellular Automaton

Rule 110 expands to 01110110
sage: test(interacts.geometry.unit_circle) - Interactive function with 2 widgets + ...Interactive function with 2 widgets function: Dropdown(description='function', options=(('sin(x)', 0), ('cos(x)', 1), ('tan(x)', 2)), value=0) x: TransformFloatSlider(value=0.0, description='x', max=6.283185307179586, step=0.015707963267948967)
Lines of the same color have the same length
sage: test(interacts.geometry.trigonometric_properties_triangle) - Interactive function with 3 widgets + ...Interactive function with 3 widgets a0: IntSlider(value=30, description='A', max=360) a1: IntSlider(value=180, description='B', max=360) a2: IntSlider(value=300, description='C', max=360) @@ -266,7 +266,7 @@ Test all interacts from the Sage interact library:: Area of triangle \(ABC = 1.183013\) sage: test(interacts.geometry.special_points) - Interactive function with 10 widgets + ...Interactive function with 10 widgets title: HTMLText(value='

Special points in triangle

') a0: IntSlider(value=30, description='A', max=360) a1: IntSlider(value=180, description='B', max=360) @@ -279,10 +279,9 @@ Test all interacts from the Sage interact library:: show_euler: Checkbox(value=False, description="Euler's Line") sage: test(interacts.statistics.coin) - Interactive function with 2 widgets + ...Interactive function with 2 widgets n: IntSlider(value=1000, description='Number of Tosses', max=10000, min=2, step=100) interval: IntRangeSlider(value=(0, 0), description='Plotting range (y)', max=1) - doctest:...: UserWarning: Attempting to set identical bottom == top == 0.0 results in singular transformations; automatically expanding. Test matrix control (see :trac:`27735`):: @@ -291,7 +290,7 @@ Test matrix control (see :trac:`27735`):: ....: print(A) ....: print(parent(A)) sage: test(matrix_test) - Interactive function with 1 widget + ...Interactive function with 1 widget A: Grid(value=[[0, 1], [2, 3]], children=(Label(value='A'), VBox(children=(EvalText(value='0', layout=Layout(max_width='5em')), EvalText(value='2', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))))) [0 1] [2 3] From 8b8930b6d7dcde5cde7ade56472b84cecc450731 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 24 Sep 2022 11:07:33 +0200 Subject: [PATCH 279/350] Update ipywidgets and widgetsnbextension --- build/pkgs/ipywidgets/checksums.ini | 6 +++--- build/pkgs/ipywidgets/package-version.txt | 2 +- build/pkgs/widgetsnbextension/checksums.ini | 6 +++--- build/pkgs/widgetsnbextension/package-version.txt | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index e250f8111d0..63a890dcf81 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,5 +1,5 @@ tarball=ipywidgets-VERSION.tar.gz -sha1=db842df5008a1786ab6434875c2d56b974c5109a -md5=61deb9024c3de1848812b97c2560d0cf -cksum=3129459111 +sha1=b2c8adf4fefc012adfb61e03a2e957bddbbb7597 +md5=c976de164b782eac9e5dfc933e8da295 +cksum=305610881 upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/package-version.txt b/build/pkgs/ipywidgets/package-version.txt index 1985849fb58..8b22a322d0f 100644 --- a/build/pkgs/ipywidgets/package-version.txt +++ b/build/pkgs/ipywidgets/package-version.txt @@ -1 +1 @@ -7.7.0 +8.0.2 diff --git a/build/pkgs/widgetsnbextension/checksums.ini b/build/pkgs/widgetsnbextension/checksums.ini index 520bd3a6401..2b335f09484 100644 --- a/build/pkgs/widgetsnbextension/checksums.ini +++ b/build/pkgs/widgetsnbextension/checksums.ini @@ -1,5 +1,5 @@ tarball=widgetsnbextension-VERSION.tar.gz -sha1=0dddc23af2ec56d3a666bba070da1518312d1163 -md5=86dd0471c4e376d981d7633224aa0607 -cksum=3308939542 +sha1=21f8dc7732adad09921bf590fa0eb0d4c3dd7f48 +md5=2d44896382b3a587823e08df6d2f3165 +cksum=209268639 upstream_url=https://pypi.io/packages/source/w/widgetsnbextension/widgetsnbextension-VERSION.tar.gz diff --git a/build/pkgs/widgetsnbextension/package-version.txt b/build/pkgs/widgetsnbextension/package-version.txt index 9575d51bad2..c4e41f94594 100644 --- a/build/pkgs/widgetsnbextension/package-version.txt +++ b/build/pkgs/widgetsnbextension/package-version.txt @@ -1 +1 @@ -3.6.1 +4.0.3 From 86949b3cadcd2df6df942948cd27d7948250b0ad Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 25 Sep 2022 08:38:26 +0200 Subject: [PATCH 280/350] Drop obsolete patch --- .../patches/no-notebook-dep.patch | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 build/pkgs/widgetsnbextension/patches/no-notebook-dep.patch diff --git a/build/pkgs/widgetsnbextension/patches/no-notebook-dep.patch b/build/pkgs/widgetsnbextension/patches/no-notebook-dep.patch deleted file mode 100644 index 976091637f5..00000000000 --- a/build/pkgs/widgetsnbextension/patches/no-notebook-dep.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 55bc3c93bf4310d4f4d9d02f2e51d1d65b7f6533 (HEAD -> 7.6.3-sage) -Author: Sylvain Corlay -Date: Mon Oct 21 01:33:23 2019 +0200 - - Drop notebook dependency from widgetsnbextension - -diff --git a/widgetsnbextension/setup.py b/widgetsnbextension/setup.py -index 866d82eb..88746f95 100644 ---- a/setup.py -+++ b/setup.py -@@ -219,13 +219,5 @@ if 'setuptools' in sys.modules: - from setuptools.command.develop import develop - setup_args['cmdclass']['develop'] = js_prerelease(develop, strict=True) - --setuptools_args = {} --install_requires = setuptools_args['install_requires'] = [ -- 'notebook>=4.4.1', --] -- --if 'setuptools' in sys.modules: -- setup_args.update(setuptools_args) -- - if __name__ == '__main__': - setup(**setup_args) From d6a2f56dd2d944a3b29b6d399cbf43516b6f6d1e Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 25 Sep 2022 08:59:52 +0200 Subject: [PATCH 281/350] Update dependencies --- ...install-requires-of-jupyterlab_widge.patch | 35 ------------------- build/pkgs/widgetsnbextension/dependencies | 2 +- 2 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 build/pkgs/ipywidgets/patches/0001-setup.py-Remove-install-requires-of-jupyterlab_widge.patch diff --git a/build/pkgs/ipywidgets/patches/0001-setup.py-Remove-install-requires-of-jupyterlab_widge.patch b/build/pkgs/ipywidgets/patches/0001-setup.py-Remove-install-requires-of-jupyterlab_widge.patch deleted file mode 100644 index fed30e5445e..00000000000 --- a/build/pkgs/ipywidgets/patches/0001-setup.py-Remove-install-requires-of-jupyterlab_widge.patch +++ /dev/null @@ -1,35 +0,0 @@ -From e64096431a7099f8db46748ef7d1021939f1a624 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Wed, 24 Mar 2021 12:59:13 -0700 -Subject: [PATCH] setup.py: Remove install-requires of jupyterlab_widgets, - nbformat - ---- - setup.py | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/setup.py b/setup.py -index e544267a..bff154af 100644 ---- a/setup.py -+++ b/setup.py -@@ -112,9 +112,6 @@ setuptools_args = {} - install_requires = setuptools_args['install_requires'] = [ - 'ipykernel>=4.5.1', - 'traitlets>=4.3.1', -- # Requiring nbformat to specify bugfix version which is not required by -- # notebook. -- 'nbformat>=4.2.0', - # TODO: Dynamically add this dependency - # only if notebook 4.x is installed in this - # interpreter, to allow ipywidgets to be -@@ -125,7 +122,6 @@ install_requires = setuptools_args['install_requires'] = [ - extras_require = setuptools_args['extras_require'] = { - ':python_version<"3.3"' : ['ipython>=4.0.0,<6.0.0'], - ':python_version>="3.3"': ['ipython>=4.0.0'], -- ':python_version>="3.6"': ['jupyterlab_widgets>=1.0.0'], - 'test:python_version=="2.7"': ['mock'], - 'test': ['pytest>=3.6.0', 'pytest-cov'], - } --- -2.28.0 - diff --git a/build/pkgs/widgetsnbextension/dependencies b/build/pkgs/widgetsnbextension/dependencies index dd63a9f4ef1..f7ff1dca568 100644 --- a/build/pkgs/widgetsnbextension/dependencies +++ b/build/pkgs/widgetsnbextension/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) jupyter_core +$(PYTHON) jupyter_packaging | $(PYTHON_TOOLCHAIN) jupyter_core ---------- All lines of this file are ignored except the first. From 3c7b7b4a54874c85c4eeb28d21345cc764e6c0b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 9 Oct 2022 12:15:03 -0700 Subject: [PATCH 282/350] build/pkgs/jupyterlab_widgets: Make it a standard wheel package - ipywidgets dependency --- build/pkgs/ipywidgets/dependencies | 2 +- build/pkgs/jupyterlab_widgets/SPKG.rst | 10 +++++----- build/pkgs/jupyterlab_widgets/checksums.ini | 5 +++++ build/pkgs/jupyterlab_widgets/dependencies | 2 +- .../{requirements.txt => install-requires.txt} | 0 build/pkgs/jupyterlab_widgets/package-version.txt | 1 + build/pkgs/jupyterlab_widgets/type | 2 +- 7 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 build/pkgs/jupyterlab_widgets/checksums.ini rename build/pkgs/jupyterlab_widgets/{requirements.txt => install-requires.txt} (100%) create mode 100644 build/pkgs/jupyterlab_widgets/package-version.txt diff --git a/build/pkgs/ipywidgets/dependencies b/build/pkgs/ipywidgets/dependencies index e6cc2ed95d5..64f5151c754 100644 --- a/build/pkgs/ipywidgets/dependencies +++ b/build/pkgs/ipywidgets/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) widgetsnbextension | $(PYTHON_TOOLCHAIN) ipykernel ipython traitlets +$(PYTHON) widgetsnbextension jupyterlab_widgets | $(PYTHON_TOOLCHAIN) ipykernel ipython traitlets ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_widgets/SPKG.rst b/build/pkgs/jupyterlab_widgets/SPKG.rst index f17f3c08eda..758cff7b3db 100644 --- a/build/pkgs/jupyterlab_widgets/SPKG.rst +++ b/build/pkgs/jupyterlab_widgets/SPKG.rst @@ -1,18 +1,18 @@ -jupyterlab_widgets: A JupyterLab extension for Jupyter/IPython widgets -====================================================================== +jupyterlab_widgets: Jupyter interactive widgets for JupyterLab +============================================================== Description ----------- -A JupyterLab extension for Jupyter/IPython widgets. +Jupyter interactive widgets for JupyterLab License ------- -BSD License +BSD-3-Clause Upstream Contact ---------------- -Home page: https://github.com/jupyter-widgets/ipywidgets +https://pypi.org/project/jupyterlab-widgets/ diff --git a/build/pkgs/jupyterlab_widgets/checksums.ini b/build/pkgs/jupyterlab_widgets/checksums.ini new file mode 100644 index 00000000000..5d021049263 --- /dev/null +++ b/build/pkgs/jupyterlab_widgets/checksums.ini @@ -0,0 +1,5 @@ +tarball=jupyterlab_widgets-VERSION-py3-none-any.whl +sha1=584e25e221b38c3ca7139667621a3eaf23260ffc +md5=d7b643a04ef1bb9012c58e6833d277c9 +cksum=202463248 +upstream_url=https://pypi.io/packages/py3/j/jupyterlab_widgets/jupyterlab_widgets-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_widgets/dependencies b/build/pkgs/jupyterlab_widgets/dependencies index 4d2deddc8bf..0738c2d7777 100644 --- a/build/pkgs/jupyterlab_widgets/dependencies +++ b/build/pkgs/jupyterlab_widgets/dependencies @@ -1,4 +1,4 @@ -ipympl jupyterlab nodejs tornado $(PYTHON) | $(PYTHON_TOOLCHAIN) jupyter_packaging +$(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/jupyterlab_widgets/requirements.txt b/build/pkgs/jupyterlab_widgets/install-requires.txt similarity index 100% rename from build/pkgs/jupyterlab_widgets/requirements.txt rename to build/pkgs/jupyterlab_widgets/install-requires.txt diff --git a/build/pkgs/jupyterlab_widgets/package-version.txt b/build/pkgs/jupyterlab_widgets/package-version.txt new file mode 100644 index 00000000000..75a22a26ac4 --- /dev/null +++ b/build/pkgs/jupyterlab_widgets/package-version.txt @@ -0,0 +1 @@ +3.0.3 diff --git a/build/pkgs/jupyterlab_widgets/type b/build/pkgs/jupyterlab_widgets/type index 134d9bc32d5..a6a7b9cd726 100644 --- a/build/pkgs/jupyterlab_widgets/type +++ b/build/pkgs/jupyterlab_widgets/type @@ -1 +1 @@ -optional +standard From 5a339e1fc56ba7b470b3aec91497ca6319b24ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 9 Oct 2022 21:17:07 +0200 Subject: [PATCH 283/350] fix some pep in words --- src/sage/combinat/words/finite_word.py | 8 +- src/sage/combinat/words/lyndon_word.py | 1 + src/sage/combinat/words/paths.py | 84 ++++++++++++++++++- src/sage/combinat/words/word.py | 20 ++++- src/sage/combinat/words/word_generators.py | 5 +- .../combinat/words/word_infinite_datatypes.py | 18 ++-- src/sage/combinat/words/word_options.py | 25 +++--- 7 files changed, 129 insertions(+), 32 deletions(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 5773491e025..6acf3866ad3 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -5949,7 +5949,6 @@ def sturmian_desubstitute_as_possible(self): desubstitued_word = desubstitued_word + w_running ** (current_run_length - min_run) return desubstitued_word.sturmian_desubstitute_as_possible() - def is_sturmian_factor(self): r""" Tell whether ``self`` is a factor of a Sturmian word. @@ -6010,7 +6009,6 @@ def is_sturmian_factor(self): """ return self.sturmian_desubstitute_as_possible().is_empty() - def is_tangent(self): r""" Tell whether ``self`` is a tangent word. @@ -6080,7 +6078,6 @@ def is_tangent(self): mini = min(mini , height) return (maxi - mini <= 2) - # TODO. # 1. Those three swap functions should use the cmp of python. # 2. The actual code should then be copied as is in the Word_over_Alphabet @@ -7175,7 +7172,6 @@ def minimal_conjugate(self): if end >= p.length(): return factor ** q -####################################################################### class CallableFromListOfWords(tuple): r""" @@ -7222,6 +7218,7 @@ def __call__(self, i): j -= c.length() raise IndexError("index (=%s) out of range" % i) + class Factorization(list): r""" A list subclass having a nicer representation for factorization of words. @@ -7245,6 +7242,7 @@ def __repr__(self): """ return '(%s)' % ', '.join(w.string_rep() for w in self) + ####################################################################### def evaluation_dict(w): @@ -7270,13 +7268,13 @@ def evaluation_dict(w): sage: evaluation_dict('1213121') # keys appear in random order {'1': 4, '2': 2, '3': 1} - """ d = defaultdict(int) for a in w: d[a] += 1 return dict(d) + def word_to_ordered_set_partition(w): r""" Return the ordered set partition corresponding to a finite diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index c006bb9588c..ca271c5a114 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -613,6 +613,7 @@ def standard_bracketing(lw): if lw[i:] in LyndonWords(): return [standard_bracketing(lw[:i]), standard_bracketing(lw[i:])] + def standard_unbracketing(sblw): """ Return flattened ``sblw`` if it is a standard bracketing of a Lyndon word, diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index 38f238aa945..3d0ee41a4c4 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -202,6 +202,7 @@ WordDatatype_callable) from sage.matrix.constructor import vector_on_axis_rotation_matrix + ####################################################################### # # # WordPaths function # @@ -348,10 +349,11 @@ def WordPaths(alphabet, steps=None): elif steps == 'dyck': return WordPaths_dyck(alphabet=alphabet) else: - raise TypeError("Unknown type of steps : %s"%steps) + raise TypeError("Unknown type of steps : %s" % steps) else: return WordPaths_all(alphabet=alphabet, steps=steps) + ####################################################################### # # # Combinatorial classes of word paths # @@ -608,6 +610,7 @@ def vector_space(self): """ return self._vector_space + class WordPaths_square_grid(WordPaths_all): r""" The combinatorial class of all paths on the square grid. @@ -676,6 +679,7 @@ def __repr__(self): """ return "Word Paths on the square grid" + class WordPaths_triangle_grid(WordPaths_all): r""" The combinatorial class of all paths on the triangle grid. @@ -755,6 +759,7 @@ def __repr__(self): """ return "Word Paths on the triangle grid" + class WordPaths_hexagonal_grid(WordPaths_triangle_grid): r""" The combinatorial class of all paths on the hexagonal grid. @@ -823,6 +828,7 @@ def __repr__(self): """ return "Word Paths on the hexagonal grid" + class WordPaths_cube_grid(WordPaths_all): r""" The combinatorial class of all paths on the cube grid. @@ -890,6 +896,7 @@ def __repr__(self): """ return "Word Paths on the cube grid" + class WordPaths_dyck(WordPaths_all): r""" The combinatorial class of all Dyck paths. @@ -957,6 +964,7 @@ def __repr__(self): """ return "Finite Dyck paths" + class WordPaths_north_east(WordPaths_all): r""" The combinatorial class of all paths using North and East directions. @@ -1024,6 +1032,7 @@ def __repr__(self): """ return "Word Paths in North and East steps" + ####################################################################### # # # Abstract word path classes # @@ -1476,6 +1485,7 @@ def is_tangent(self): """ raise NotImplementedError + class FiniteWordPath_2d(FiniteWordPath_all): def plot(self, pathoptions=dict(rgbcolor='red',thickness=3), fill=True, filloptions=dict(rgbcolor='red',alpha=0.2), @@ -2023,6 +2033,7 @@ def plot(self, pathoptions=dict(rgbcolor='red',arrow_head=True,thickness=3), G += line(pts, **pathoptions) return G + ####################################################################### # # # Abstract word path classes # @@ -2208,7 +2219,8 @@ def tikz_trajectory(self): sage: f.tikz_trajectory() '(0, 0) -- (0, -1) -- (-1, -1) -- (-1, -2) -- (0, -2) -- (0, -3) -- (1, -3) -- (1, -2) -- (2, -2) -- (2, -1) -- (1, -1) -- (1, 0) -- (0, 0)' """ - return ' -- '.join(map(str,self.points())) + return ' -- '.join(map(str, self.points())) + class FiniteWordPath_triangle_grid(FiniteWordPath_2d): # Triangle grid paths are implemented with quadratic fields, @@ -2285,7 +2297,7 @@ def ymax(self): return max(RR(y) for (_,y) in self.points()) -#TODO: faire une verification du mot pour etre sur hexagonal grid +# TODO: faire une verification du mot pour etre sur hexagonal grid class FiniteWordPath_hexagonal_grid(FiniteWordPath_triangle_grid): def __init__(self, parent, *args, **kwds): r""" @@ -2310,15 +2322,19 @@ def __init__(self, parent, *args, **kwds): """ super().__init__(parent, *args, **kwds) + class FiniteWordPath_cube_grid(FiniteWordPath_3d): pass + class FiniteWordPath_north_east(FiniteWordPath_2d): pass + class FiniteWordPath_dyck(FiniteWordPath_2d): pass + ####################################################################### # # # Concrete word path classes # @@ -2345,6 +2361,7 @@ class FiniteWordPath_all_list(WordDatatype_list, FiniteWordPath_all, FiniteWord_ """ pass + class FiniteWordPath_all_str(WordDatatype_str, FiniteWordPath_all, FiniteWord_class): r""" TESTS:: @@ -2359,6 +2376,7 @@ class FiniteWordPath_all_str(WordDatatype_str, FiniteWordPath_all, FiniteWord_cl """ pass + class FiniteWordPath_all_tuple(WordDatatype_tuple, FiniteWordPath_all, FiniteWord_class): r""" TESTS:: @@ -2373,18 +2391,23 @@ class FiniteWordPath_all_tuple(WordDatatype_tuple, FiniteWordPath_all, FiniteWor """ pass + class FiniteWordPath_all_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_all, FiniteWord_class): pass + class FiniteWordPath_all_iter(WordDatatype_iter, FiniteWordPath_all, FiniteWord_class): pass + class FiniteWordPath_all_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_all, FiniteWord_class): pass + class FiniteWordPath_all_callable(WordDatatype_callable, FiniteWordPath_all, FiniteWord_class): pass + ##### Finite paths on 2d ##### class FiniteWordPath_2d_list(WordDatatype_list, FiniteWordPath_2d, FiniteWord_class): @@ -2401,6 +2424,7 @@ class FiniteWordPath_2d_list(WordDatatype_list, FiniteWordPath_2d, FiniteWord_cl """ pass + class FiniteWordPath_2d_str(WordDatatype_str, FiniteWordPath_2d, FiniteWord_class): r""" TESTS:: @@ -2415,6 +2439,7 @@ class FiniteWordPath_2d_str(WordDatatype_str, FiniteWordPath_2d, FiniteWord_clas """ pass + class FiniteWordPath_2d_tuple(WordDatatype_tuple, FiniteWordPath_2d, FiniteWord_class): r""" TESTS:: @@ -2429,18 +2454,23 @@ class FiniteWordPath_2d_tuple(WordDatatype_tuple, FiniteWordPath_2d, FiniteWord_ """ pass + class FiniteWordPath_2d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_2d, FiniteWord_class): pass + class FiniteWordPath_2d_iter(WordDatatype_iter, FiniteWordPath_2d, FiniteWord_class): pass + class FiniteWordPath_2d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_2d, FiniteWord_class): pass + class FiniteWordPath_2d_callable(WordDatatype_callable, FiniteWordPath_2d, FiniteWord_class): pass + ##### Finite paths on 3d ##### class FiniteWordPath_3d_list(WordDatatype_list, FiniteWordPath_3d, FiniteWord_class): @@ -2457,6 +2487,7 @@ class FiniteWordPath_3d_list(WordDatatype_list, FiniteWordPath_3d, FiniteWord_cl """ pass + class FiniteWordPath_3d_str(WordDatatype_str, FiniteWordPath_3d, FiniteWord_class): r""" TESTS:: @@ -2471,6 +2502,7 @@ class FiniteWordPath_3d_str(WordDatatype_str, FiniteWordPath_3d, FiniteWord_clas """ pass + class FiniteWordPath_3d_tuple(WordDatatype_tuple, FiniteWordPath_3d, FiniteWord_class): r""" TESTS:: @@ -2485,18 +2517,23 @@ class FiniteWordPath_3d_tuple(WordDatatype_tuple, FiniteWordPath_3d, FiniteWord_ """ pass + class FiniteWordPath_3d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_3d, FiniteWord_class): pass + class FiniteWordPath_3d_iter(WordDatatype_iter, FiniteWordPath_3d, FiniteWord_class): pass + class FiniteWordPath_3d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_3d, FiniteWord_class): pass + class FiniteWordPath_3d_callable(WordDatatype_callable, FiniteWordPath_3d, FiniteWord_class): pass + ##### Finite paths on square grid ##### class FiniteWordPath_square_grid_list(WordDatatype_list, FiniteWordPath_square_grid, FiniteWord_class): @@ -2513,6 +2550,7 @@ class FiniteWordPath_square_grid_list(WordDatatype_list, FiniteWordPath_square_g """ pass + class FiniteWordPath_square_grid_str(WordDatatype_str, FiniteWordPath_square_grid, FiniteWord_class): r""" TESTS:: @@ -2527,6 +2565,7 @@ class FiniteWordPath_square_grid_str(WordDatatype_str, FiniteWordPath_square_gri """ pass + class FiniteWordPath_square_grid_tuple(WordDatatype_tuple, FiniteWordPath_square_grid, FiniteWord_class): r""" TESTS:: @@ -2541,18 +2580,23 @@ class FiniteWordPath_square_grid_tuple(WordDatatype_tuple, FiniteWordPath_square """ pass + class FiniteWordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, FiniteWord_class): pass + class FiniteWordPath_square_grid_iter(WordDatatype_iter, FiniteWordPath_square_grid, FiniteWord_class): pass + class FiniteWordPath_square_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_square_grid, FiniteWord_class): pass + class FiniteWordPath_square_grid_callable(WordDatatype_callable, FiniteWordPath_square_grid, FiniteWord_class): pass + ##### Unknown length paths on square grid (experimental) ##### #class WordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, Word_class): @@ -2574,6 +2618,7 @@ class FiniteWordPath_triangle_grid_list(WordDatatype_list, FiniteWordPath_triang """ pass + class FiniteWordPath_triangle_grid_str(WordDatatype_str, FiniteWordPath_triangle_grid, FiniteWord_class): r""" TESTS:: @@ -2588,6 +2633,7 @@ class FiniteWordPath_triangle_grid_str(WordDatatype_str, FiniteWordPath_triangle """ pass + class FiniteWordPath_triangle_grid_tuple(WordDatatype_tuple, FiniteWordPath_triangle_grid, FiniteWord_class): r""" TESTS:: @@ -2602,18 +2648,23 @@ class FiniteWordPath_triangle_grid_tuple(WordDatatype_tuple, FiniteWordPath_tria """ pass + class FiniteWordPath_triangle_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class): pass + class FiniteWordPath_triangle_grid_iter(WordDatatype_iter, FiniteWordPath_triangle_grid, FiniteWord_class): pass + class FiniteWordPath_triangle_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class): pass + class FiniteWordPath_triangle_grid_callable(WordDatatype_callable, FiniteWordPath_triangle_grid, FiniteWord_class): pass + ##### Finite paths on hexagonal grid ##### class FiniteWordPath_hexagonal_grid_list(WordDatatype_list, FiniteWordPath_hexagonal_grid, FiniteWord_class): @@ -2630,6 +2681,7 @@ class FiniteWordPath_hexagonal_grid_list(WordDatatype_list, FiniteWordPath_hexag """ pass + class FiniteWordPath_hexagonal_grid_str(WordDatatype_str, FiniteWordPath_hexagonal_grid, FiniteWord_class): r""" TESTS:: @@ -2644,6 +2696,7 @@ class FiniteWordPath_hexagonal_grid_str(WordDatatype_str, FiniteWordPath_hexagon """ pass + class FiniteWordPath_hexagonal_grid_tuple(WordDatatype_tuple, FiniteWordPath_hexagonal_grid, FiniteWord_class): r""" TESTS:: @@ -2658,18 +2711,23 @@ class FiniteWordPath_hexagonal_grid_tuple(WordDatatype_tuple, FiniteWordPath_hex """ pass + class FiniteWordPath_hexagonal_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class): pass + class FiniteWordPath_hexagonal_grid_iter(WordDatatype_iter, FiniteWordPath_hexagonal_grid, FiniteWord_class): pass + class FiniteWordPath_hexagonal_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class): pass + class FiniteWordPath_hexagonal_grid_callable(WordDatatype_callable, FiniteWordPath_hexagonal_grid, FiniteWord_class): pass + ##### Finite paths on cube grid ##### class FiniteWordPath_cube_grid_list(WordDatatype_list, FiniteWordPath_cube_grid, FiniteWord_class): @@ -2686,6 +2744,7 @@ class FiniteWordPath_cube_grid_list(WordDatatype_list, FiniteWordPath_cube_grid, """ pass + class FiniteWordPath_cube_grid_str(WordDatatype_str, FiniteWordPath_cube_grid, FiniteWord_class): r""" TESTS:: @@ -2700,6 +2759,7 @@ class FiniteWordPath_cube_grid_str(WordDatatype_str, FiniteWordPath_cube_grid, F """ pass + class FiniteWordPath_cube_grid_tuple(WordDatatype_tuple, FiniteWordPath_cube_grid, FiniteWord_class): r""" TESTS:: @@ -2714,18 +2774,23 @@ class FiniteWordPath_cube_grid_tuple(WordDatatype_tuple, FiniteWordPath_cube_gri """ pass + class FiniteWordPath_cube_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_cube_grid, FiniteWord_class): pass + class FiniteWordPath_cube_grid_iter(WordDatatype_iter, FiniteWordPath_cube_grid, FiniteWord_class): pass + class FiniteWordPath_cube_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_cube_grid, FiniteWord_class): pass + class FiniteWordPath_cube_grid_callable(WordDatatype_callable, FiniteWordPath_cube_grid, FiniteWord_class): pass + ##### Finite paths on north_east ##### class FiniteWordPath_north_east_list(WordDatatype_list, FiniteWordPath_north_east, FiniteWord_class): @@ -2742,6 +2807,7 @@ class FiniteWordPath_north_east_list(WordDatatype_list, FiniteWordPath_north_eas """ pass + class FiniteWordPath_north_east_str(WordDatatype_str, FiniteWordPath_north_east, FiniteWord_class): r""" TESTS:: @@ -2756,6 +2822,7 @@ class FiniteWordPath_north_east_str(WordDatatype_str, FiniteWordPath_north_east, """ pass + class FiniteWordPath_north_east_tuple(WordDatatype_tuple, FiniteWordPath_north_east, FiniteWord_class): r""" TESTS:: @@ -2770,18 +2837,23 @@ class FiniteWordPath_north_east_tuple(WordDatatype_tuple, FiniteWordPath_north_e """ pass + class FiniteWordPath_north_east_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_north_east, FiniteWord_class): pass + class FiniteWordPath_north_east_iter(WordDatatype_iter, FiniteWordPath_north_east, FiniteWord_class): pass + class FiniteWordPath_north_east_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_north_east, FiniteWord_class): pass + class FiniteWordPath_north_east_callable(WordDatatype_callable, FiniteWordPath_north_east, FiniteWord_class): pass + ##### Finite paths on dyck ##### class FiniteWordPath_dyck_list(WordDatatype_list, FiniteWordPath_dyck, FiniteWord_class): @@ -2798,6 +2870,7 @@ class FiniteWordPath_dyck_list(WordDatatype_list, FiniteWordPath_dyck, FiniteWor """ pass + class FiniteWordPath_dyck_str(WordDatatype_str, FiniteWordPath_dyck, FiniteWord_class): r""" TESTS:: @@ -2812,6 +2885,7 @@ class FiniteWordPath_dyck_str(WordDatatype_str, FiniteWordPath_dyck, FiniteWord_ """ pass + class FiniteWordPath_dyck_tuple(WordDatatype_tuple, FiniteWordPath_dyck, FiniteWord_class): r""" TESTS:: @@ -2826,14 +2900,18 @@ class FiniteWordPath_dyck_tuple(WordDatatype_tuple, FiniteWordPath_dyck, FiniteW """ pass + class FiniteWordPath_dyck_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_dyck, FiniteWord_class): pass + class FiniteWordPath_dyck_iter(WordDatatype_iter, FiniteWordPath_dyck, FiniteWord_class): pass + class FiniteWordPath_dyck_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_dyck, FiniteWord_class): pass + class FiniteWordPath_dyck_callable(WordDatatype_callable, FiniteWordPath_dyck, FiniteWord_class): pass diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 85974ec33e7..3822e85eb36 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -41,6 +41,7 @@ # TODO. Word needs to be replaced by Word. Consider renaming # Word_class to Word and imbedding Word as its __call__ method. + def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK_data=None): r""" Construct a word. @@ -218,6 +219,7 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK ##### Finite Words ##### + class FiniteWord_char(WordDatatype_char, FiniteWord_class): r""" Finite word represented by an array ``unsigned char *`` (i.e. integers @@ -279,6 +281,7 @@ class FiniteWord_char(WordDatatype_char, FiniteWord_class): """ pass + class FiniteWord_list(WordDatatype_list, FiniteWord_class): r""" Finite word represented by a Python list. @@ -300,6 +303,7 @@ class FiniteWord_list(WordDatatype_list, FiniteWord_class): """ pass + class FiniteWord_str(WordDatatype_str, FiniteWord_class): r""" Finite word represented by a Python str. @@ -321,6 +325,7 @@ class FiniteWord_str(WordDatatype_str, FiniteWord_class): """ pass + class FiniteWord_tuple(WordDatatype_tuple, FiniteWord_class): r""" Finite word represented by a Python tuple. @@ -342,6 +347,7 @@ class FiniteWord_tuple(WordDatatype_tuple, FiniteWord_class): """ pass + class FiniteWord_iter_with_caching(WordDatatype_iter_with_caching, FiniteWord_class): r""" Finite word represented by an iterator (with caching). @@ -368,6 +374,7 @@ class FiniteWord_iter_with_caching(WordDatatype_iter_with_caching, FiniteWord_cl """ pass + class FiniteWord_iter(WordDatatype_iter, FiniteWord_class): r""" Finite word represented by an iterator. @@ -396,6 +403,7 @@ class FiniteWord_iter(WordDatatype_iter, FiniteWord_class): """ pass + class FiniteWord_callable_with_caching(WordDatatype_callable_with_caching, FiniteWord_class): r""" Finite word represented by a callable (with caching). @@ -447,6 +455,7 @@ class FiniteWord_callable_with_caching(WordDatatype_callable_with_caching, Finit """ pass + class FiniteWord_callable(WordDatatype_callable, FiniteWord_class): r""" Finite word represented by a callable. @@ -476,6 +485,7 @@ class FiniteWord_callable(WordDatatype_callable, FiniteWord_class): """ pass + ##### Infinite Words ##### class InfiniteWord_iter_with_caching(WordDatatype_iter_with_caching, InfiniteWord_class): @@ -516,6 +526,7 @@ class InfiniteWord_iter_with_caching(WordDatatype_iter_with_caching, InfiniteWor """ pass + class InfiniteWord_iter(WordDatatype_iter, InfiniteWord_class): r""" Infinite word represented by an iterable. @@ -554,6 +565,7 @@ class InfiniteWord_iter(WordDatatype_iter, InfiniteWord_class): """ pass + class InfiniteWord_callable_with_caching(WordDatatype_callable_with_caching, InfiniteWord_class): r""" Infinite word represented by a callable (with caching). @@ -584,6 +596,7 @@ class InfiniteWord_callable_with_caching(WordDatatype_callable_with_caching, Inf """ pass + class InfiniteWord_callable(WordDatatype_callable, InfiniteWord_class): r""" Infinite word represented by a callable. @@ -615,6 +628,7 @@ class InfiniteWord_callable(WordDatatype_callable, InfiniteWord_class): """ pass + ##### Words of unknown length ##### class Word_iter_with_caching(WordDatatype_iter_with_caching, Word_class): @@ -653,6 +667,7 @@ class Word_iter_with_caching(WordDatatype_iter_with_caching, Word_class): """ pass + class Word_iter(WordDatatype_iter, Word_class): r""" Word of unknown length (finite or infinite) represented by an @@ -689,7 +704,9 @@ class Word_iter(WordDatatype_iter, Word_class): """ pass + ##### Morphic Words ##### + class FiniteWord_morphic(WordDatatype_morphic, FiniteWord_class): r""" Finite morphic word. @@ -713,10 +730,10 @@ class FiniteWord_morphic(WordDatatype_morphic, FiniteWord_class): sage: loads(dumps(w)) word: ab - """ pass + class InfiniteWord_morphic(WordDatatype_morphic, InfiniteWord_class): r""" Morphic word of infinite length. @@ -740,6 +757,5 @@ class InfiniteWord_morphic(WordDatatype_morphic, InfiniteWord_class): sage: loads(dumps(w)) word: abaababaabaababaababaabaababaabaababaaba... - """ pass diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index e7110609d63..4c889636fba 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -104,6 +104,7 @@ def _build_tab(sym, tab, W): res.append((w[-1] % c) + 1) return res + class LowerChristoffelWord(FiniteWord_list): r""" Returns the lower Christoffel word of slope `p/q`, where `p` and @@ -310,6 +311,7 @@ def __reduce__(self): """ return self.__class__, (self.__p, self.__q, self.parent().alphabet()) + class WordGenerator(): r""" Constructor of several famous words. @@ -1275,7 +1277,7 @@ def StandardEpisturmianWord(self, directive_word): if not isinstance(directive_word, Word_class): raise TypeError("directive_word is not a word, so it cannot be used to build an episturmian word") epistandard = directive_word.parent()(\ - self._StandardEpisturmianWord_LetterIterator(directive_word), \ + self._StandardEpisturmianWord_LetterIterator(directive_word), datatype='iter') return epistandard @@ -2042,4 +2044,5 @@ def BaumSweetWord(self): inner = WordMorphism('a->aa,b->cb,c->ba,d->db') return outer(inner.fixed_point('d')) + words = WordGenerator() diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index 90ab35efd84..defef1e84d1 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -244,13 +244,13 @@ def __getitem__(self, key): if step > 0: start = 0 if key.start is None else key.start length = self._len if key.stop is None else \ - int(max(0,ceil((key.stop-start)/float(step)))) + int(max(0, ceil((key.stop-start)/float(step)))) else: if key.start is None or key.start < 0: raise ValueError("start value must be nonnegative for negative step values") start = key.start stop = 0 if key.stop is None else key.stop - length = int(max(0,ceil((key.stop-start)/float(step)))) + length = int(max(0, ceil((key.stop-start)/float(step)))) fcn = lambda x: self._func(start + x*step) if length is None: return self._parent(fcn, length=length) @@ -270,7 +270,7 @@ def __getitem__(self, key): else: start, stop, step = slice(key.start, key.stop, step).indices(self._len) - length = int(max(0,ceil((stop-start)/float(step)))) + length = int(max(0, ceil((stop-start)/float(step)))) fcn = lambda x: self._func(start + x*step) return self._parent(fcn, length=length) else: @@ -313,6 +313,7 @@ def __reduce__(self): else: return self._parent, (s, 'pickled_function', False) + class WordDatatype_callable_with_caching(WordDatatype_callable): r""" Datatype for a word defined by a callable. @@ -581,6 +582,7 @@ def flush(self): """ self._letter_cache = {} + class WordDatatype_iter(WordDatatype): # NOTE: The constructor callable should do all the slicing (see islice) def __init__(self, parent, iter, length=None): @@ -839,7 +841,7 @@ def __getitem__(self, key): length = Infinity stop = None else: # key.stop > 0 - length = int(max(0,ceil((key.stop-start)/float(step)))) + length = int(max(0, ceil((key.stop-start)/float(step)))) stop = int(key.stop) data = itertools.islice(self, start, stop, step) else: @@ -847,7 +849,7 @@ def __getitem__(self, key): raise ValueError("start value must be nonnegative for negative step values") start = int(key.start) stop = 0 if key.stop is None else int(key.stop) - length = int(max(0,ceil((stop-start)/float(step)))) + length = int(max(0, ceil((stop-start)/float(step)))) data = list(itertools.islice(self, start+1))[key] if length is None or length is Infinity: @@ -872,7 +874,7 @@ def __getitem__(self, key): length = None else: # start >= 0, step >= 1, stop >= 0 or None data = itertools.islice(self, start, stop, step) - length = "unknown" if stop is None else int(max(0,((stop-start)/float(step)))) + length = "unknown" if stop is None else int(max(0, ((stop-start)/float(step)))) return self._parent.factors()(data, length=length) else: @@ -912,8 +914,8 @@ def __reduce__(self): """ if self.is_finite(): return self._parent, (list(self),) - else: - return self._parent, (iter(self), 'iter', False) + return self._parent, (iter(self), 'iter', False) + class WordDatatype_iter_with_caching(WordDatatype_iter): def __init__(self, parent, iter, length=None): diff --git a/src/sage/combinat/words/word_options.py b/src/sage/combinat/words/word_options.py index e49946a9deb..2d2bf3bc7ff 100644 --- a/src/sage/combinat/words/word_options.py +++ b/src/sage/combinat/words/word_options.py @@ -1,27 +1,26 @@ r""" User-customizable options for words """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Franco Saliola # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import copy from sage.rings.integer import Integer -word_options = {\ - 'identifier':'word: ', \ - 'display':'string', \ - 'truncate':True, \ - 'truncate_length':40, \ - 'letter_separator':',', \ - 'cache':True, \ - 'old_repr':False \ - } +word_options = {'identifier': 'word: ', + 'display': 'string', + 'truncate': True, + 'truncate_length': 40, + 'letter_separator': ',', + 'cache': True, + 'old_repr': False} + def WordOptions(**kwargs): """ @@ -73,7 +72,7 @@ def WordOptions(**kwargs): else: word_options['truncate'] = kwargs['truncate'] elif 'truncate_length' in kwargs: - if not isinstance(kwargs['truncate_length'], (int,Integer)) or kwargs['truncate_length'] <= 0: + if not isinstance(kwargs['truncate_length'], (int, Integer)) or kwargs['truncate_length'] <= 0: raise ValueError("truncate_length must be a positive integer") else: word_options['truncate_length'] = kwargs['truncate_length'] From c6881bbba4333243ef6badc14b959e516f4bc39a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 9 Oct 2022 12:21:17 -0700 Subject: [PATCH 284/350] src/bin/sage-notebook: No longer point to jupyterlab_widgets to install jupyterlab --- src/bin/sage-notebook | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/bin/sage-notebook b/src/bin/sage-notebook index 13636b88703..2e8b12e1a1c 100755 --- a/src/bin/sage-notebook +++ b/src/bin/sage-notebook @@ -60,9 +60,6 @@ class NotebookJupyterlab(): traceback.print_exc() print("Jupyterlab is not installed (at least not in this Sage installation).") print("You can install it by running") - print(" sage -i jupyterlab_widgets") - print("which includes support for interacts and the ability to download and") - print("install other Jupyterlab extensions. For a minimal installation, run") print(" sage -i jupyterlab") print("Alternatively, you can follow the instructions at") print(" " + _system_jupyter_url) @@ -89,9 +86,6 @@ class NotebookNbclassic(): traceback.print_exc() print("Jupyterlab is not installed (at least not in this Sage installation).") print("You can install it by running") - print(" sage -i jupyterlab_widgets") - print("which includes support for interacts and the ability to download and") - print("install other Jupyterlab extensions. For a minimal installation, run") print(" sage -i jupyterlab") raise SystemExit(1) self.print_banner() @@ -115,9 +109,6 @@ class NotebookRetrolab(): traceback.print_exc() print("Retrolab is not installed (at least not in this Sage installation).") print("You can install it by running") - print(" sage -i jupyterlab_widgets retrolab") - print("which includes support for interacts and the ability to download and") - print("install other Jupyterlab extensions. For a minimal installation, run") print(" sage -i retrolab") raise SystemExit(1) self.print_banner() From 5cf583646a4d990d3e5d3163ba7c620a1712f141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Mon, 10 Oct 2022 10:54:07 +1300 Subject: [PATCH 285/350] update imagesize to 1.4.1. Minimum required for sphinx 5.2 is 1.3. --- build/pkgs/imagesize/checksums.ini | 6 +++--- build/pkgs/imagesize/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/imagesize/checksums.ini b/build/pkgs/imagesize/checksums.ini index 6a49dac52c4..8e0bef1a816 100644 --- a/build/pkgs/imagesize/checksums.ini +++ b/build/pkgs/imagesize/checksums.ini @@ -1,5 +1,5 @@ tarball=imagesize-VERSION.tar.gz -sha1=b88a92cabe93b5a53faacb1cff4e50f8a2d9427a -md5=3a1e124594183778a8f87e4bcdb6dca9 -cksum=2804705518 +sha1=89627e703f80c3ad2a77cc8168d85d119e71dcbe +md5=5a40586a25c07e1a8f16f6267252c321 +cksum=3711184129 upstream_url=https://pypi.io/packages/source/i/imagesize/imagesize-VERSION.tar.gz diff --git a/build/pkgs/imagesize/package-version.txt b/build/pkgs/imagesize/package-version.txt index 26aaba0e866..347f5833ee6 100644 --- a/build/pkgs/imagesize/package-version.txt +++ b/build/pkgs/imagesize/package-version.txt @@ -1 +1 @@ -1.2.0 +1.4.1 From 8f8af65e54d3a9962cfab40f15dc23f4e955b43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Mon, 10 Oct 2022 10:56:37 +1300 Subject: [PATCH 286/350] update sphinx to 5.2.3 --- build/pkgs/sphinx/checksums.ini | 6 +++--- build/pkgs/sphinx/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/sphinx/checksums.ini b/build/pkgs/sphinx/checksums.ini index 49b3d2806f4..99c08b0c2d5 100644 --- a/build/pkgs/sphinx/checksums.ini +++ b/build/pkgs/sphinx/checksums.ini @@ -1,5 +1,5 @@ tarball=Sphinx-VERSION.tar.gz -sha1=e1c25f090eb9e1960276bafd636374413f17660f -md5=a266df26c4cabd093f55b79eaaffc4bd -cksum=2420152777 +sha1=bef629b31b868d3b031050bd36653696f6b73d8e +md5=327ae7af29b3f08f059b52a4b9ed98cb +cksum=2569899835 upstream_url=https://pypi.io/packages/source/s/sphinx/Sphinx-VERSION.tar.gz diff --git a/build/pkgs/sphinx/package-version.txt b/build/pkgs/sphinx/package-version.txt index 91ff57278e3..c0baecbaaa9 100644 --- a/build/pkgs/sphinx/package-version.txt +++ b/build/pkgs/sphinx/package-version.txt @@ -1 +1 @@ -5.2.0 +5.2.3 From d7474da083fc06e3316c4bdb54d7c1ddc3f3ff9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 11:09:09 +0200 Subject: [PATCH 287/350] pep8 cleanup for genera/normal_form --- .../quadratic_forms/genera/normal_form.py | 439 +++++++++--------- 1 file changed, 224 insertions(+), 215 deletions(-) diff --git a/src/sage/quadratic_forms/genera/normal_form.py b/src/sage/quadratic_forms/genera/normal_form.py index 4744e3d079e..a1fc35588d1 100644 --- a/src/sage/quadratic_forms/genera/normal_form.py +++ b/src/sage/quadratic_forms/genera/normal_form.py @@ -120,7 +120,7 @@ def collect_small_blocks(G): L = _get_small_block_indices(D)[1:] D.subdivide(L, L) blocks = [] - for i in range(len(L)+1): + for i in range(len(L) + 1): block = copy(D.subdivision(i, i)) blocks.append(block) return blocks @@ -246,11 +246,11 @@ def p_adic_normal_form(G, p, precision=None, partial=False, debug=False): d = denom.valuation(p) r = G0.rank() if r != G0.ncols(): - U = G0.hermite_form(transformation=True)[1] + U = G0.hermite_form(transformation=True)[1] else: U = G0.parent().identity_matrix() - kernel = U[r:,:] - nondeg = U[:r,:] + kernel = U[r:, :] + nondeg = U[:r, :] # continue with the non-degenerate part G = nondeg * G * nondeg.T * p**d @@ -282,10 +282,10 @@ def p_adic_normal_form(G, p, precision=None, partial=False, debug=False): if debug: assert B.determinant().valuation() == 0 # B is invertible! if p == 2: - assert B*G*B.T == Matrix.block_diagonal(collect_small_blocks(D)) + assert B * G * B.T == Matrix.block_diagonal(collect_small_blocks(D)) else: - assert B*G*B.T == Matrix.diagonal(D.diagonal()) - return D/p**d, B + assert B * G * B.T == Matrix.diagonal(D.diagonal()) + return D / p**d, B def _find_min_p(G, cnt, lower_bound=0): @@ -338,7 +338,7 @@ def _find_min_p(G, cnt, lower_bound=0): minval = v # off diagonal for i in range(cnt, n): - for j in range(i+1, n): + for j in range(i + 1, n): v = G[i, j].valuation() if v == lower_bound: return lower_bound, i, j @@ -375,16 +375,17 @@ def _get_small_block_indices(G): L = [] n = G.ncols() i = 0 - while i < n-1: + while i < n - 1: L.append(i) - if G[i, i+1]!=0: + if G[i, i + 1] != 0: i += 2 else: i += 1 - if i == n-1: + if i == n - 1: L.append(i) return L[:] + def _get_homogeneous_block_indices(G): r""" Return the indices of the homogeneous blocks. @@ -394,7 +395,7 @@ def _get_homogeneous_block_indices(G): INPUT: - - ``G`` - a block diagonal matrix over the p-adics + - ``G`` -- a block diagonal matrix over the p-adics with blocks of size at most `2`. OUTPUT: @@ -418,26 +419,27 @@ def _get_homogeneous_block_indices(G): n = G.ncols() i = 0 val = -5 - while i < n-1: - if G[i,i+1] != 0: - m = G[i,i+1].valuation() + while i < n - 1: + if G[i, i + 1] != 0: + m = G[i, i + 1].valuation() else: - m = G[i,i].valuation() + m = G[i, i].valuation() if m > val: L.append(i) val = m vals.append(val) - if G[i, i+1] != 0: + if G[i, i + 1] != 0: i += 1 i += 1 - if i == n-1: - m = G[i,i].valuation() + if i == n - 1: + m = G[i, i].valuation() if m > val: L.append(i) val = m vals.append(val) return L, vals + def _homogeneous_normal_form(G, w): r""" Return the homogeneous normal form of the homogeneous ``G``. @@ -522,34 +524,35 @@ def _homogeneous_normal_form(G, w): D = copy(G) n = B.ncols() if w == 2: - if n>2 and D[-3,-3]!=0: + if n > 2 and D[-3, -3] != 0: v = 2 else: v = 0 - if v==2: - e1 = D[-2,-2].unit_part() - e2 = D[-1,-1].unit_part() + if v == 2: + e1 = D[-2, -2].unit_part() + e2 = D[-1, -1].unit_part() e = {e1, e2} - E = [{1,3}, {1,7}, {5,7}, {3,5}] + E = [{1, 3}, {1, 7}, {5, 7}, {3, 5}] if e not in E: - B[-4:,:] = _relations(D[-4:,-4:], 5) * B[-4:,:] + B[-4:, :] = _relations(D[-4:, -4:], 5) * B[-4:, :] D = B * G * B.T - e1 = D[-2,-2].unit_part() - e2 = D[-1,-1].unit_part() - e = {e1,e2} - E = [{3,3}, {3,5}, {5,5}, {5,7}] + e1 = D[-2, -2].unit_part() + e2 = D[-1, -1].unit_part() + e = {e1, e2} + E = [{3, 3}, {3, 5}, {5, 5}, {5, 7}] if e in E: - B[-2:,:] = _relations(D[-2:,-2:], 1) * B[-2:,:] + B[-2:, :] = _relations(D[-2:, -2:], 1) * B[-2:, :] D = B * G * B.T # assert that e1 < e2 - e1 = D[-2,-2].unit_part() - e2 = D[-1,-1].unit_part() + e1 = D[-2, -2].unit_part() + e2 = D[-1, -1].unit_part() if ZZ(e1) > ZZ(e2): - B.swap_rows(n-1, n-2) - D.swap_rows(n-1, n-2) - D.swap_columns(n-1, n-2) + B.swap_rows(n - 1, n - 2) + D.swap_rows(n - 1, n - 2) + D.swap_columns(n - 1, n - 2) return D, B + def _jordan_odd_adic(G): r""" Return the Jordan decomposition of a symmetric matrix over an odd prime. @@ -608,8 +611,8 @@ def _jordan_odd_adic(G): D.swap_columns(cnt, piv1) # we are already orthogonal to the part with i < cnt # now make the rest orthogonal too - for i in range(cnt+1,n): - if D[i, cnt]!= 0: + for i in range(cnt + 1, n): + if D[i, cnt] != 0: c = D[i, cnt] // D[cnt, cnt] B[i, :] += - c * B[cnt, :] D[i, :] += - c * D[cnt, :] @@ -680,55 +683,56 @@ def _jordan_2_adic(G): cnt = 0 minval = None while cnt < n: - pivot = _find_min_p(D, cnt) - piv1 = pivot[1] - piv2 = pivot[2] - minval = pivot[0] - # the smallest valuation is on the diagonal - if piv1 == piv2: - # move pivot to position [cnt,cnt] - if piv1 != cnt: - B.swap_rows(cnt, piv1) - D.swap_rows(cnt, piv1) - D.swap_columns(cnt, piv1) - # we are already orthogonal to the part with i < cnt - # now make the rest orthogonal too - for i in range(cnt+1, n): - if D[i, cnt] != 0: - c = D[i, cnt]//D[cnt, cnt] - B[i, :] += -c * B[cnt, :] - D[i, :] += -c * D[cnt, :] - D[:, i] += -c * D[:, cnt] - cnt = cnt + 1 - # the smallest valuation is off the diagonal - else: - # move this 2 x 2 block to the top left (starting from cnt) - if piv1 != cnt: - B.swap_rows(cnt, piv1) - D.swap_rows(cnt, piv1) - D.swap_columns(cnt, piv1) - if piv2 != cnt+1: - B.swap_rows(cnt+1, piv2) - D.swap_rows(cnt+1, piv2) - D.swap_columns(cnt+1, piv2) - # we split off a 2 x 2 block - # if it is the last 2 x 2 block, there is nothing to do. - if cnt != n-2: - content = R(2 ** minval) - eqn_mat = D[cnt:cnt+2, cnt:cnt+2].list() - eqn_mat = Matrix(R, 2, 2, [e // content for e in eqn_mat]) - # calculate the inverse without using division - inv = eqn_mat.adjugate() * eqn_mat.det().inverse_of_unit() - B1 = B[cnt:cnt+2, :] - B2 = D[cnt+2:, cnt:cnt+2] * inv - for i in range(B2.nrows()): - for j in range(B2.ncols()): - B2[i, j]=B2[i, j] // content - B[cnt+2:, :] -= B2 * B1 - D[cnt:, cnt:] = B[cnt:, :] * G * B[cnt:, :].transpose() - cnt += 2 + pivot = _find_min_p(D, cnt) + piv1 = pivot[1] + piv2 = pivot[2] + minval = pivot[0] + # the smallest valuation is on the diagonal + if piv1 == piv2: + # move pivot to position [cnt,cnt] + if piv1 != cnt: + B.swap_rows(cnt, piv1) + D.swap_rows(cnt, piv1) + D.swap_columns(cnt, piv1) + # we are already orthogonal to the part with i < cnt + # now make the rest orthogonal too + for i in range(cnt + 1, n): + if D[i, cnt] != 0: + c = D[i, cnt] // D[cnt, cnt] + B[i, :] += -c * B[cnt, :] + D[i, :] += -c * D[cnt, :] + D[:, i] += -c * D[:, cnt] + cnt = cnt + 1 + # the smallest valuation is off the diagonal + else: + # move this 2 x 2 block to the top left (starting from cnt) + if piv1 != cnt: + B.swap_rows(cnt, piv1) + D.swap_rows(cnt, piv1) + D.swap_columns(cnt, piv1) + if piv2 != cnt + 1: + B.swap_rows(cnt + 1, piv2) + D.swap_rows(cnt + 1, piv2) + D.swap_columns(cnt + 1, piv2) + # we split off a 2 x 2 block + # if it is the last 2 x 2 block, there is nothing to do. + if cnt != n - 2: + content = R(2 ** minval) + eqn_mat = D[cnt:cnt + 2, cnt:cnt + 2].list() + eqn_mat = Matrix(R, 2, 2, [e // content for e in eqn_mat]) + # calculate the inverse without using division + inv = eqn_mat.adjugate() * eqn_mat.det().inverse_of_unit() + B1 = B[cnt:cnt + 2, :] + B2 = D[cnt + 2:, cnt:cnt + 2] * inv + for i in range(B2.nrows()): + for j in range(B2.ncols()): + B2[i, j] = B2[i, j] // content + B[cnt + 2:, :] -= B2 * B1 + D[cnt:, cnt:] = B[cnt:, :] * G * B[cnt:, :].transpose() + cnt += 2 return D, B + def _min_nonsquare(p): r""" Return the minimal nonsquare modulo the prime `p`. @@ -752,11 +756,11 @@ def _min_nonsquare(p): sage: _min_nonsquare(7) 3 """ - R = GF(p) - for i in R: - if not R(i).is_square(): + for i in GF(p): + if not i.is_square(): return i + def _normalize(G, normal_odd=True): r""" Return the transformation to sums of forms of types `U`, `V` and `W`. @@ -805,14 +809,14 @@ def _normalize(G, normal_odd=True): non_squares = [] val = 0 for i in range(n): - if D[i,i].valuation() > val: + if D[i, i].valuation() > val: # a new block starts - val = D[i,i].valuation() + val = D[i, i].valuation() if normal_odd and len(non_squares) != 0: # move the non-square to # the last entry of the previous block j = non_squares.pop() - B.swap_rows(j, i-1) + B.swap_rows(j, i - 1) d = D[i, i].unit_part() if d.is_square(): D[i, i] = 1 @@ -824,15 +828,15 @@ def _normalize(G, normal_odd=True): # we combine two non-squares to get # the 2 x 2 identity matrix j = non_squares.pop() - trafo = _normalize_odd_2x2(D[[i,j],[i,j]]) - B[[i,j],:] = trafo*B[[i,j],:] - D[i,i] = 1 - D[j,j] = 1 + trafo = _normalize_odd_2x2(D[[i, j], [i, j]]) + B[[i, j], :] = trafo * B[[i, j], :] + D[i, i] = 1 + D[j, j] = 1 else: non_squares.append(i) - if normal_odd and len(non_squares) != 0: - j=non_squares.pop() - B.swap_rows(j,n-1) + if normal_odd and non_squares: + j = non_squares.pop() + B.swap_rows(j, n - 1) else: # squareclasses 1,3,5,7 modulo 8 for i in range(n): @@ -841,14 +845,15 @@ def _normalize(G, normal_odd=True): v = R(mod(d, 8)) B[i, :] *= (v * d.inverse_of_unit()).sqrt() D = B * G * B.T - for i in range(n-1): - if D[i, i+1] != 0: # there is a 2 x 2 block here - block = D[i:i+2, i:i+2] + for i in range(n - 1): + if D[i, i + 1] != 0: # there is a 2 x 2 block here + block = D[i:i + 2, i:i + 2] trafo = _normalize_2x2(block) - B[i:i+2, :] = trafo * B[i:i+2, :] + B[i:i + 2, :] = trafo * B[i:i + 2, :] D = B * G * B.T return D, B + def _normalize_2x2(G): r""" Normalize this indecomposable `2` by `2` block. @@ -904,9 +909,9 @@ def _normalize_2x2(G): # The input must be an even block odd1 = (G[0, 0].valuation() < G[1, 0].valuation()) odd2 = (G[1, 1].valuation() < G[1, 0].valuation()) - if odd1 or odd2: - raise ValueError("Not a valid 2 x 2 block.") - scale = 2 ** G[0,1].valuation() + if odd1 or odd2: + raise ValueError("not a valid 2 x 2 block") + scale = 2 ** G[0, 1].valuation() D = Matrix(R, 2, 2, [d // scale for d in G.list()]) # now D is of the form # [2a b ] @@ -932,7 +937,7 @@ def _normalize_2x2(G): # 1 2 # Find a point of norm 2 # solve: 2 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] - pol = (D[1,1]*x**2 + 2*D[1,0]*x + D[0,0]-2) // 2 + pol = (D[1, 1] * x**2 + 2 * D[1, 0] * x + D[0, 0] - 2) // 2 # somehow else pari can get a hickup see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] @@ -944,35 +949,35 @@ def _normalize_2x2(G): # solve: v*D*v == 2 with v = (x, -2*x+1) if D[1, 1] != 2: - v = vector([x, -2*x + 1]) - pol = (v*D*v - 2) // 2 + v = vector([x, -2 * x + 1]) + pol = (v * D * v - 2) // 2 # somehow else pari can get a hickup see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] - B[1, :] = sol * B[0,:] + (-2*sol + 1)*B[1, :] + B[1, :] = sol * B[0, :] + (-2 * sol + 1) * B[1, :] D = B * G * B.transpose() # check the result - assert D == Matrix(G.parent(), 2, 2, [2, 1, 1, 2]), "D1 \n %r" %D + assert D == Matrix(G.parent(), 2, 2, [2, 1, 1, 2]), "D1 \n %r" % D elif mod(D.det(), 8) == 7: # in this case we can transform D to # 0 1 # 1 0 # Find a point representing 0 # solve: 0 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] - pol = (D[1,1]*x**2 + 2*D[1,0]*x + D[0,0])//2 + pol = (D[1, 1] * x**2 + 2 * D[1, 0] * x + D[0, 0]) // 2 # somehow else pari can get a hickup, see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] - B[0,:] += sol*B[1, :] + B[0, :] += sol * B[1, :] D = B * G * B.transpose() # make the second basis vector have 0 square as well. - B[1, :] = B[1, :] - D[1, 1]//(2*D[0, 1])*B[0,:] + B[1, :] = B[1, :] - D[1, 1] // (2 * D[0, 1]) * B[0, :] D = B * G * B.transpose() # rescale to get D[0,1] = 1 B[0, :] *= D[1, 0].inverse_of_unit() D = B * G * B.transpose() # check the result - assert D == Matrix(G.parent(), 2, 2, [0, 1, 1, 0]), "D2 \n %r" %D + assert D == Matrix(G.parent(), 2, 2, [0, 1, 1, 0]), "D2 \n %r" % D return B @@ -1000,19 +1005,20 @@ def _normalize_odd_2x2(G): [1 0] [0 1] """ - assert G[0,0]==G[1,1] - u = G[0,0] + assert G[0, 0] == G[1, 1] + u = G[0, 0] y = G.base_ring().zero() - while not (1/u-y**2).is_square(): - y = y + 1 - x = (1/u-y**2).sqrt() + while not (1 / u - y**2).is_square(): + y += 1 + x = (1 / u - y**2).sqrt() B = copy(G.parent().identity_matrix()) - B[0,0] = x - B[0,1] = y - B[1,0] = y - B[1,1] = -x + B[0, 0] = x + B[0, 1] = y + B[1, 0] = y + B[1, 1] = -x return B + def _partial_normal_form_of_block(G): r""" Return the partial normal form of the homogeneous block ``G``. @@ -1079,16 +1085,16 @@ def _partial_normal_form_of_block(G): V = [] W = [] for i in blocks: - if i+1 in blocks or i==n-1: + if i + 1 in blocks or i == n - 1: W.append(i) else: - if D[i,i] != 0: - V += [i,i+1] + if D[i, i] != 0: + V += [i, i + 1] else: - U += [i,i+1] + U += [i, i + 1] if len(W) == 3: # W W W transforms to W U or W V - B[W,:] = _relations(D[W,W],2) * B[W,:] + B[W, :] = _relations(D[W, W], 2) * B[W, :] D = B * G * B.T if mod(D[W[1:], W[1:]].det().unit_part(), 8) == 3: V += W[1:] @@ -1096,18 +1102,18 @@ def _partial_normal_form_of_block(G): U += W[1:] W = W[:1] if len(V) == 4: - B[V,:] = _relations(D[V,V],3) * B[V,:] + B[V, :] = _relations(D[V, V], 3) * B[V, :] U += V V = [] D = B * G * B.T # put everything into the right order UVW = U + V + W - B = B[UVW,:] + B = B[UVW, :] D = B * G * B.T return D, B, len(W) -def _relations(G,n): +def _relations(G, n): r""" Return relations of `2`-adic quadratic forms. @@ -1315,59 +1321,61 @@ def _relations(G,n): """ R = G.base_ring() if n == 1: - e1 = G[0,0].unit_part() - e2 = G[1,1].unit_part() - B = Matrix(R,2,[1,2,2*e2,-e1]) - if n == 2: - e1 = G[0,0].unit_part() - e2 = G[1,1].unit_part() - e3 = G[2,2].unit_part() - B = Matrix(R,3,[1,1,1,e2,-e1,0,e3,0,-e1]) - if n == 3: - B = Matrix(R,4,[1,1,1,0, 1,1,0,1, 1,0,-1,-1, 0,1,-1,-1]) - if n == 4: + e1 = G[0, 0].unit_part() + e2 = G[1, 1].unit_part() + B = Matrix(R, 2, 2, [1, 2, 2 * e2, -e1]) + elif n == 2: + e1 = G[0, 0].unit_part() + e2 = G[1, 1].unit_part() + e3 = G[2, 2].unit_part() + B = Matrix(R, 3, 3, [1, 1, 1, e2, -e1, 0, e3, 0, -e1]) + elif n == 3: + B = Matrix(R, 4, 4, + [1, 1, 1, 0, 1, 1, 0, 1, 1, 0, -1, -1, 0, 1, -1, -1]) + elif n == 4: raise NotImplementedError("relation 4 is not needed") - if n == 5: - e1 = G[2,2].unit_part() - e2 = G[3,3].unit_part() - if mod(e1,4) != mod(e2,4): + elif n == 5: + e1 = G[2, 2].unit_part() + e2 = G[3, 3].unit_part() + if mod(e1, 4) != mod(e2, 4): raise ValueError("W is of the wrong type for relation 5") - B = Matrix(R,4,[ 1, 0, 1, 1, - 0, 1, 1, 1, - -e2, -e2, 0, 3, - -e1, -e1, 2*e2 + 3, -2*e1]) - if n == 6: - if G[0,0].valuation()+1 != G[1,1].valuation(): + B = Matrix(R, 4, [1, 0, 1, 1, + 0, 1, 1, 1, + -e2, -e2, 0, 3, + -e1, -e1, 2 * e2 + 3, -2 * e1]) + elif n == 6: + if G[0, 0].valuation() + 1 != G[1, 1].valuation(): raise ValueError("wrong scales for relation 6") - e1 = G[0,0].unit_part() - e2 = G[1,1].unit_part() - B = Matrix(R,2,[1,1,-2*e2,e1]) - if n == 7: - e = G[0,0].unit_part() - B = Matrix(R,3,[-3, e**2, e**2, 2*e, 1, 0, 2*e, 0, 1]) - if n == 8: - e = G[2,2].unit_part() - if G[0,0]==0: - B = Matrix(R,3,[e, 0, -1, - 0, e, -1, - 2, 2, 1]) + e1 = G[0, 0].unit_part() + e2 = G[1, 1].unit_part() + B = Matrix(R, 2, 2, [1, 1, -2 * e2, e1]) + elif n == 7: + e = G[0, 0].unit_part() + B = Matrix(R, 3, 3, [-3, e**2, e**2, 2 * e, 1, 0, 2 * e, 0, 1]) + elif n == 8: + e = G[2, 2].unit_part() + if G[0, 0] == 0: + B = Matrix(R, 3, 3, [e, 0, -1, + 0, e, -1, + 2, 2, 1]) else: - B = Matrix(R,3,[ 1, 0, 1, - 0, 1, 1, - 2*e, 2*e, - 3]) - if n == 9: - e1 = G[0,0].unit_part() - e2 = G[1,1].unit_part() - e3 = G[2,2].unit_part() - B = Matrix(R,3,[1, 0, 1, - 2*e3, 1, - -e1, -2*e2*e3, 2*e1**2*e3 + 4*e1*e3**2, e1*e2]) - if n == 10: - e1 = G[0,0].unit_part() - e2 = G[1,1].unit_part() - B = Matrix(R,2,[1,1,-4*e2,e1]) - D, B1 = _normalize(B*G*B.T) - return B1*B + B = Matrix(R, 3, 3, [1, 0, 1, + 0, 1, 1, + 2 * e, 2 * e, - 3]) + elif n == 9: + e1 = G[0, 0].unit_part() + e2 = G[1, 1].unit_part() + e3 = G[2, 2].unit_part() + B = Matrix(R, 3, 3, [1, 0, 1, + 2 * e3, 1, -e1, + -2 * e2 * e3, 2 * e1**2 * e3 + 4 * e1 * e3**2, + e1 * e2]) + elif n == 10: + e1 = G[0, 0].unit_part() + e2 = G[1, 1].unit_part() + B = Matrix(R, 2, 2, [1, 1, -4 * e2, e1]) + D, B1 = _normalize(B * G * B.T) + return B1 * B def _two_adic_normal_forms(G, partial=False): @@ -1424,21 +1432,21 @@ def _two_adic_normal_forms(G, partial=False): # UVlist[k] is a list of indices of the block of scale p^k. # It contains the indices of the part of types U or V. # So it may be empty. - UVlist = [[],[]] # empty lists are appended to avoid special cases. + UVlist = [[], []] # empty lists are appended to avoid special cases. # same as UVlist but contains the indices of the part of type W - Wlist = [[],[]] + Wlist = [[], []] # homogeneous normal form for each part - for k in range(scales[-1] - scales[0]+1): - if k+scales[0] in scales: + for k in range(scales[-1] - scales[0] + 1): + if k + scales[0] in scales: i = scales.index(k + scales[0]) - Gk = G[h[i]:h[i+1], h[i]:h[i+1]] + Gk = G[h[i]:h[i + 1], h[i]:h[i + 1]] Dk, Bk, wk = _partial_normal_form_of_block(Gk) - B[h[i]:h[i+1],:] = Bk * B[h[i]:h[i+1], :] + B[h[i]:h[i + 1], :] = Bk * B[h[i]:h[i + 1], :] if not partial: Dk, B1k = _homogeneous_normal_form(Dk, wk) - B[h[i]:h[i+1],:] = B1k * B[h[i]:h[i+1], :] - UVlist.append(list(range(h[i], h[i+1] - wk))) - Wlist.append(list(range(h[i+1]-wk, h[i+1]))) + B[h[i]:h[i + 1], :] = B1k * B[h[i]:h[i + 1], :] + UVlist.append(list(range(h[i], h[i + 1] - wk))) + Wlist.append(list(range(h[i + 1] - wk, h[i + 1]))) else: UVlist.append([]) Wlist.append([]) @@ -1449,69 +1457,70 @@ def _two_adic_normal_forms(G, partial=False): # we never leave partial normal form # but the homogeneous normal form may be destroyed # it is restored at the end. - for k in range(len(UVlist)-1,2,-1): + for k in range(len(UVlist) - 1, 2, -1): # setup notation W = Wlist[k] - Wm = Wlist[k-1] - Wmm = Wlist[k-2] + Wm = Wlist[k - 1] + Wmm = Wlist[k - 2] UV = UVlist[k] - UVm = UVlist[k-1] + UVm = UVlist[k - 1] V = UVlist[k][-2:] - if len(V)!=0 and D[V[0], V[0]]==0: + if len(V) != 0 and D[V[0], V[0]] == 0: V = [] # it is U not V # condition b) if len(Wm) != 0: - if len(V)==2: + if len(V) == 2: R = Wm[:1] + V - B[R,:] = _relations(D[R,R],7) * B[R,:] + B[R, :] = _relations(D[R, R], 7) * B[R, :] V = [] D = B * G * B.T - E = {3,7} + E = {3, 7} for w in W: - if D[w,w].unit_part() in E: + if D[w, w].unit_part() in E: R = Wm[:1] + [w] - B[R,:] = _relations(D[R,R],6) * B[R,:] + B[R, :] = _relations(D[R, R], 6) * B[R, :] D = B * G * B.T # condition c) # We want type a or W = [] # modify D[w,w] to go from type b to type a - x = [len(V)] + [ZZ(mod(w.unit_part(),8)) for w in D[W,W].diagonal()] - if len(x)==3 and x[1]>x[2]: - x[1],x[2] = x[2], x[1] + x = [len(V)] + [ZZ(mod(w.unit_part(), 8)) for w in D[W, W].diagonal()] + if len(x) == 3 and x[1] > x[2]: + x[1], x[2] = x[2], x[1] # the first entry of x is either # 0 if there is no type V component or # 2 if there is a single type V component - # a = [[0,1], [2,3], [2,5], [0,7], [0,1,1], [2,1,3], [0,7,7], [0,1,7]] - b = [[0,5], [2,7], [2,1], [0,3], [0,1,5], [2,1,7], [0,3,7], [0,1,3]] + # a = [[0,1], [2,3], [2,5], [0,7], [0,1,1], [2,1,3], [0,7,7], [0,1,7]] + b = [[0, 5], [2, 7], [2, 1], [0, 3], + [0, 1, 5], [2, 1, 7], [0, 3, 7], [0, 1, 3]] if x in b: w = W[-1] - if x == [0,3,7]: + if x == [0, 3, 7]: # relation 10 should be applied to 3 to stay in homogeneous normal form w = W[0] if len(UVm) > 0: R = UVm[-2:] + [w] - B[R,:] = _relations(D[R,R],8) * B[R,:] + B[R, :] = _relations(D[R, R], 8) * B[R, :] elif len(Wmm) > 0: R = Wmm[:1] + [w] - B[R,:] = _relations(D[R,R],10) * B[R,:] + B[R, :] = _relations(D[R, R], 10) * B[R, :] elif len(Wm) == 2: - e0 = D[Wm,Wm][0,0].unit_part() - e1 = D[Wm,Wm][1,1].unit_part() - if mod(e1-e0,4) == 0: + e0 = D[Wm, Wm][0, 0].unit_part() + e1 = D[Wm, Wm][1, 1].unit_part() + if mod(e1 - e0, 4) == 0: R = Wm + [w] - B[R,:] = _relations(D[R,R],9) * B[R,:] + B[R, :] = _relations(D[R, R], 9) * B[R, :] D = B * G * B.T # condition a) - stay in homogeneous normal form R = UV + W - Dk = D[R,R] + Dk = D[R, R] Bk = _homogeneous_normal_form(Dk, len(W))[1] - B[R,:] = Bk * B[R,:] + B[R, :] = Bk * B[R, :] D = B * G * B.T # we need to restore the homogeneous normal form of k-1 - if len(Wm)>0: + if Wm: R = UVm + Wm - Dkm = D[R,R] + Dkm = D[R, R] Bkm = _homogeneous_normal_form(Dkm, len(Wm))[1] - B[R,:] = Bkm * B[R,:] + B[R, :] = Bkm * B[R, :] D = B * G * B.T return D, B From 94104462d5d78075dc37b6aeae3b14523bf91bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 11:44:20 +0200 Subject: [PATCH 288/350] minor details in schemes/ --- .../schemes/elliptic_curves/ell_generic.py | 18 +++---- src/sage/schemes/elliptic_curves/heegner.py | 37 ++++++------- .../hyperelliptic_curves/constructor.py | 38 +++++++------ src/sage/schemes/plane_conics/con_field.py | 53 +++++++++---------- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 926ae310ea8..154a581bc2a 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -1918,9 +1918,9 @@ def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evalu and x.lift().base_ring() is self.base_ring(): d = x.parent().modulus().degree() evaluate = m < 220 or \ - (d < 10 and m < 420) or (d < 15 and m < 340) or \ - (d < 30 and m < 280) or (d < 100 and m < 250) or \ - m <= min(250, d) + (d < 10 and m < 420) or (d < 15 and m < 340) or \ + (d < 30 and m < 280) or (d < 100 and m < 250) or \ + m <= min(250, d) # Check if we should (attempt to) compute the result by simply # evaluating a cached polynomial at the given input. @@ -2849,7 +2849,7 @@ def montgomery_model(self, twisted=False, morphism=False): return E, self.isomorphism_to(E) return E - P2, (x,y,z) = self.ambient_space().objgens() + P2, (x, y, z) = self.ambient_space().objgens() f = B * y**2*z - x * (x * (x + A*z) + z**2) C = plane_curve.ProjectivePlaneCurve(P2, f) @@ -2857,8 +2857,8 @@ def montgomery_model(self, twisted=False, morphism=False): return C t = ~(B * s).sqrt() - iso_maps = (x - r * z, t * y , s * z) - inv_maps = (x * s + r * z, s * y/t, z) + iso_maps = (x - r * z, t * y, s * z) + inv_maps = (x * s + r * z, s * y / t, z) w = self.isomorphism_to(Ew) wmap, winv = w.rational_maps(), (~w).rational_maps() @@ -2868,7 +2868,7 @@ def montgomery_model(self, twisted=False, morphism=False): inv = [f(*inv_maps) for f in winv] from sage.schemes.elliptic_curves.weierstrass_transform \ - import WeierstrassTransformationWithInverse as WTI + import WeierstrassTransformationWithInverse as WTI iso = WTI(self, C, iso, 1, inv, s**-3) return C, iso @@ -3194,7 +3194,7 @@ def _p_primary_torsion_basis(self, p, m=None): k = 1 log_order = 2 if m <= log_order: - return [[P1,1],[P2,1]] + return [[P1, 1], [P2, 1]] pts1 = P1.division_points(p) pts2 = P2.division_points(p) @@ -3255,7 +3255,7 @@ def _p_primary_torsion_basis(self, p, m=None): return [[P1, n], [P2, k]] pts = P1.division_points(p) if not pts: - for Q in generic.multiples(P2,p-1,P1+P2,operation='+'): + for Q in generic.multiples(P2, p-1, P1+P2, operation='+'): # Q runs through P1+a*P2 for a=1,2,...,p-1 pts = Q.division_points(p) if pts: diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index 2b699fd6cf8..298f44fedc6 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -117,7 +117,7 @@ from sage.modular.modsym.p1list import P1List -################################################################################## +############################################################################### # # The exported functions, which are in most cases enough to get the # user going working with Heegner points: @@ -125,7 +125,7 @@ # heegner_points -- all of them with given level, discriminant, conductor # heegner_point -- a specific one # -################################################################################## +############################################################################### def heegner_points(N, D=None, c=None): """ @@ -135,11 +135,11 @@ def heegner_points(N, D=None, c=None): INPUT: - - `N` -- level (positive integer) + - `N` -- level (positive integer) - - `D` -- discriminant (negative integer) + - `D` -- discriminant (negative integer) - - `c` -- conductor (positive integer) + - `c` -- conductor (positive integer) EXAMPLES:: @@ -155,9 +155,10 @@ def heegner_points(N, D=None, c=None): if D is not None and c is None: return HeegnerPoints_level_disc(N, D) if D is not None and c is not None: - return HeegnerPoints_level_disc_cond(N,D,c) + return HeegnerPoints_level_disc_cond(N, D, c) raise TypeError + def heegner_point(N, D=None, c=1): """ Return a specific Heegner point of level `N` with given @@ -167,11 +168,11 @@ def heegner_point(N, D=None, c=1): INPUT: - - `N` -- level (positive integer) + - `N` -- level (positive integer) - - `D` -- discriminant (optional: default first valid `D`) + - `D` -- discriminant (optional: default first valid `D`) - - `c` -- conductor (positive integer, optional, default: 1) + - `c` -- conductor (positive integer, optional, default: 1) EXAMPLES:: @@ -185,20 +186,20 @@ def heegner_point(N, D=None, c=1): Heegner point 1/778*sqrt(-20) - 165/389 of discriminant -20 on X_0(389) """ if D is not None: - return heegner_points(N,D,c)[0] + return heegner_points(N, D, c)[0] H = heegner_points(N) D = H.discriminants(1)[0] - return heegner_points(N,D,c)[0] + return heegner_points(N, D, c)[0] -################################################################################## +############################################################################### # # Ring class fields, represented as abstract objects. These do not # derive from number fields, since we do not need to work with their # elements, and explicitly representing them as number fields would be # far too difficult. # -################################################################################## +############################################################################### class RingClassField(SageObject): """ @@ -352,9 +353,8 @@ def _repr_(self): """ c = self.__c if c == 1: - return "Hilbert class field of QQ[sqrt(%s)]"%self.__D - else: - return "Ring class field extension of QQ[sqrt(%s)] of conductor %s"%(self.__D, self.__c) + return "Hilbert class field of QQ[sqrt(%s)]" % self.__D + return "Ring class field extension of QQ[sqrt(%s)] of conductor %s" % (self.__D, self.__c) @cached_method def degree_over_K(self): @@ -6533,7 +6533,8 @@ def heegner_point_height(self, D, prec=2, check_rank=True): return IR(alpha-MIN_ERR,alpha+MIN_ERR) * IR(LE1-err_E,LE1+err_E) * IR(LF1-err_F,LF1+err_F) -def heegner_index(self, D, min_p=2, prec=5, descent_second_limit=12, verbose_mwrank=False, check_rank=True): +def heegner_index(self, D, min_p=2, prec=5, descent_second_limit=12, + verbose_mwrank=False, check_rank=True): r""" Return an interval that contains the index of the Heegner point `y_K` in the group of `K`-rational points modulo torsion @@ -6745,7 +6746,7 @@ def _adjust_heegner_index(self, a): return a.sqrt() -def heegner_index_bound(self, D=0, prec=5, max_height=None): +def heegner_index_bound(self, D=0, prec=5, max_height=None): r""" Assume ``self`` has rank 0. diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index 5aa3ad0abd4..54556e08755 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -6,15 +6,13 @@ - David Kohel (2006): initial version - Anna Somoza (2019-04): dynamic class creation - """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 David Kohel # 2019 Anna Somoza # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.schemes.projective.projective_space import ProjectiveSpace @@ -31,6 +29,7 @@ from sage.structure.dynamic_class import dynamic_class + def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): r""" Returns the hyperelliptic curve `y^2 + h y = f`, for @@ -216,40 +215,39 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): if P(2) == 0: # characteristic 2 if h == 0: - raise ValueError("In characteristic 2, argument h (= %s) must be non-zero."%h) + raise ValueError("In characteristic 2, argument h (= %s) must be non-zero." % h) if h[g+1] == 0 and f[2*g+1]**2 == f[2*g+2]*h[g]**2: - raise ValueError("Not a hyperelliptic curve: " \ - "highly singular at infinity.") + raise ValueError("Not a hyperelliptic curve: " + "highly singular at infinity.") should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2] else: # characteristic not 2 if not F.degree() in [2*g+1, 2*g+2]: - raise ValueError("Not a hyperelliptic curve: " \ - "highly singular at infinity.") + raise ValueError("Not a hyperelliptic curve: " + "highly singular at infinity.") should_be_coprime = [F, F.derivative()] try: - smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree()==0 + smooth = should_be_coprime[0].gcd(should_be_coprime[1]).degree() == 0 except (AttributeError, NotImplementedError, TypeError): try: - smooth = should_be_coprime[0].resultant(should_be_coprime[1])!=0 + smooth = should_be_coprime[0].resultant(should_be_coprime[1]) != 0 except (AttributeError, NotImplementedError, TypeError): - raise NotImplementedError("Cannot determine whether " \ - "polynomials %s have a common root. Use " \ - "check_squarefree=False to skip this check." % \ + raise NotImplementedError("Cannot determine whether " + "polynomials %s have a common root. Use " + "check_squarefree=False to skip this check." % should_be_coprime) if not smooth: - raise ValueError("Not a hyperelliptic curve: " \ - "singularity in the provided affine patch.") + raise ValueError("Not a hyperelliptic curve: " + "singularity in the provided affine patch.") R = P.base_ring() PP = ProjectiveSpace(2, R) if names is None: - names = ["x","y"] + names = ["x", "y"] superclass = [] cls_name = ["HyperellipticCurve"] - genus_classes = { - 2 : HyperellipticCurve_g2} + genus_classes = {2: HyperellipticCurve_g2} is_pAdicField = lambda x: isinstance(x, sage.rings.abc.pAdicField) diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index 05022c45113..117bc1c0daa 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -40,6 +40,7 @@ from sage.categories.fields import Fields _Fields = Fields() + class ProjectiveConic_field(ProjectivePlaneCurve_field): r""" Create a projective plane conic curve over a field. @@ -113,10 +114,10 @@ def base_extend(self, S): if B == S: return self if not S.has_coerce_map_from(B): - raise ValueError("No natural map from the base ring of self " \ + raise ValueError("No natural map from the base ring of self " "(= %s) to S (= %s)" % (self, S)) from .constructor import Conic - con = Conic([S(c) for c in self.coefficients()], \ + con = Conic([S(c) for c in self.coefficients()], self.variable_names()) if self._rational_point is not None: pt = [S(c) for c in Sequence(self._rational_point)] @@ -188,9 +189,7 @@ def derivative_matrix(self): [1 2 1] [1 1 0] - An example in characteristic `2`: - - :: + An example in characteristic `2`:: sage: P. = GF(2)[] sage: c = Conic([t, 1, t^2, 1, 1, 0]); c @@ -203,9 +202,9 @@ def derivative_matrix(self): [t^2 1 0] """ a, b, c, d, e, f = self.coefficients() - return Matrix([[ 2*a , b , c ], - [ b , 2*d , e ], - [ c , e , 2*f ]]) + return Matrix([[2 * a, b, c], + [b, 2 * d, e], + [c, e, 2 * f]]) def determinant(self): r""" @@ -497,8 +496,8 @@ def has_rational_point(self, point=False, # writing) fraction field elements are not converted automatically # from Magma to Sage. try: - return True, self.point( \ - [B(c.Numerator().sage()/c.Denominator().sage()) for c in pt]) + return True, self.point( + [B(c.Numerator().sage() / c.Denominator().sage()) for c in pt]) except (TypeError, NameError): pass @@ -539,8 +538,8 @@ def has_rational_point(self, point=False, if point: return ret return ret[0] - raise NotImplementedError("has_rational_point not implemented for " \ - "conics over base field %s" % B) + raise NotImplementedError("has_rational_point not implemented for " + "conics over base field %s" % B) def has_singular_point(self, point=False): r""" @@ -693,8 +692,8 @@ def hom(self, x, Y=None): if Y is None: Y = im elif not Y == im: - raise ValueError("The matrix x (= %s) does not define a " \ - "map from self (= %s) to Y (= %s)" % \ + raise ValueError("The matrix x (= %s) does not define a " + "map from self (= %s) to Y (= %s)" % (x, self, Y)) x = Sequence(x*vector(self.ambient_space().gens())) return self.Hom(Y)(x, check=False) @@ -1120,12 +1119,12 @@ def rational_point(self, algorithm='default', read_cache=True): ... ValueError: Conic Projective Conic Curve over Real Field with 53 bits of precision defined by x^2 + y^2 + z^2 has no rational points over Real Field with 53 bits of precision! """ - bl,pt = self.has_rational_point(point=True, algorithm=algorithm, - read_cache=read_cache) + bl, pt = self.has_rational_point(point=True, algorithm=algorithm, + read_cache=read_cache) if bl: return pt - raise ValueError("Conic %s has no rational points over %s!" % \ - (self, self.ambient_space().base_ring())) + raise ValueError("Conic %s has no rational points over %s!" % + (self, self.ambient_space().base_ring())) def singular_point(self): r""" @@ -1149,8 +1148,8 @@ def singular_point(self): """ b = self.has_singular_point(point=True) if not b[0]: - raise ValueError("The conic self (= %s) has no rational " \ - "singular point" % self) + raise ValueError("The conic self (= %s) has no rational " + "singular point" % self) return b[1] def symmetric_matrix(self): @@ -1175,13 +1174,13 @@ def symmetric_matrix(self): a, b, c, d, e, f = self.coefficients() if self.base_ring().characteristic() == 2: if b == 0 and c == 0 and e == 0: - return Matrix([[a,0,0],[0,d,0],[0,0,f]]) - raise ValueError("The conic self (= %s) has no symmetric matrix " \ - "because the base field has characteristic 2" % \ - self) - return Matrix([[ a , b/2, c/2 ], - [ b/2, d , e/2 ], - [ c/2, e/2, f ]]) + return Matrix([[a, 0, 0], [0, d, 0], [0, 0, f]]) + raise ValueError("The conic self (= %s) has no symmetric matrix " + "because the base field has characteristic 2" % + self) + return Matrix([[a, b / 2, c / 2], + [b / 2, d, e / 2], + [c / 2, e / 2, f]]) def upper_triangular_matrix(self): r""" From 47a089da18197117af8e946659facd5702f942f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 12:26:01 +0200 Subject: [PATCH 289/350] fix more W605 in rings/ --- src/sage/rings/complex_arb.pyx | 4 +-- src/sage/rings/complex_double.pyx | 2 +- src/sage/rings/complex_mpc.pyx | 48 +++++++++++++++---------------- src/sage/rings/complex_mpfr.pyx | 2 +- src/sage/rings/integer.pyx | 11 +++---- src/sage/rings/real_arb.pyx | 18 ++++++------ 6 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index 62841a9f8d6..797f5122d40 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -2984,7 +2984,7 @@ cdef class ComplexBall(RingElement): return res def rising_factorial(self, n): - """ + r""" Return the ``n``-th rising factorial of this ball. The `n`-th rising factorial of `x` is equal to `x (x+1) \cdots (x+n-1)`. @@ -3704,7 +3704,7 @@ cdef class ComplexBall(RingElement): return res def polylog(self, s): - """ + r""" Return the polylogarithm `\operatorname{Li}_s(\mathrm{self})`. EXAMPLES:: diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 5cd5cb1910f..f0c70c67f82 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -1637,7 +1637,7 @@ cdef class ComplexDoubleElement(FieldElement): return self.real().is_NaN() or self.imag().is_NaN() cpdef _pow_(self, other): - """ + r""" The complex number ``self`` raised to the power ``other``. This is computed using complex logarithms and exponentials diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 49109af92c6..2a5e3048fbc 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -137,15 +137,15 @@ cdef inline mpfr_rnd_t rnd_im(mpc_rnd_t rnd): sign = '[+-]' digit_ten = '[0123456789]' exponent_ten = '[e@]' + sign + '?[0123456789]+' -number_ten = 'inf(?:inity)?|@inf@|nan(?:\([0-9A-Z_]*\))?|@nan@(?:\([0-9A-Z_]*\))?'\ - '|(?:' + digit_ten + '*\.' + digit_ten + '+|' + digit_ten + '+\.?)(?:' + exponent_ten + ')?' -imaginary_ten = 'i(?:\s*\*\s*(?:' + number_ten + '))?|(?:' + number_ten + ')\s*\*\s*i' -complex_ten = '(?P(?P' + sign + ')?\s*(?P' + imaginary_ten + ')' \ - '(\s*(?P' + sign + ')\s*(?P' + number_ten + '))?)' \ +number_ten = r'inf(?:inity)?|@inf@|nan(?:\([0-9A-Z_]*\))?|@nan@(?:\([0-9A-Z_]*\))?'\ + '|(?:' + digit_ten + r'*\.' + digit_ten + '+|' + digit_ten + r'+\.?)(?:' + exponent_ten + ')?' +imaginary_ten = r'i(?:\s*\*\s*(?:' + number_ten + '))?|(?:' + number_ten + r')\s*\*\s*i' +complex_ten = '(?P(?P' + sign + r')?\s*(?P' + imaginary_ten + r')' \ + r'(\s*(?P' + sign + r')\s*(?P' + number_ten + '))?)' \ '|' \ - '(?P(?P' + sign + ')?\s*(?P' + number_ten + ')' \ - '(\s*(?P' + sign + ')\s*(?P' + imaginary_ten + '))?)' -re_complex_ten = re.compile('^\s*(?:' + complex_ten + ')\s*$', re.I) + '(?P(?P' + sign + r')?\s*(?P' + number_ten + r')' \ + r'(\s*(?P' + sign + r')\s*(?P' + imaginary_ten + '))?)' +re_complex_ten = re.compile(r'^\s*(?:' + complex_ten + r')\s*$', re.I) cpdef inline split_complex_string(string, int base=10): """ @@ -185,17 +185,17 @@ cpdef inline split_complex_string(string, int base=10): # Warning: number, imaginary, and complex should be enclosed in parentheses # when used as regexp because of alternatives '|' - number = '@nan@(?:\([0-9A-Z_]*\))?|@inf@|(?:' + digit + '*\.' + digit + '+|' + digit + '+\.?)(?:' + exponent + ')?' + number = r'@nan@(?:\([0-9A-Z_]*\))?|@inf@|(?:' + digit + r'*\.' + digit + '+|' + digit + r'+\.?)(?:' + exponent + ')?' if base <= 10: - number = 'nan(?:\([0-9A-Z_]*\))?|inf(?:inity)?|' + number - imaginary = 'i(?:\s*\*\s*(?:' + number + '))?|(?:' + number + ')\s*\*\s*i' - complex = '(?P(?P' + sign + ')?\s*(?P' + imaginary + ')' \ - '(\s*(?P' + sign + ')\s*(?P' + number + '))?)' \ + number = r'nan(?:\([0-9A-Z_]*\))?|inf(?:inity)?|' + number + imaginary = r'i(?:\s*\*\s*(?:' + number + '))?|(?:' + number + r')\s*\*\s*i' + complex = '(?P(?P' + sign + r')?\s*(?P' + imaginary + r')' \ + r'(\s*(?P' + sign + r')\s*(?P' + number + '))?)' \ '|' \ - '(?P(?P' + sign + ')?\s*(?P' + number + ')' \ - '(\s*(?P' + sign + ')\s*(?P' + imaginary + '))?)' + '(?P(?P' + sign + r')?\s*(?P' + number + r')' \ + r'(\s*(?P' + sign + r')\s*(?P' + imaginary + '))?)' - z = re.match('^\s*(?:' + complex + ')\s*$', string, re.I) + z = re.match(r'^\s*(?:' + complex + r')\s*$', string, re.I) x, y = None, None if z is not None: @@ -207,18 +207,18 @@ cpdef inline split_complex_string(string, int base=10): return None if z.group(prefix + '_re_abs') is not None: - x = z.expand('\g<' + prefix + '_re_abs>') + x = z.expand(r'\g<' + prefix + '_re_abs>') if z.group(prefix + '_re_sign') is not None: - x = z.expand('\g<' + prefix + '_re_sign>') + x + x = z.expand(r'\g<' + prefix + '_re_sign>') + x if z.group(prefix + '_im_abs') is not None: - y = re.search('(?P' + number + ')', z.expand('\g<' + prefix + '_im_abs>'), re.I) + y = re.search('(?P' + number + ')', z.expand(r'\g<' + prefix + '_im_abs>'), re.I) if y is None: y = '1' else: - y = y.expand('\g') + y = y.expand(r'\g') if z.group(prefix + '_im_sign') is not None: - y = z.expand('\g<' + prefix + '_im_sign>') + y + y = z.expand(r'\g<' + prefix + '_im_sign>') + y return x, y @@ -1701,7 +1701,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): return z def cosh(self): - """ + r""" Return the hyperbolic cosine of this complex number: .. MATH:: @@ -1721,7 +1721,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): return z def sinh(self): - """ + r""" Return the hyperbolic sine of this complex number: .. MATH:: @@ -2063,7 +2063,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): return z def exp(self): - """ + r""" Return the exponential of this complex number: .. MATH:: diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 21b32326aa3..5083f66a89d 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -2549,7 +2549,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): # Other special functions def agm(self, right, algorithm="optimal"): - """ + r""" Return the Arithmetic-Geometric Mean (AGM) of ``self`` and ``right``. INPUT: diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 00b490ecb00..0312f3f99fb 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -1257,7 +1257,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return self.str(2) def bits(self): - """ + r""" Return the bits in self as a list, least significant first. The result satisfies the identity @@ -2434,7 +2434,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): integer_ring.ZZ(n).ordinal_str())) cpdef size_t _exact_log_log2_iter(self,Integer m): - """ + r""" This is only for internal use only. You should expect it to crash and burn for negative or other malformed input. In particular, if the base `2 \leq m < 4` the log2 approximation of m is 1 and certain @@ -3463,7 +3463,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return q, r def powermod(self, exp, mod): - """ + r""" Compute self\*\*exp modulo mod. EXAMPLES:: @@ -6714,8 +6714,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise ArithmeticError("inverse does not exist") def inverse_mod(self, n): - """ - Returns the inverse of self modulo `n`, if this inverse exists. + r""" + Return the inverse of self modulo `n`, if this inverse exists. + Otherwise, raises a ``ZeroDivisionError`` exception. INPUT: diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 4fc1de6cce8..23a41c2bf6a 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -238,7 +238,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.cpython.string cimport char_to_str, str_to_bytes cdef void mpfi_to_arb(arb_t target, const mpfi_t source, const long precision): - """ + r""" Convert an MPFI interval to an Arb ball. INPUT: @@ -282,7 +282,7 @@ cdef void mpfi_to_arb(arb_t target, const mpfi_t source, const long precision): mpfr_clear(right) cdef int arb_to_mpfi(mpfi_t target, arb_t source, const long precision) except -1: - """ + r""" Convert an Arb ball to an MPFI interval. INPUT: @@ -798,7 +798,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): # Ball functions of non-ball arguments def sinpi(self, x): - """ + r""" Return a ball enclosing `\sin(\pi x)`. This works even if ``x`` itself is not a ball, and may be faster or @@ -844,7 +844,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): return res def cospi(self, x): - """ + r""" Return a ball enclosing `\cos(\pi x)`. This works even if ``x`` itself is not a ball, and may be faster or @@ -2986,7 +2986,7 @@ cdef class RealBall(RingElement): return res def sqrt1pm1(self): - """ + r""" Return `\sqrt{1+\mathrm{self}}-1`, computed accurately when ``self`` is close to zero. @@ -3728,7 +3728,7 @@ cdef class RealBall(RingElement): return res def gamma(self, a=None): - """ + r""" Image of this ball by the (upper incomplete) Euler Gamma function For `a` real, return the upper incomplete Gamma function @@ -3770,7 +3770,7 @@ cdef class RealBall(RingElement): gamma_inc = gamma def gamma_inc_lower(self, a): - """ + r""" Image of this ball by the lower incomplete Euler Gamma function For `a` real, return the lower incomplete Gamma function @@ -3828,7 +3828,7 @@ cdef class RealBall(RingElement): return res def rising_factorial(self, n): - """ + r""" Return the ``n``-th rising factorial of this ball. The `n`-th rising factorial of `x` is equal to `x (x+1) \cdots (x+n-1)`. @@ -3934,7 +3934,7 @@ cdef class RealBall(RingElement): return res def polylog(self, s): - """ + r""" Return the polylogarithm `\operatorname{Li}_s(\mathrm{self})`. EXAMPLES:: From 48ba8d0b9eb4373cd288418f4cfbfbf871695fc3 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 10 Oct 2022 11:27:55 +0900 Subject: [PATCH 290/350] Add sage_docbuild/ext/* files to doc --- src/doc/en/reference/documentation/index.rst | 13 ++++ src/doc/en/reference/index.rst | 14 ++-- src/sage_docbuild/ext/multidocs.py | 70 ++++++++++---------- src/sage_docbuild/ext/sage_autodoc.py | 13 ++-- 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/doc/en/reference/documentation/index.rst b/src/doc/en/reference/documentation/index.rst index 13d17594db3..4a96c47ed8c 100644 --- a/src/doc/en/reference/documentation/index.rst +++ b/src/doc/en/reference/documentation/index.rst @@ -1,6 +1,9 @@ Documentation System ==================== +Sage Doc Builders +----------------- + .. toctree:: :maxdepth: 1 @@ -10,3 +13,13 @@ Documentation System sage_docbuild/sphinxbuild sage_docbuild/conf sage_docbuild/utils + +Sphinx Extensions +----------------- + +.. toctree:: + :maxdepth: 1 + + sage_docbuild/ext/inventory_builder + sage_docbuild/ext/sage_autodoc + sage_docbuild/ext/multidocs diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index 9008c78e157..144b57760bc 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -143,23 +143,23 @@ Miscellaneous * :doc:`Databases ` * :doc:`Games ` -Programming -=========== +Infrastructure +============== -Facilities ----------- +Programming Facilities +---------------------- * :doc:`Data Structures ` * :doc:`Utilities ` * :doc:`Test Framework ` * :doc:`Parallel Computing ` +* :doc:`Python Technicalities ` -Interfaces ----------- +Subsystem Interfaces +-------------------- * :doc:`Interpreter Interfaces ` * :doc:`C/C++ Library Interfaces ` -* :doc:`Python Technicalities ` Documentation System -------------------- diff --git a/src/sage_docbuild/ext/multidocs.py b/src/sage_docbuild/ext/multidocs.py index 39121ef90ac..13187654090 100644 --- a/src/sage_docbuild/ext/multidocs.py +++ b/src/sage_docbuild/ext/multidocs.py @@ -1,24 +1,24 @@ # -*- coding: utf-8 -*- """ - multi documentation in Sphinx - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - The goal of this extension is to manage a multi documentation in Sphinx. - To be able to compile Sage's huge documentation in parallel, the - documentation is cut into a bunch of independent documentations called - "subdocs", which are compiled separately. There is a master document which - points to all the subdocs. The intersphinx extension ensures that the - cross-link between the subdocs are correctly resolved. However some work - is needed to build a global index. This is the goal of multidocs. - - More precisely this extension ensures the correct merging of - - the todo list if this extension is activated; - - the python indexes; - - the list of python modules; - - the javascript index; - - the citations. -""" +Sage multidocs extension + +The goal of this extension is to manage a multi-documentation in Sphinx. To be +able to compile Sage's huge documentation in parallel, the documentation is cut +into a bunch of independent documentations called "sub-docs", which are +compiled separately. There is a master document which points to all the +sub-docs. The intersphinx extension ensures that the cross-link between the +sub-docs are correctly resolved. However some work is needed to build a global +index. This is the goal of the ``multidocs`` extension. + +More precisely this extension ensures the correct merging of + +- the todo list if this extension is activated +- the python indexes +- the list of python modules +- the javascript index +- the citations +""" import os import pickle import shutil @@ -35,15 +35,15 @@ def merge_environment(app, env): """ - Merges the following attributes of the sub-docs environment into the main + Merge the following attributes of the sub-docs environment into the main environment: - - titles # Titles - - todo_all_todos # ToDo's - - indexentries # global python index - - all_docs # needed by the js index - - citations # citations - - domaindata['py']['modules'] # list of python modules + - ``titles`` -- Titles + - ``todo_all_todos`` -- todo's + - ``indexentries`` -- global python index + - ``all_docs`` -- needed by the js index + - ``citations`` -- citations + - ``domaindata['py']['modules']`` -- list of python modules """ logger.info(bold('Merging environment/index files...')) for curdoc in app.env.config.multidocs_subdoc_list: @@ -81,7 +81,7 @@ def merge_environment(app, env): env.all_docs.update(newalldoc) # needed by env.check_consistency (sphinx.environment, line 1734) for ind in newalldoc: - # treat subdocument source as orphaned file and don't complain + # treat sub-document source as orphaned file and don't complain md = env.metadata.get(ind, dict()) md['orphan'] = 1 env.metadata[ind] = md @@ -192,14 +192,14 @@ def get_js_index(app, curdoc): def fix_path_html(app, pagename, templatename, ctx, event_arg): """ - Fixes the context so that the files - - search.html - - genindex.html - - py-modindex.html - point to the right place, that is in - reference/ - instead of - reference/subdocument + Fix the context so that the files + + - :file:`search.html` + - :file:`genindex.html` + - :file:`py-modindex.html` + + point to the right place, that is in :file:`reference/` instead of + :file:`reference/subdocument`. """ # sphinx/builder/html.py line 702 # def pathto(otheruri, resource=False, @@ -265,7 +265,7 @@ def fetch_citation(app: Sphinx, env): def init_subdoc(app): """ - Init the merger depending on if we are compiling a subdoc or the master + Init the merger depending on if we are compiling a sub-doc or the master doc itself. """ if app.config.multidocs_is_master: diff --git a/src/sage_docbuild/ext/sage_autodoc.py b/src/sage_docbuild/ext/sage_autodoc.py index 5b97b272718..0d15eec91a2 100644 --- a/src/sage_docbuild/ext/sage_autodoc.py +++ b/src/sage_docbuild/ext/sage_autodoc.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- """ -Sage autodoc extension based on sphinx.ext.autodoc from Sphinx +Sage autodoc extension -From sphinx.ext.autodoc: +This is based on :mod:`sphinx.ext.autodoc` from Sphinx. + +From :mod:`sphinx.ext.autodoc`: Automatically insert docstrings for functions, classes or whole modules into the doctree, thus avoiding duplication between docstrings and documentation @@ -23,7 +25,7 @@ - Simon King (2011-04): use sageinspect; include public cython attributes only in the documentation if they have a docstring -- Kwankyu Lee (2018-12-26): rebase on the latest sphinx.ext.autodoc +- Kwankyu Lee (2018-12-26): rebased on the latest sphinx.ext.autodoc """ @@ -64,7 +66,7 @@ MethodDescriptorType = type(type.__subclasses__) -#: extended signature RE: with explicit module name separated by :: +# extended signature RE: with explicit module name separated by ``::`` py_ext_sig_re = re.compile( r'''^ ([\w.]+::)? # explicit module name ([\w.]+\.)? # module and/or class name(s) @@ -192,7 +194,8 @@ def cut_lines(pre, post=0, what=None): from sphinx.ext.autodoc import cut_lines app.connect('autodoc-process-docstring', cut_lines(4, what=['module'])) - This can (and should) be used in place of :confval:`automodule_skip_lines`. + This can (and should) be used in place of ``automodule_skip_lines`` (config + value defined in Sphinx autodoc). """ def process(app, what_, name, obj, options, lines): # type: (Sphinx, unicode, unicode, Any, Any, List[unicode]) -> None From 16fd967e51813ef97c7f9da6eee35ade6c5857de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 21:17:05 +0200 Subject: [PATCH 291/350] some details in permutation groups --- src/sage/groups/perm_gps/all.py | 19 ++++++---- src/sage/groups/perm_gps/constructor.py | 15 +++++--- .../perm_gps/partn_ref/refinement_graphs.pyx | 8 ++-- .../groups/perm_gps/permgroup_morphism.py | 38 +++++++++++-------- .../perm_gps/permutation_groups_catalog.py | 2 +- .../groups/perm_gps/symgp_conjugacy_class.py | 14 ++++--- 6 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/sage/groups/perm_gps/all.py b/src/sage/groups/perm_gps/all.py index 999f0bbfb2c..83afad7c691 100644 --- a/src/sage/groups/perm_gps/all.py +++ b/src/sage/groups/perm_gps/all.py @@ -1,17 +1,20 @@ from .permgroup_named import (SymmetricGroup, AlternatingGroup, - DihedralGroup, SplitMetacyclicGroup, SemidihedralGroup, CyclicPermutationGroup, - DiCyclicGroup, TransitiveGroup, PGL, PSL, PSp,PSU,PGU, - MathieuGroup, KleinFourGroup, QuaternionGroup, - PrimitiveGroup, PrimitiveGroups, - SuzukiGroup, TransitiveGroups, GeneralDihedralGroup) + DihedralGroup, SplitMetacyclicGroup, + SemidihedralGroup, CyclicPermutationGroup, + DiCyclicGroup, TransitiveGroup, + PGL, PSL, PSp, PSU, PGU, + MathieuGroup, KleinFourGroup, QuaternionGroup, + PrimitiveGroup, PrimitiveGroups, + SuzukiGroup, TransitiveGroups, + GeneralDihedralGroup) -from .permgroup import PermutationGroup, PermutationGroup_generic, PermutationGroup_subgroup, direct_product_permgroups +from .permgroup import PermutationGroup, PermutationGroup_generic, PermutationGroup_subgroup, direct_product_permgroups from .constructor import PermutationGroupElement from .permgroup_morphism import (PermutationGroupMorphism as PermutationGroupMap, - PermutationGroupMorphism_im_gens, - PermutationGroupMorphism_id) + PermutationGroupMorphism_im_gens, + PermutationGroupMorphism_id) PermutationGroupMorphism = PermutationGroupMorphism_im_gens from .cubegroup import CubeGroup, RubiksCube diff --git a/src/sage/groups/perm_gps/constructor.py b/src/sage/groups/perm_gps/constructor.py index 1992679efd3..73dc5f94c41 100644 --- a/src/sage/groups/perm_gps/constructor.py +++ b/src/sage/groups/perm_gps/constructor.py @@ -7,7 +7,7 @@ objects have a more group theoretic flavor than the more combinatorial :class:`~sage.combinat.permutation.Permutation`. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 William Stein # Copyright (C) 2006 David Joyner # Copyright (C) 2019 Vincent Delecroix <20100.delecroix@gmail.com> @@ -16,16 +16,17 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from . import permgroup_element from sage.misc.sage_eval import sage_eval from sage.misc.lazy_import import lazy_import from sage.interfaces.gap import GapElement -lazy_import('sage.combinat.permutation', ['Permutation', 'from_cycles']) from sage.libs.pari.all import pari_gen from sage.libs.gap.element import GapElement_Permutation +lazy_import('sage.combinat.permutation', ['Permutation', 'from_cycles']) + def PermutationGroupElement(g, parent=None, check=True): r""" @@ -118,6 +119,7 @@ def PermutationGroupElement(g, parent=None, check=True): return parent.element_class(g, parent, check) + def string_to_tuples(g): """ EXAMPLES:: @@ -136,10 +138,11 @@ def string_to_tuples(g): raise ValueError("g (= %s) must be a string" % g) elif g == '()': return [] - g = g.replace('\n','').replace(' ', '').replace(')(', '),(').replace(')', ',)') + g = g.replace('\n', '').replace(' ', '').replace(')(', '),(').replace(')', ',)') g = '[' + g + ']' return sage_eval(g, preparse=False) + def standardize_generator(g, convert_dict=None, as_cycles=False): r""" Standardize the input for permutation group elements to a list @@ -258,6 +261,6 @@ def standardize_generator(g, convert_dict=None, as_cycles=False): if convert_dict is not None and needs_conversion: g = [tuple([convert_dict[x] for x in cycle]) for cycle in g] if not as_cycles: - degree = max([1] + [max(cycle+(1,)) for cycle in g]) + degree = max([1] + [max(cycle + (1,)) for cycle in g]) g = from_cycles(degree, g) return g diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx index 4ab08bd6ba7..1acb46201a0 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx @@ -7,10 +7,9 @@ EXAMPLES:: REFERENCE: -- [1] McKay, Brendan D. Practical Graph Isomorphism. Congressus Numerantium, +- [1] McKay, Brendan D. *Practical Graph Isomorphism*. Congressus Numerantium, Vol. 30 (1981), pp. 45-87. """ - # **************************************************************************** # Copyright (C) 2006 - 2011 Robert L. Miller # @@ -643,9 +642,8 @@ cdef int compare_graphs(int *gamma_1, int *gamma_2, void *S1, void *S2, int degr r""" Compare gamma_1(S1) and gamma_2(S2). - Return return -1 if gamma_1(S1) < gamma_2(S2), 0 if gamma_1(S1) == - gamma_2(S2), 1 if gamma_1(S1) > gamma_2(S2). (Just like the python - \code{cmp}) function. + Return -1 if gamma_1(S1) < gamma_2(S2), 0 if gamma_1(S1) == + gamma_2(S2), 1 if gamma_1(S1) > gamma_2(S2). INPUT: diff --git a/src/sage/groups/perm_gps/permgroup_morphism.py b/src/sage/groups/perm_gps/permgroup_morphism.py index d190df81614..917ddd01865 100644 --- a/src/sage/groups/perm_gps/permgroup_morphism.py +++ b/src/sage/groups/perm_gps/permgroup_morphism.py @@ -30,24 +30,26 @@ Cyclic group of order 4 as a permutation group """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 David Joyner and William Stein # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.categories.morphism import Morphism from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic + class PermutationGroupMorphism(Morphism): """ A set-theoretic map between PermutationGroups. """ def _repr_type(self): """ - Returns the type of this morphism. This is used for printing - the morphism. + Return the type of this morphism. + + This is used for printing the morphism. EXAMPLES:: @@ -60,7 +62,7 @@ def _repr_type(self): def kernel(self): """ - Returns the kernel of this homomorphism as a permutation group. + Return the kernel of this homomorphism as a permutation group. EXAMPLES:: @@ -134,7 +136,7 @@ def image(self, J): def __call__(self, g): """ Some python code for wrapping GAP's Images function but only for - permutation groups. Returns an error if g is not in G. + permutation groups. This returns an error if g is not in G. EXAMPLES:: @@ -148,9 +150,11 @@ def __call__(self, g): """ return self.image(g) + class PermutationGroupMorphism_id(PermutationGroupMorphism): pass + class PermutationGroupMorphism_from_gap(PermutationGroupMorphism): def __init__(self, G, H, gap_hom): """ @@ -201,7 +205,7 @@ def _repr_defn(self): def _gap_(self, gap=None): """ - Returns a GAP version of this morphism. + Return a GAP version of this morphism. EXAMPLES:: @@ -217,7 +221,7 @@ def _gap_(self, gap=None): def __call__(self, g): """ Some python code for wrapping GAP's Images function but only for - permutation groups. Returns an error if g is not in G. + permutation groups. This returns an error if g is not in G. EXAMPLES:: @@ -236,7 +240,7 @@ def __init__(self, G, H, gens=None): """ Some python code for wrapping GAP's GroupHomomorphismByImages function but only for permutation groups. Can be expensive if G is - large. Returns "fail" if gens does not generate self or if the map + large. This returns "fail" if gens does not generate self or if the map does not extend to a group homomorphism, self - other. EXAMPLES:: @@ -270,8 +274,9 @@ def __init__(self, G, H, gens=None): def _repr_defn(self): """ - Returns the definition of this morphism. This is used when - printing the morphism. + Return the definition of this morphism. + + This is used when printing the morphism. EXAMPLES:: @@ -281,11 +286,11 @@ def _repr_defn(self): sage: phi._repr_defn() '[(1,2,3,4)] -> [(1,2,3,4)]' """ - return "%s -> %s"%(list(self.domain().gens()), self._images) + return "%s -> %s" % (list(self.domain().gens()), self._images) def _gap_(self): """ - Returns a GAP representation of this morphism. + Return a GAP representation of this morphism. EXAMPLES:: @@ -298,9 +303,10 @@ def _gap_(self): """ return self.domain()._gap_().GroupHomomorphismByImages(self.codomain(), self.domain().gens(), self._images) -def is_PermutationGroupMorphism(f): + +def is_PermutationGroupMorphism(f) -> bool: """ - Returns True if the argument ``f`` is a PermutationGroupMorphism. + Return True if the argument ``f`` is a PermutationGroupMorphism. EXAMPLES:: diff --git a/src/sage/groups/perm_gps/permutation_groups_catalog.py b/src/sage/groups/perm_gps/permutation_groups_catalog.py index ae3a0ebf33a..52f99920307 100644 --- a/src/sage/groups/perm_gps/permutation_groups_catalog.py +++ b/src/sage/groups/perm_gps/permutation_groups_catalog.py @@ -26,6 +26,6 @@ from .permgroup_named import JankoGroup as Janko from .permgroup_named import SuzukiSporadicGroup as SuzukiSporadic from .permgroup_named import SuzukiGroup as Suzuki -from .permgroup_named import (PGL, PSL, PSp,PSU,PGU,) +from .permgroup_named import (PGL, PSL, PSp, PSU, PGU) from .permgroup_named import TransitiveGroup as Transitive from .cubegroup import CubeGroup as RubiksCube diff --git a/src/sage/groups/perm_gps/symgp_conjugacy_class.py b/src/sage/groups/perm_gps/symgp_conjugacy_class.py index b338d616b70..d6112df67af 100644 --- a/src/sage/groups/perm_gps/symgp_conjugacy_class.py +++ b/src/sage/groups/perm_gps/symgp_conjugacy_class.py @@ -48,7 +48,7 @@ def _repr_(self): Conjugacy class of cycle type [4] in Symmetric group of order 4! as a permutation group """ - return "Conjugacy class of cycle type %s in %s"%(self._part, self._parent) + return "Conjugacy class of cycle type %s in %s" % (self._part, self._parent) def __eq__(self, other): r""" @@ -167,9 +167,10 @@ def set(self): """ if not self._set: self._set = Set(self._parent.element_class(x, self._parent, check=False) - for x in conjugacy_class_iterator(self._part, self._domain) ) + for x in conjugacy_class_iterator(self._part, self._domain)) return self._set + class PermutationsConjugacyClass(SymmetricGroupConjugacyClassMixin, ConjugacyClass): """ A conjugacy class of the permutations of `n`. @@ -197,7 +198,7 @@ def __init__(self, P, part): part = elt.cycle_type() else: elt = P.element_in_conjugacy_classes(part) - SymmetricGroupConjugacyClassMixin.__init__(self, range(1, P.n+1), part) + SymmetricGroupConjugacyClassMixin.__init__(self, range(1, P.n + 1), part) ConjugacyClass.__init__(self, P, elt) def __iter__(self): @@ -241,11 +242,12 @@ def set(self): """ if not self._set: self._set = Set(from_cycles(self._parent.n, x, self._parent) - for x in conjugacy_class_iterator(self._part, self._domain) ) + for x in conjugacy_class_iterator(self._part, self._domain)) return self._set + ##################################################################### -## Helper functions +# Helper functions def default_representative(part, G): r""" @@ -284,7 +286,7 @@ def default_representative(part, G): total = 0 cycles = [] for p in part: - cycles.append(tuple(D[total:total+p])) + cycles.append(tuple(D[total:total + p])) total += p return G.element_class(cycles, G, check=False) From 86f8a140a91f9ca935cbbbf79b3159b61e4e43cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 11 Oct 2022 09:41:40 +0200 Subject: [PATCH 292/350] remove one trace of python2 --- .../uncompress/filter_os_files.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/build/sage_bootstrap/uncompress/filter_os_files.py b/build/sage_bootstrap/uncompress/filter_os_files.py index db05e4303ae..f6d99ee3280 100644 --- a/build/sage_bootstrap/uncompress/filter_os_files.py +++ b/build/sage_bootstrap/uncompress/filter_os_files.py @@ -1,19 +1,16 @@ """ Filtering out OS-specific files """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Volker Braun # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** import os -import sys def filter_os_files(filenames): @@ -23,7 +20,6 @@ def filter_os_files(filenames): Currently removes OSX .DS_Store files and AppleDouble format ._ files. """ - files_set = set(filenames) def is_os_file(path): @@ -45,10 +41,4 @@ def is_os_file(path): return False - filenames = filter(lambda f: not is_os_file(f), filenames) - - if sys.version_info[0] == 2: - return filenames - else: - # Make sure to return a list on Python >= 3 - return list(filenames) + return [f for f in filenames if not is_os_file(f)] From cea9605d9d3cfb7f83a755b65a179376676e3101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 16:53:53 +0200 Subject: [PATCH 293/350] add svg display hook for plane partitions --- src/sage/combinat/plane_partition.py | 83 +++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index 49edf8abdea..758ce44d598 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -25,21 +25,22 @@ from __future__ import annotations from typing import Iterator -from sage.structure.list_clone import ClonableArray -from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.parent import Parent from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.combinat.posets.posets import Poset -from sage.rings.integer import Integer -from sage.misc.misc_c import prod from sage.combinat.tableau import Tableau +from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.misc.lazy_import import lazy_import +from sage.misc.misc_c import prod +from sage.modules.free_module_element import vector +from sage.rings.integer import Integer +from sage.structure.list_clone import ClonableArray +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation lazy_import("sage.plot.plot3d.platonic", "cube") class PlanePartition(ClonableArray, - metaclass=InheritComparisonClasscallMetaclass): + metaclass=InheritComparisonClasscallMetaclass): r""" A plane partition. @@ -396,6 +397,70 @@ def pp(self, show_box=False): """ print(self._repr_diagram(show_box)) + def _repr_svg_(self) -> str: + """ + Return the svg picture of a plane partition. + + This can be displayed by Jupyter. + + EXAMPLES:: + + sage: PP = PlanePartition([[2, 1, 1], [1, 1]]) + sage: PP._repr_svg_() + '' + """ + colors = ["snow", "tomato", "steelblue"] + + resu = '' + resu += '' + resu += '' + resu1 += '' + resu1 += '' + resu1 += '' + def _latex_(self, show_box=False, colors=["white", "lightgray", "darkgray"]) -> str: r""" @@ -622,8 +687,8 @@ def is_SPP(self) -> bool: for j in range(c2): T[i][j] = Z[i][j] return all(T[r][c] == T[c][r] - for r in range(size) - for c in range(r, size)) + for r in range(size) + for c in range(r, size)) def is_CSPP(self) -> bool: r""" From e5a96a17642ef4453e6a1344126d5007735711af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 10 Oct 2022 14:26:29 +0200 Subject: [PATCH 294/350] simplify maxima error handling --- src/sage/calculus/calculus.py | 1 - src/sage/interfaces/maxima_lib.py | 66 +++++++++---------------------- src/sage/symbolic/relation.py | 8 +++- 3 files changed, 25 insertions(+), 50 deletions(-) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index 76cd8986123..00da3f9d4af 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -2252,7 +2252,6 @@ def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima): sage: sefms("x # 3") == SR(x != 3) True sage: solve([x != 5], x) - #0: solve_rat_ineq(ineq=_SAGE_VAR_x # 5) [[x - 5 != 0]] sage: solve([2*x==3, x != 5], x) [[x == (3/2), (-7/2) != 0]] diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index e772ede1101..e1bdb76a415 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -158,14 +158,14 @@ (mterpri)))))))) """) -## Redirection of ECL and Maxima stdout to /dev/null +# Redirection of ECL and Maxima stdout to /dev/null ecl_eval(r"""(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))""") ecl_eval("(setf original-standard-output *standard-output*)") ecl_eval("(setf *standard-output* *dev-null*)") #ecl_eval("(setf *error-output* *dev-null*)") -## Default options set in Maxima +# Default options set in Maxima # display2d -- no ascii art output # keepfloat -- don't automatically convert floats to rationals @@ -183,48 +183,21 @@ init_code.append('nolabels : true') for l in init_code: ecl_eval("#$%s$"%l) -## To get more debug information uncomment the next line -## should allow to do this through a method +# To get more debug information uncomment the next line +# should allow to do this through a method #ecl_eval("(setf *standard-output* original-standard-output)") -## This is the main function (ECL object) used for evaluation +# This is the main function (ECL object) used for evaluation # This returns an EclObject maxima_eval=ecl_eval(""" (defun maxima-eval( form ) - (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form))))) - ;(princ (list "result=" result)) - ;(terpri) - ;(princ (list "$error=" $error)) - ;(terpri) - (cond - ((and (consp result) (eq (car result) 'maxima_eval)) (cdr result)) - ((eq result 'maxima-error) - (let ((the-jig (process-error-argl (cddr $error)))) - (mapc #'set (car the-jig) (cadr the-jig)) - (error (concatenate 'string - "Error executing code in Maxima: " - (with-output-to-string (stream) - (apply #'mformat stream (cadr $error) - (caddr the-jig))))) - )) - (t - (let ((the-jig (process-error-argl (cddr $error)))) - (mapc #'set (car the-jig) (cadr the-jig)) - (error (concatenate 'string "Maxima condition. result:" - (princ-to-string result) "$error:" - (with-output-to-string (stream) - (apply #'mformat stream (cadr $error) - (caddr the-jig))))) - )) - ) - ) -) + (with-$error (meval form))) """) -## Number of instances of this interface +# Number of instances of this interface maxima_lib_instances = 0 -## Here we define several useful ECL/Maxima objects +# Here we define several useful ECL/Maxima objects # The Maxima string function can change the structure of its input #maxprint=EclObject("$STRING") maxprint=EclObject(r"""(defun mstring-for-sage (form) @@ -678,10 +651,10 @@ def _object_function_class(self): """ return MaximaLibElementFunction - ## some helper functions to wrap the calculus use of the maxima interface. - ## these routines expect arguments living in the symbolic ring - ## and return something that is hopefully coercible into the symbolic - ## ring again. + # some helper functions to wrap the calculus use of the maxima interface. + # these routines expect arguments living in the symbolic ring + # and return something that is hopefully coercible into the symbolic + # ring again. def sr_integral(self,*args): """ @@ -864,7 +837,7 @@ def sr_sum(self,*args): sage: sum(1/(m^4 + 2*m^3 + 3*m^2 + 2*m)^2, m, 0, infinity) Traceback (most recent call last): ... - RuntimeError: ECL says: Error executing code in Maxima: Zero to negative power computed. + RuntimeError: ECL says: Zero to negative power computed. Similar situation for :trac:`12410`:: @@ -872,8 +845,7 @@ def sr_sum(self,*args): sage: sum(1/x*(-1)^x, x, 0, oo) Traceback (most recent call last): ... - RuntimeError: ECL says: Error executing code in Maxima: Zero to negative power computed. - + RuntimeError: ECL says: Zero to negative power computed. """ try: return max_to_sr(maxima_eval([[max_ratsimp],[[max_simplify_sum],([max_sum],[sr_to_max(SR(a)) for a in args])]])) @@ -1201,7 +1173,7 @@ def reduce_load_MaximaLib(): NIL=EclObject("NIL") lisp_length=EclObject("length") -## Dictionaries for standard operators +# Dictionaries for standard operators sage_op_dict = { sage.functions.other.abs : "MABS", add_vararg : "MPLUS", @@ -1230,7 +1202,7 @@ def reduce_load_MaximaLib(): max_op_dict = dict([(sage_op_dict[k],k) for k in sage_op_dict]) -## Here we correct the dictionaries for some simple operators +# Here we correct the dictionaries for some simple operators def sage_rat(x,y): r""" @@ -1260,7 +1232,7 @@ def sage_rat(x,y): max_op_dict[rat]=sage_rat -## Here we build dictionaries for operators needing special conversions. +# Here we build dictionaries for operators needing special conversions. ratdisrep = EclObject("ratdisrep") mrat = EclObject("MRAT") mqapply = EclObject("MQAPPLY") @@ -1508,12 +1480,12 @@ def max_pochhammer_to_sage(expr): } -## Dictionaries for symbols +# Dictionaries for symbols sage_sym_dict={} max_sym_dict={} -## Generic conversion functions +# Generic conversion functions max_i=EclObject("$%I") def pyobject_to_max(obj): diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 6bd6469dd22..e9dbc0fea30 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -1197,12 +1197,16 @@ def _solve_expression(f, x, explicit_solutions, multiplicities, Catch error message from Maxima:: sage: solve(acot(x),x) - [] + Traceback (most recent call last): + ... + TypeError: ECL says: cot: argument 0 isn't in the domain of cot. :: sage: solve(acot(x),x,to_poly_solve=True) - [] + Traceback (most recent call last): + ... + TypeError: ECL says: cot: argument 0 isn't in the domain of cot. :trac:`7491` fixed:: From 5501e0de0dca1cff0355326dd42bd8c7e5749568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 11 Oct 2022 17:25:04 -0300 Subject: [PATCH 295/350] Support matplotlib 3.6 --- src/sage/plot/arc.py | 6 +++--- src/sage/plot/ellipse.py | 3 ++- src/sage/plot/graphics.py | 4 ++-- src/sage/plot/plot.py | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/plot/arc.py b/src/sage/plot/arc.py index bb834763afc..f65973bcbd5 100644 --- a/src/sage/plot/arc.py +++ b/src/sage/plot/arc.py @@ -273,9 +273,9 @@ def _matplotlib_arc(self): p = patches.Arc((self.x, self.y), 2. * self.r1, 2. * self.r2, - fmod(self.angle, 2 * pi) * (180. / pi), - self.s1 * (180. / pi), - self.s2 * (180. / pi)) + angle=fmod(self.angle, 2 * pi) * (180. / pi), + theta1=self.s1 * (180. / pi), + theta2=self.s2 * (180. / pi)) return p def bezier_path(self): diff --git a/src/sage/plot/ellipse.py b/src/sage/plot/ellipse.py index a77e6fe640a..c35bed574ef 100644 --- a/src/sage/plot/ellipse.py +++ b/src/sage/plot/ellipse.py @@ -192,7 +192,8 @@ def _render_on_subplot(self, subplot): options = self.options() p = patches.Ellipse( (self.x,self.y), - self.r1*2.,self.r2*2.,self.angle/pi*180.) + self.r1*2.,self.r2*2., + angle=self.angle/pi*180.) p.set_linewidth(float(options['thickness'])) p.set_fill(options['fill']) a = float(options['alpha']) diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index e779e1210e3..8d620b5c625 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -2007,7 +2007,7 @@ def show(self, **kwds): We can also do custom formatting if you need it. See above for full details:: - sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex") + sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex") # not tested (broken with matplotlib 3.6) Graphics object consisting of 1 graphics primitive This is particularly useful when setting custom ticks in multiples @@ -2341,7 +2341,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), sage: subplot = Figure().add_subplot(111) sage: p._objects[0]._render_on_subplot(subplot) sage: p._matplotlib_tick_formatter(subplot, **d) - (, + (, , , , diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index b36ee57227c..5301a05c3dc 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -1741,7 +1741,7 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) :: - sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex") + sage: plot(2*x+1,(x,0,5),ticks=[[0,1,e,pi,sqrt(20)],2],tick_formatter="latex") # not tested (broken with matplotlib 3.6) Graphics object consisting of 1 graphics primitive .. PLOT:: From 9dc18eccad24a06de04f393854a4ecbff866c31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 12 Oct 2022 09:01:24 +0200 Subject: [PATCH 296/350] details fixed --- src/sage/quadratic_forms/genera/normal_form.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/quadratic_forms/genera/normal_form.py b/src/sage/quadratic_forms/genera/normal_form.py index a1fc35588d1..e9611fc5666 100644 --- a/src/sage/quadratic_forms/genera/normal_form.py +++ b/src/sage/quadratic_forms/genera/normal_form.py @@ -718,12 +718,12 @@ def _jordan_2_adic(G): # if it is the last 2 x 2 block, there is nothing to do. if cnt != n - 2: content = R(2 ** minval) - eqn_mat = D[cnt:cnt + 2, cnt:cnt + 2].list() + eqn_mat = D[cnt:cnt+2, cnt:cnt+2].list() eqn_mat = Matrix(R, 2, 2, [e // content for e in eqn_mat]) # calculate the inverse without using division inv = eqn_mat.adjugate() * eqn_mat.det().inverse_of_unit() - B1 = B[cnt:cnt + 2, :] - B2 = D[cnt + 2:, cnt:cnt + 2] * inv + B1 = B[cnt:cnt+2, :] + B2 = D[cnt+2:, cnt:cnt+2] * inv for i in range(B2.nrows()): for j in range(B2.ncols()): B2[i, j] = B2[i, j] // content @@ -847,9 +847,9 @@ def _normalize(G, normal_odd=True): D = B * G * B.T for i in range(n - 1): if D[i, i + 1] != 0: # there is a 2 x 2 block here - block = D[i:i + 2, i:i + 2] + block = D[i:i+2, i:i+2] trafo = _normalize_2x2(block) - B[i:i + 2, :] = trafo * B[i:i + 2, :] + B[i:i+2, :] = trafo * B[i:i+2, :] D = B * G * B.T return D, B @@ -1465,10 +1465,10 @@ def _two_adic_normal_forms(G, partial=False): UV = UVlist[k] UVm = UVlist[k - 1] V = UVlist[k][-2:] - if len(V) != 0 and D[V[0], V[0]] == 0: + if V and D[V[0], V[0]] == 0: V = [] # it is U not V # condition b) - if len(Wm) != 0: + if Wm: if len(V) == 2: R = Wm[:1] + V B[R, :] = _relations(D[R, R], 7) * B[R, :] @@ -1497,10 +1497,10 @@ def _two_adic_normal_forms(G, partial=False): if x == [0, 3, 7]: # relation 10 should be applied to 3 to stay in homogeneous normal form w = W[0] - if len(UVm) > 0: + if UVm: R = UVm[-2:] + [w] B[R, :] = _relations(D[R, R], 8) * B[R, :] - elif len(Wmm) > 0: + elif Wmm: R = Wmm[:1] + [w] B[R, :] = _relations(D[R, R], 10) * B[R, :] elif len(Wm) == 2: From 96539b4bfa0968e5f040a139e82a66ea19a278ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 12 Oct 2022 11:36:29 +0200 Subject: [PATCH 297/350] fine tuning --- src/sage/combinat/plane_partition.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index 758ce44d598..c8b29e06294 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -415,13 +415,13 @@ def _repr_svg_(self) -> str: resu += '' resu += '' - resu1 += '' - resu1 += '' resu1 += ' Date: Wed, 12 Oct 2022 20:24:03 +0200 Subject: [PATCH 298/350] trac #34123: revert a change --- src/sage/graphs/edge_connectivity.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 459ee90fe4f..adb382cbeb8 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -51,7 +51,7 @@ cdef class GabowEdgeConnectivity: - ``D`` -- a :class:`~sage.graphs.digraph.DiGraph` - EXAMPLES:: + EXAMPLES: A random `d`-regular digraph is `d`-edge-connected:: From 19198067d158e2fe0c4dbfec6ca4878c000d09cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Leli=C3=A8vre?= Date: Mon, 12 Jul 2021 11:57:39 +0200 Subject: [PATCH 299/350] 32182: Add some Python 3.x distro package names Arch Linux, Cygwin, Debian, Fedora, FreeBSD, Homebrew, MacPorts, OpenSUSE. Missing: Conda, Gentoo, Nix, Slackware, Void Linux. --- build/pkgs/_python3.10/distros/arch.txt | 1 + build/pkgs/_python3.10/distros/cygwin.txt | 1 + build/pkgs/_python3.10/distros/debian.txt | 1 + build/pkgs/_python3.10/distros/fedora.txt | 1 + build/pkgs/_python3.10/distros/freebsd.txt | 1 + build/pkgs/_python3.10/distros/homebrew.txt | 1 + build/pkgs/_python3.10/distros/macports.txt | 1 + build/pkgs/_python3.10/distros/opensuse.txt | 1 + build/pkgs/_python3.7/distros/arch.txt | 1 + build/pkgs/_python3.7/distros/cygwin.txt | 1 + build/pkgs/_python3.7/distros/debian.txt | 1 + build/pkgs/_python3.7/distros/fedora.txt | 1 + build/pkgs/_python3.7/distros/freebsd.txt | 1 + build/pkgs/_python3.7/distros/homebrew.txt | 1 + build/pkgs/_python3.7/distros/macports.txt | 1 + build/pkgs/_python3.7/distros/opensuse.txt | 1 + build/pkgs/_python3.8/distros/arch.txt | 1 + build/pkgs/_python3.8/distros/cygwin.txt | 1 + build/pkgs/_python3.8/distros/debian.txt | 1 + build/pkgs/_python3.8/distros/fedora.txt | 1 + build/pkgs/_python3.8/distros/freebsd.txt | 1 + build/pkgs/_python3.8/distros/homebrew.txt | 1 + build/pkgs/_python3.8/distros/macports.txt | 1 + build/pkgs/_python3.8/distros/opensuse.txt | 1 + build/pkgs/_python3.9/distros/arch.txt | 1 + build/pkgs/_python3.9/distros/cygwin.txt | 1 + build/pkgs/_python3.9/distros/debian.txt | 1 + build/pkgs/_python3.9/distros/fedora.txt | 1 + build/pkgs/_python3.9/distros/freebsd.txt | 1 + build/pkgs/_python3.9/distros/homebrew.txt | 1 + build/pkgs/_python3.9/distros/macports.txt | 1 + build/pkgs/_python3.9/distros/opensuse.txt | 1 + 32 files changed, 32 insertions(+) create mode 100644 build/pkgs/_python3.10/distros/arch.txt create mode 100644 build/pkgs/_python3.10/distros/cygwin.txt create mode 100644 build/pkgs/_python3.10/distros/debian.txt create mode 100644 build/pkgs/_python3.10/distros/fedora.txt create mode 100644 build/pkgs/_python3.10/distros/freebsd.txt create mode 100644 build/pkgs/_python3.10/distros/homebrew.txt create mode 100644 build/pkgs/_python3.10/distros/macports.txt create mode 100644 build/pkgs/_python3.10/distros/opensuse.txt create mode 100644 build/pkgs/_python3.7/distros/arch.txt create mode 100644 build/pkgs/_python3.7/distros/cygwin.txt create mode 100644 build/pkgs/_python3.7/distros/debian.txt create mode 100644 build/pkgs/_python3.7/distros/fedora.txt create mode 100644 build/pkgs/_python3.7/distros/freebsd.txt create mode 100644 build/pkgs/_python3.7/distros/homebrew.txt create mode 100644 build/pkgs/_python3.7/distros/macports.txt create mode 100644 build/pkgs/_python3.7/distros/opensuse.txt create mode 100644 build/pkgs/_python3.8/distros/arch.txt create mode 100644 build/pkgs/_python3.8/distros/cygwin.txt create mode 100644 build/pkgs/_python3.8/distros/debian.txt create mode 100644 build/pkgs/_python3.8/distros/fedora.txt create mode 100644 build/pkgs/_python3.8/distros/freebsd.txt create mode 100644 build/pkgs/_python3.8/distros/homebrew.txt create mode 100644 build/pkgs/_python3.8/distros/macports.txt create mode 100644 build/pkgs/_python3.8/distros/opensuse.txt create mode 100644 build/pkgs/_python3.9/distros/arch.txt create mode 100644 build/pkgs/_python3.9/distros/cygwin.txt create mode 100644 build/pkgs/_python3.9/distros/debian.txt create mode 100644 build/pkgs/_python3.9/distros/fedora.txt create mode 100644 build/pkgs/_python3.9/distros/freebsd.txt create mode 100644 build/pkgs/_python3.9/distros/homebrew.txt create mode 100644 build/pkgs/_python3.9/distros/macports.txt create mode 100644 build/pkgs/_python3.9/distros/opensuse.txt diff --git a/build/pkgs/_python3.10/distros/arch.txt b/build/pkgs/_python3.10/distros/arch.txt new file mode 100644 index 00000000000..92826c681b4 --- /dev/null +++ b/build/pkgs/_python3.10/distros/arch.txt @@ -0,0 +1 @@ +python310 diff --git a/build/pkgs/_python3.10/distros/cygwin.txt b/build/pkgs/_python3.10/distros/cygwin.txt new file mode 100644 index 00000000000..92826c681b4 --- /dev/null +++ b/build/pkgs/_python3.10/distros/cygwin.txt @@ -0,0 +1 @@ +python310 diff --git a/build/pkgs/_python3.10/distros/debian.txt b/build/pkgs/_python3.10/distros/debian.txt new file mode 100644 index 00000000000..da848b787c6 --- /dev/null +++ b/build/pkgs/_python3.10/distros/debian.txt @@ -0,0 +1 @@ +python3.10 diff --git a/build/pkgs/_python3.10/distros/fedora.txt b/build/pkgs/_python3.10/distros/fedora.txt new file mode 100644 index 00000000000..da848b787c6 --- /dev/null +++ b/build/pkgs/_python3.10/distros/fedora.txt @@ -0,0 +1 @@ +python3.10 diff --git a/build/pkgs/_python3.10/distros/freebsd.txt b/build/pkgs/_python3.10/distros/freebsd.txt new file mode 100644 index 00000000000..92826c681b4 --- /dev/null +++ b/build/pkgs/_python3.10/distros/freebsd.txt @@ -0,0 +1 @@ +python310 diff --git a/build/pkgs/_python3.10/distros/homebrew.txt b/build/pkgs/_python3.10/distros/homebrew.txt new file mode 100644 index 00000000000..b669c26e698 --- /dev/null +++ b/build/pkgs/_python3.10/distros/homebrew.txt @@ -0,0 +1 @@ +python@3.10 diff --git a/build/pkgs/_python3.10/distros/macports.txt b/build/pkgs/_python3.10/distros/macports.txt new file mode 100644 index 00000000000..92826c681b4 --- /dev/null +++ b/build/pkgs/_python3.10/distros/macports.txt @@ -0,0 +1 @@ +python310 diff --git a/build/pkgs/_python3.10/distros/opensuse.txt b/build/pkgs/_python3.10/distros/opensuse.txt new file mode 100644 index 00000000000..92826c681b4 --- /dev/null +++ b/build/pkgs/_python3.10/distros/opensuse.txt @@ -0,0 +1 @@ +python310 diff --git a/build/pkgs/_python3.7/distros/arch.txt b/build/pkgs/_python3.7/distros/arch.txt new file mode 100644 index 00000000000..2fde931221e --- /dev/null +++ b/build/pkgs/_python3.7/distros/arch.txt @@ -0,0 +1 @@ +python37 diff --git a/build/pkgs/_python3.7/distros/cygwin.txt b/build/pkgs/_python3.7/distros/cygwin.txt new file mode 100644 index 00000000000..2fde931221e --- /dev/null +++ b/build/pkgs/_python3.7/distros/cygwin.txt @@ -0,0 +1 @@ +python37 diff --git a/build/pkgs/_python3.7/distros/debian.txt b/build/pkgs/_python3.7/distros/debian.txt new file mode 100644 index 00000000000..a3079c597bd --- /dev/null +++ b/build/pkgs/_python3.7/distros/debian.txt @@ -0,0 +1 @@ +python3.7 diff --git a/build/pkgs/_python3.7/distros/fedora.txt b/build/pkgs/_python3.7/distros/fedora.txt new file mode 100644 index 00000000000..a3079c597bd --- /dev/null +++ b/build/pkgs/_python3.7/distros/fedora.txt @@ -0,0 +1 @@ +python3.7 diff --git a/build/pkgs/_python3.7/distros/freebsd.txt b/build/pkgs/_python3.7/distros/freebsd.txt new file mode 100644 index 00000000000..2fde931221e --- /dev/null +++ b/build/pkgs/_python3.7/distros/freebsd.txt @@ -0,0 +1 @@ +python37 diff --git a/build/pkgs/_python3.7/distros/homebrew.txt b/build/pkgs/_python3.7/distros/homebrew.txt new file mode 100644 index 00000000000..aa19b29d856 --- /dev/null +++ b/build/pkgs/_python3.7/distros/homebrew.txt @@ -0,0 +1 @@ +python@3.7 diff --git a/build/pkgs/_python3.7/distros/macports.txt b/build/pkgs/_python3.7/distros/macports.txt new file mode 100644 index 00000000000..2fde931221e --- /dev/null +++ b/build/pkgs/_python3.7/distros/macports.txt @@ -0,0 +1 @@ +python37 diff --git a/build/pkgs/_python3.7/distros/opensuse.txt b/build/pkgs/_python3.7/distros/opensuse.txt new file mode 100644 index 00000000000..2fde931221e --- /dev/null +++ b/build/pkgs/_python3.7/distros/opensuse.txt @@ -0,0 +1 @@ +python37 diff --git a/build/pkgs/_python3.8/distros/arch.txt b/build/pkgs/_python3.8/distros/arch.txt new file mode 100644 index 00000000000..398ae3228b3 --- /dev/null +++ b/build/pkgs/_python3.8/distros/arch.txt @@ -0,0 +1 @@ +python38 diff --git a/build/pkgs/_python3.8/distros/cygwin.txt b/build/pkgs/_python3.8/distros/cygwin.txt new file mode 100644 index 00000000000..398ae3228b3 --- /dev/null +++ b/build/pkgs/_python3.8/distros/cygwin.txt @@ -0,0 +1 @@ +python38 diff --git a/build/pkgs/_python3.8/distros/debian.txt b/build/pkgs/_python3.8/distros/debian.txt new file mode 100644 index 00000000000..b960de0d329 --- /dev/null +++ b/build/pkgs/_python3.8/distros/debian.txt @@ -0,0 +1 @@ +python3.8 diff --git a/build/pkgs/_python3.8/distros/fedora.txt b/build/pkgs/_python3.8/distros/fedora.txt new file mode 100644 index 00000000000..b960de0d329 --- /dev/null +++ b/build/pkgs/_python3.8/distros/fedora.txt @@ -0,0 +1 @@ +python3.8 diff --git a/build/pkgs/_python3.8/distros/freebsd.txt b/build/pkgs/_python3.8/distros/freebsd.txt new file mode 100644 index 00000000000..398ae3228b3 --- /dev/null +++ b/build/pkgs/_python3.8/distros/freebsd.txt @@ -0,0 +1 @@ +python38 diff --git a/build/pkgs/_python3.8/distros/homebrew.txt b/build/pkgs/_python3.8/distros/homebrew.txt new file mode 100644 index 00000000000..ea9989e790c --- /dev/null +++ b/build/pkgs/_python3.8/distros/homebrew.txt @@ -0,0 +1 @@ +python@3.8 diff --git a/build/pkgs/_python3.8/distros/macports.txt b/build/pkgs/_python3.8/distros/macports.txt new file mode 100644 index 00000000000..398ae3228b3 --- /dev/null +++ b/build/pkgs/_python3.8/distros/macports.txt @@ -0,0 +1 @@ +python38 diff --git a/build/pkgs/_python3.8/distros/opensuse.txt b/build/pkgs/_python3.8/distros/opensuse.txt new file mode 100644 index 00000000000..398ae3228b3 --- /dev/null +++ b/build/pkgs/_python3.8/distros/opensuse.txt @@ -0,0 +1 @@ +python38 diff --git a/build/pkgs/_python3.9/distros/arch.txt b/build/pkgs/_python3.9/distros/arch.txt new file mode 100644 index 00000000000..6a2d05c5edb --- /dev/null +++ b/build/pkgs/_python3.9/distros/arch.txt @@ -0,0 +1 @@ +python39 diff --git a/build/pkgs/_python3.9/distros/cygwin.txt b/build/pkgs/_python3.9/distros/cygwin.txt new file mode 100644 index 00000000000..6a2d05c5edb --- /dev/null +++ b/build/pkgs/_python3.9/distros/cygwin.txt @@ -0,0 +1 @@ +python39 diff --git a/build/pkgs/_python3.9/distros/debian.txt b/build/pkgs/_python3.9/distros/debian.txt new file mode 100644 index 00000000000..f4f2a021c6b --- /dev/null +++ b/build/pkgs/_python3.9/distros/debian.txt @@ -0,0 +1 @@ +python3.9 diff --git a/build/pkgs/_python3.9/distros/fedora.txt b/build/pkgs/_python3.9/distros/fedora.txt new file mode 100644 index 00000000000..f4f2a021c6b --- /dev/null +++ b/build/pkgs/_python3.9/distros/fedora.txt @@ -0,0 +1 @@ +python3.9 diff --git a/build/pkgs/_python3.9/distros/freebsd.txt b/build/pkgs/_python3.9/distros/freebsd.txt new file mode 100644 index 00000000000..6a2d05c5edb --- /dev/null +++ b/build/pkgs/_python3.9/distros/freebsd.txt @@ -0,0 +1 @@ +python39 diff --git a/build/pkgs/_python3.9/distros/homebrew.txt b/build/pkgs/_python3.9/distros/homebrew.txt new file mode 100644 index 00000000000..62a4a244e21 --- /dev/null +++ b/build/pkgs/_python3.9/distros/homebrew.txt @@ -0,0 +1 @@ +python@3.9 diff --git a/build/pkgs/_python3.9/distros/macports.txt b/build/pkgs/_python3.9/distros/macports.txt new file mode 100644 index 00000000000..6a2d05c5edb --- /dev/null +++ b/build/pkgs/_python3.9/distros/macports.txt @@ -0,0 +1 @@ +python39 diff --git a/build/pkgs/_python3.9/distros/opensuse.txt b/build/pkgs/_python3.9/distros/opensuse.txt new file mode 100644 index 00000000000..6a2d05c5edb --- /dev/null +++ b/build/pkgs/_python3.9/distros/opensuse.txt @@ -0,0 +1 @@ +python39 From ad4d9aaf46b0d232a11e405050d942933ceec215 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Oct 2022 13:46:24 -0700 Subject: [PATCH 300/350] build/pkgs/_python3.11: New; remove _python3.7 --- build/pkgs/_python3.11/distros/arch.txt | 1 + build/pkgs/_python3.11/distros/cygwin.txt | 1 + build/pkgs/_python3.11/distros/debian.txt | 1 + build/pkgs/_python3.11/distros/fedora.txt | 1 + build/pkgs/_python3.11/distros/freebsd.txt | 1 + build/pkgs/_python3.11/distros/homebrew.txt | 1 + build/pkgs/_python3.11/distros/macports.txt | 1 + build/pkgs/_python3.11/distros/opensuse.txt | 1 + build/pkgs/_python3.7/distros/arch.txt | 1 - build/pkgs/_python3.7/distros/cygwin.txt | 1 - build/pkgs/_python3.7/distros/debian.txt | 1 - build/pkgs/_python3.7/distros/fedora.txt | 1 - build/pkgs/_python3.7/distros/freebsd.txt | 1 - build/pkgs/_python3.7/distros/homebrew.txt | 1 - build/pkgs/_python3.7/distros/macports.txt | 1 - build/pkgs/_python3.7/distros/opensuse.txt | 1 - 16 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 build/pkgs/_python3.11/distros/arch.txt create mode 100644 build/pkgs/_python3.11/distros/cygwin.txt create mode 100644 build/pkgs/_python3.11/distros/debian.txt create mode 100644 build/pkgs/_python3.11/distros/fedora.txt create mode 100644 build/pkgs/_python3.11/distros/freebsd.txt create mode 100644 build/pkgs/_python3.11/distros/homebrew.txt create mode 100644 build/pkgs/_python3.11/distros/macports.txt create mode 100644 build/pkgs/_python3.11/distros/opensuse.txt delete mode 100644 build/pkgs/_python3.7/distros/arch.txt delete mode 100644 build/pkgs/_python3.7/distros/cygwin.txt delete mode 100644 build/pkgs/_python3.7/distros/debian.txt delete mode 100644 build/pkgs/_python3.7/distros/fedora.txt delete mode 100644 build/pkgs/_python3.7/distros/freebsd.txt delete mode 100644 build/pkgs/_python3.7/distros/homebrew.txt delete mode 100644 build/pkgs/_python3.7/distros/macports.txt delete mode 100644 build/pkgs/_python3.7/distros/opensuse.txt diff --git a/build/pkgs/_python3.11/distros/arch.txt b/build/pkgs/_python3.11/distros/arch.txt new file mode 100644 index 00000000000..1d66f45569a --- /dev/null +++ b/build/pkgs/_python3.11/distros/arch.txt @@ -0,0 +1 @@ +python311 diff --git a/build/pkgs/_python3.11/distros/cygwin.txt b/build/pkgs/_python3.11/distros/cygwin.txt new file mode 100644 index 00000000000..1d66f45569a --- /dev/null +++ b/build/pkgs/_python3.11/distros/cygwin.txt @@ -0,0 +1 @@ +python311 diff --git a/build/pkgs/_python3.11/distros/debian.txt b/build/pkgs/_python3.11/distros/debian.txt new file mode 100644 index 00000000000..ae2250b2363 --- /dev/null +++ b/build/pkgs/_python3.11/distros/debian.txt @@ -0,0 +1 @@ +python3.11 diff --git a/build/pkgs/_python3.11/distros/fedora.txt b/build/pkgs/_python3.11/distros/fedora.txt new file mode 100644 index 00000000000..ae2250b2363 --- /dev/null +++ b/build/pkgs/_python3.11/distros/fedora.txt @@ -0,0 +1 @@ +python3.11 diff --git a/build/pkgs/_python3.11/distros/freebsd.txt b/build/pkgs/_python3.11/distros/freebsd.txt new file mode 100644 index 00000000000..1d66f45569a --- /dev/null +++ b/build/pkgs/_python3.11/distros/freebsd.txt @@ -0,0 +1 @@ +python311 diff --git a/build/pkgs/_python3.11/distros/homebrew.txt b/build/pkgs/_python3.11/distros/homebrew.txt new file mode 100644 index 00000000000..f80da9b2e50 --- /dev/null +++ b/build/pkgs/_python3.11/distros/homebrew.txt @@ -0,0 +1 @@ +python@3.11 diff --git a/build/pkgs/_python3.11/distros/macports.txt b/build/pkgs/_python3.11/distros/macports.txt new file mode 100644 index 00000000000..1d66f45569a --- /dev/null +++ b/build/pkgs/_python3.11/distros/macports.txt @@ -0,0 +1 @@ +python311 diff --git a/build/pkgs/_python3.11/distros/opensuse.txt b/build/pkgs/_python3.11/distros/opensuse.txt new file mode 100644 index 00000000000..1d66f45569a --- /dev/null +++ b/build/pkgs/_python3.11/distros/opensuse.txt @@ -0,0 +1 @@ +python311 diff --git a/build/pkgs/_python3.7/distros/arch.txt b/build/pkgs/_python3.7/distros/arch.txt deleted file mode 100644 index 2fde931221e..00000000000 --- a/build/pkgs/_python3.7/distros/arch.txt +++ /dev/null @@ -1 +0,0 @@ -python37 diff --git a/build/pkgs/_python3.7/distros/cygwin.txt b/build/pkgs/_python3.7/distros/cygwin.txt deleted file mode 100644 index 2fde931221e..00000000000 --- a/build/pkgs/_python3.7/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -python37 diff --git a/build/pkgs/_python3.7/distros/debian.txt b/build/pkgs/_python3.7/distros/debian.txt deleted file mode 100644 index a3079c597bd..00000000000 --- a/build/pkgs/_python3.7/distros/debian.txt +++ /dev/null @@ -1 +0,0 @@ -python3.7 diff --git a/build/pkgs/_python3.7/distros/fedora.txt b/build/pkgs/_python3.7/distros/fedora.txt deleted file mode 100644 index a3079c597bd..00000000000 --- a/build/pkgs/_python3.7/distros/fedora.txt +++ /dev/null @@ -1 +0,0 @@ -python3.7 diff --git a/build/pkgs/_python3.7/distros/freebsd.txt b/build/pkgs/_python3.7/distros/freebsd.txt deleted file mode 100644 index 2fde931221e..00000000000 --- a/build/pkgs/_python3.7/distros/freebsd.txt +++ /dev/null @@ -1 +0,0 @@ -python37 diff --git a/build/pkgs/_python3.7/distros/homebrew.txt b/build/pkgs/_python3.7/distros/homebrew.txt deleted file mode 100644 index aa19b29d856..00000000000 --- a/build/pkgs/_python3.7/distros/homebrew.txt +++ /dev/null @@ -1 +0,0 @@ -python@3.7 diff --git a/build/pkgs/_python3.7/distros/macports.txt b/build/pkgs/_python3.7/distros/macports.txt deleted file mode 100644 index 2fde931221e..00000000000 --- a/build/pkgs/_python3.7/distros/macports.txt +++ /dev/null @@ -1 +0,0 @@ -python37 diff --git a/build/pkgs/_python3.7/distros/opensuse.txt b/build/pkgs/_python3.7/distros/opensuse.txt deleted file mode 100644 index 2fde931221e..00000000000 --- a/build/pkgs/_python3.7/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -python37 From 957738684943d639805ed2c727da7e3ccdc6d5f1 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 13 Oct 2022 01:29:08 +0200 Subject: [PATCH 301/350] implement Polynomial_generic_sparse.__floordiv__ --- .../polynomial/polynomial_element_generic.py | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 38586320dcc..868a5f691f9 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -36,7 +36,7 @@ from sage.libs.pari.all import pari_gen from sage.structure.richcmp import richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn -from sage.structure.element import coerce_binop +from sage.structure.element import coerce_binop, parent from sage.rings.infinity import infinity, Infinity from sage.rings.integer_ring import ZZ @@ -543,6 +543,29 @@ def degree(self, gen=None): return -1 return max(self.__coeffs) + def __floordiv__(self, right): + """ + Return the quotient upon division (no remainder). + + EXAMPLES:: + + sage: R. = PolynomialRing(QQbar, sparse=True) + sage: f = (1+2*x)^3 + 3*x; f + 8*x^3 + 12*x^2 + 9*x + 1 + sage: g = f // (1+2*x); g + 4*x^2 + 4*x + 5/2 + sage: f - g * (1+2*x) + -3/2 + sage: f.quo_rem(1+2*x) + (4*x^2 + 4*x + 5/2, -3/2) + + """ + P = self.parent() + if P is parent(right): + return self._floordiv_(right) + d = P.base_ring()(right) + return self.map_coefficients(lambda c: c // d) + def _add_(self, right): r""" EXAMPLES:: From 7524aed5bb67247ad0a8ce4448c88e6e9e8d9c1b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Oct 2022 18:02:04 -0700 Subject: [PATCH 302/350] tox.ini, build/pkgs/_python*/distros, .github/workflows/docker.yml: Use opensuse system python3 --- .github/workflows/docker.yml | 6 +++--- build/pkgs/_python3.10/distros/opensuse.txt | 1 + build/pkgs/_python3.11/distros/opensuse.txt | 1 + build/pkgs/_python3.8/distros/opensuse.txt | 1 + build/pkgs/_python3.9/distros/opensuse.txt | 1 + tox.ini | 2 ++ 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8eff13405f8..8c1eb794159 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -47,9 +47,9 @@ on: "gentoo-python3.9", "gentoo-python3.10", "archlinux-latest", - "opensuse-15.3-gcc_11", - "opensuse-15.4-gcc_11", - "opensuse-tumbleweed", + "opensuse-15.3-gcc_11-python3.9", + "opensuse-15.4-gcc_11-python3.10", + "opensuse-tumbleweed-python3.10", "conda-forge", "ubuntu-bionic-i386", "manylinux-2_24-i686", diff --git a/build/pkgs/_python3.10/distros/opensuse.txt b/build/pkgs/_python3.10/distros/opensuse.txt index 92826c681b4..90e42c91602 100644 --- a/build/pkgs/_python3.10/distros/opensuse.txt +++ b/build/pkgs/_python3.10/distros/opensuse.txt @@ -1 +1,2 @@ python310 +python310-devel diff --git a/build/pkgs/_python3.11/distros/opensuse.txt b/build/pkgs/_python3.11/distros/opensuse.txt index 1d66f45569a..a478404f8fb 100644 --- a/build/pkgs/_python3.11/distros/opensuse.txt +++ b/build/pkgs/_python3.11/distros/opensuse.txt @@ -1 +1,2 @@ python311 +python311-devel diff --git a/build/pkgs/_python3.8/distros/opensuse.txt b/build/pkgs/_python3.8/distros/opensuse.txt index 398ae3228b3..1f9ac08ba8e 100644 --- a/build/pkgs/_python3.8/distros/opensuse.txt +++ b/build/pkgs/_python3.8/distros/opensuse.txt @@ -1 +1,2 @@ python38 +python38-devel diff --git a/build/pkgs/_python3.9/distros/opensuse.txt b/build/pkgs/_python3.9/distros/opensuse.txt index 6a2d05c5edb..046ffc713b3 100644 --- a/build/pkgs/_python3.9/distros/opensuse.txt +++ b/build/pkgs/_python3.9/distros/opensuse.txt @@ -1 +1,2 @@ python39 +python39-devel diff --git a/tox.ini b/tox.ini index 0106e693891..9754fc319cf 100644 --- a/tox.ini +++ b/tox.ini @@ -509,6 +509,8 @@ setenv = python3.11: PYTHON_MINOR=11 CONFIG_CONFIGURE_ARGS_1=--with-system-python3=yes python3_spkg: CONFIG_CONFIGURE_ARGS_1=--without-system-python3 + python3.8,python3.9,python3.10,python3.11: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} + python3.8,python3.9,python3.10,python3.11: EXTRA_SAGE_PACKAGES=_python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} _bootstrap xz bzip2 libffi libpng macos-python3_xcode: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/usr/bin/python3 macos-{python3_xcode,nohomebrew}-{python3.8}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # Homebrew keg installs From d72b2fd021398abd723583f3fb4544ae84204384 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Oct 2022 18:37:26 -0700 Subject: [PATCH 303/350] build/pkgs/_python*/distros, .github/workflows/docker.yml: Use fedora system python3 --- .github/workflows/docker.yml | 10 +++++----- build/pkgs/_python3.10/distros/fedora.txt | 3 ++- build/pkgs/_python3.11/distros/fedora.txt | 3 ++- build/pkgs/_python3.8/distros/fedora.txt | 3 ++- build/pkgs/_python3.9/distros/fedora.txt | 3 ++- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8c1eb794159..784e9f1b72d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,9 +32,9 @@ on: "linuxmint-20.2", "linuxmint-20.3", "linuxmint-21", - "fedora-29", - "fedora-30", - "fedora-31", + "fedora-29-python3.8", + "fedora-30-python3.8", + "fedora-31-python3.8", "fedora-32", "fedora-33", "fedora-34", @@ -42,8 +42,8 @@ on: "fedora-36", "fedora-37", "centos-7-devtoolset-gcc_11", - "centos-stream-8", - "centos-stream-9", + "centos-stream-8-python3.9", + "centos-stream-9-python3.9", "gentoo-python3.9", "gentoo-python3.10", "archlinux-latest", diff --git a/build/pkgs/_python3.10/distros/fedora.txt b/build/pkgs/_python3.10/distros/fedora.txt index da848b787c6..90e42c91602 100644 --- a/build/pkgs/_python3.10/distros/fedora.txt +++ b/build/pkgs/_python3.10/distros/fedora.txt @@ -1 +1,2 @@ -python3.10 +python310 +python310-devel diff --git a/build/pkgs/_python3.11/distros/fedora.txt b/build/pkgs/_python3.11/distros/fedora.txt index ae2250b2363..a478404f8fb 100644 --- a/build/pkgs/_python3.11/distros/fedora.txt +++ b/build/pkgs/_python3.11/distros/fedora.txt @@ -1 +1,2 @@ -python3.11 +python311 +python311-devel diff --git a/build/pkgs/_python3.8/distros/fedora.txt b/build/pkgs/_python3.8/distros/fedora.txt index b960de0d329..1f9ac08ba8e 100644 --- a/build/pkgs/_python3.8/distros/fedora.txt +++ b/build/pkgs/_python3.8/distros/fedora.txt @@ -1 +1,2 @@ -python3.8 +python38 +python38-devel diff --git a/build/pkgs/_python3.9/distros/fedora.txt b/build/pkgs/_python3.9/distros/fedora.txt index f4f2a021c6b..046ffc713b3 100644 --- a/build/pkgs/_python3.9/distros/fedora.txt +++ b/build/pkgs/_python3.9/distros/fedora.txt @@ -1 +1,2 @@ -python3.9 +python39 +python39-devel From 6d20dff1f971648859e78a39855f7a91be9b629e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Oct 2022 19:03:05 -0700 Subject: [PATCH 304/350] build/pkgs/_python*/distros, .github/workflows/docker.yml: Use debian system python3 --- .github/workflows/docker.yml | 6 +++--- build/pkgs/_python3.10/distros/debian.txt | 2 ++ build/pkgs/_python3.11/distros/debian.txt | 2 ++ build/pkgs/_python3.8/distros/debian.txt | 2 ++ build/pkgs/_python3.9/distros/debian.txt | 2 ++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 784e9f1b72d..795ed3cd23d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,7 +18,7 @@ on: default: >- ["ubuntu-trusty-toolchain-gcc_9", "ubuntu-xenial-toolchain-gcc_9", - "ubuntu-bionic-gcc_8", + "ubuntu-bionic-gcc_8-python3.8", "ubuntu-focal", "ubuntu-jammy", "ubuntu-kinetic", @@ -26,8 +26,8 @@ on: "debian-bullseye", "debian-bookworm", "debian-sid", - "linuxmint-19-gcc_8", - "linuxmint-19.3-gcc_8", + "linuxmint-19-gcc_8-python3.8", + "linuxmint-19.3-gcc_8-python3.8", "linuxmint-20.1", "linuxmint-20.2", "linuxmint-20.3", diff --git a/build/pkgs/_python3.10/distros/debian.txt b/build/pkgs/_python3.10/distros/debian.txt index da848b787c6..9b7529828a1 100644 --- a/build/pkgs/_python3.10/distros/debian.txt +++ b/build/pkgs/_python3.10/distros/debian.txt @@ -1 +1,3 @@ python3.10 +python3.10-dev +python3.10-venv diff --git a/build/pkgs/_python3.11/distros/debian.txt b/build/pkgs/_python3.11/distros/debian.txt index ae2250b2363..a3128e4751f 100644 --- a/build/pkgs/_python3.11/distros/debian.txt +++ b/build/pkgs/_python3.11/distros/debian.txt @@ -1 +1,3 @@ python3.11 +python3.11-dev +python3.11-venv diff --git a/build/pkgs/_python3.8/distros/debian.txt b/build/pkgs/_python3.8/distros/debian.txt index b960de0d329..11476fe0595 100644 --- a/build/pkgs/_python3.8/distros/debian.txt +++ b/build/pkgs/_python3.8/distros/debian.txt @@ -1 +1,3 @@ python3.8 +python3.8-dev +python3.8-venv diff --git a/build/pkgs/_python3.9/distros/debian.txt b/build/pkgs/_python3.9/distros/debian.txt index f4f2a021c6b..e113156b021 100644 --- a/build/pkgs/_python3.9/distros/debian.txt +++ b/build/pkgs/_python3.9/distros/debian.txt @@ -1 +1,3 @@ python3.9 +python3.9-dev +python3.9-venv From 1269c5ae7d32ccaff196c28f5e9d13c6fd79f788 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 3 Aug 2022 16:37:44 -0700 Subject: [PATCH 305/350] build/pkgs/python3: Update to 3.10.6 --- build/pkgs/python3/checksums.ini | 6 +++--- build/pkgs/python3/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/python3/checksums.ini b/build/pkgs/python3/checksums.ini index 08ff0289325..9cfab274ca5 100644 --- a/build/pkgs/python3/checksums.ini +++ b/build/pkgs/python3/checksums.ini @@ -1,5 +1,5 @@ tarball=Python-VERSION.tar.xz -sha1=b80b9c13bb6ba5eb8762ca0d2b888c404582a405 -md5=f05727cb3489aa93cd57eb561c16747b -cksum=2773343227 +sha1=b5a3c74b281ab2e8e56779bbb9aeead1d92fed02 +md5=afc7e14f7118d10d1ba95ae8e2134bf0 +cksum=511800539 upstream_url=https://www.python.org/ftp/python/VERSION/Python-VERSION.tar.xz diff --git a/build/pkgs/python3/package-version.txt b/build/pkgs/python3/package-version.txt index c84ccce96a7..ac957df861e 100644 --- a/build/pkgs/python3/package-version.txt +++ b/build/pkgs/python3/package-version.txt @@ -1 +1 @@ -3.10.5 +3.10.6 From ddcd2ca5da214393ebf7648d7e53fbb95da983bb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Sep 2022 23:31:26 -0700 Subject: [PATCH 306/350] build/pkgs/python3: Update to 3.10.7 --- build/pkgs/python3/checksums.ini | 6 +++--- build/pkgs/python3/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/python3/checksums.ini b/build/pkgs/python3/checksums.ini index 9cfab274ca5..aac44ee5733 100644 --- a/build/pkgs/python3/checksums.ini +++ b/build/pkgs/python3/checksums.ini @@ -1,5 +1,5 @@ tarball=Python-VERSION.tar.xz -sha1=b5a3c74b281ab2e8e56779bbb9aeead1d92fed02 -md5=afc7e14f7118d10d1ba95ae8e2134bf0 -cksum=511800539 +sha1=e1d4c71059170ba841af310a04e0b4d7c38cb844 +md5=b8094f007b3a835ca3be6bdf8116cccc +cksum=3490430176 upstream_url=https://www.python.org/ftp/python/VERSION/Python-VERSION.tar.xz diff --git a/build/pkgs/python3/package-version.txt b/build/pkgs/python3/package-version.txt index ac957df861e..1281604a491 100644 --- a/build/pkgs/python3/package-version.txt +++ b/build/pkgs/python3/package-version.txt @@ -1 +1 @@ -3.10.6 +3.10.7 From 9bf562fcc47d139c8d69e865f824de2aacf0cbcf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 12 Oct 2022 19:15:36 -0700 Subject: [PATCH 307/350] build/pkgs/python3: Update to 3.10.8 --- build/pkgs/python3/checksums.ini | 6 +++--- build/pkgs/python3/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/python3/checksums.ini b/build/pkgs/python3/checksums.ini index aac44ee5733..d76bfeb7a4f 100644 --- a/build/pkgs/python3/checksums.ini +++ b/build/pkgs/python3/checksums.ini @@ -1,5 +1,5 @@ tarball=Python-VERSION.tar.xz -sha1=e1d4c71059170ba841af310a04e0b4d7c38cb844 -md5=b8094f007b3a835ca3be6bdf8116cccc -cksum=3490430176 +sha1=49ca7a5be7f13375e863442fbd9ead893ace3238 +md5=e92356b012ed4d0e09675131d39b1bde +cksum=3450973870 upstream_url=https://www.python.org/ftp/python/VERSION/Python-VERSION.tar.xz diff --git a/build/pkgs/python3/package-version.txt b/build/pkgs/python3/package-version.txt index 1281604a491..36435ac696d 100644 --- a/build/pkgs/python3/package-version.txt +++ b/build/pkgs/python3/package-version.txt @@ -1 +1 @@ -3.10.7 +3.10.8 From 8a64330eba30b836ef067104a8ea42a4cb8026b0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Oct 2022 12:12:18 -0700 Subject: [PATCH 308/350] .github/workflows/docker.yml: Back from fedora-31-python3.8 to fedora-31 - there is no python38-devel package --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 795ed3cd23d..74288199e59 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -34,7 +34,7 @@ on: "linuxmint-21", "fedora-29-python3.8", "fedora-30-python3.8", - "fedora-31-python3.8", + "fedora-31", "fedora-32", "fedora-33", "fedora-34", From c6b16a26f78e0f359a0009f47f798bcd12226448 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 14 Oct 2022 10:13:11 +0900 Subject: [PATCH 309/350] Update furo wheel package to 2022.9.29 --- build/pkgs/furo/checksums.ini | 6 +++--- build/pkgs/furo/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini index 2ba1678635d..2944243bfec 100644 --- a/build/pkgs/furo/checksums.ini +++ b/build/pkgs/furo/checksums.ini @@ -1,5 +1,5 @@ tarball=furo-VERSION-py3-none-any.whl -sha1=b9261dbe404cc13d399d50db0122fe48d7daeb23 -md5=fb331872d4d8a7d33f56aeb5df1f333f -cksum=3430203884 +sha1=7ea8c115b0e0af7fff19e2679d85ba7d7f93d0e8 +md5=a2afcdbaa1c2d8e7ee6358403a83df17 +cksum=4035919447 upstream_url=https://pypi.io/packages/py3/f/furo/furo-VERSION-py3-none-any.whl diff --git a/build/pkgs/furo/package-version.txt b/build/pkgs/furo/package-version.txt index 95f879eb816..b7fb725c655 100644 --- a/build/pkgs/furo/package-version.txt +++ b/build/pkgs/furo/package-version.txt @@ -1 +1 @@ -2022.6.21 +2022.9.29 From 73055b1f7de4955f5143c2a477a59d4ea945637a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Oct 2022 20:10:26 -0700 Subject: [PATCH 310/350] sage -package update-latest: Handle wheel packages, use distribution name from install-requires.txt --- build/sage_bootstrap/app.py | 15 ++++++++++++--- build/sage_bootstrap/package.py | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/build/sage_bootstrap/app.py b/build/sage_bootstrap/app.py index 132ada17594..51a315b4075 100644 --- a/build/sage_bootstrap/app.py +++ b/build/sage_bootstrap/app.py @@ -148,13 +148,22 @@ def update_latest(self, package_name, commit=False): """ Update a package to the latest version. This modifies the Sage sources. """ + pkg = Package(package_name) + dist_name = pkg.distribution_name + if dist_name is None: + log.debug('Package %s does not have Python distribution info in install-requires.txt') + return + if pkg.tarball_pattern.endswith('.whl'): + source = 'wheel' + else: + source = 'pypi' try: - pypi = PyPiVersion(package_name) + pypi = PyPiVersion(dist_name, source=source) except PyPiNotFound: - log.debug('%s is not a pypi package', package_name) + log.debug('%s is not a pypi package', dist_name) return else: - pypi.update(Package(package_name)) + pypi.update(pkg) if commit: self.commit(package_name) diff --git a/build/sage_bootstrap/package.py b/build/sage_bootstrap/package.py index ffe790f9c74..a32f21b24da 100644 --- a/build/sage_bootstrap/package.py +++ b/build/sage_bootstrap/package.py @@ -46,6 +46,7 @@ def __init__(self, package_name): self._init_checksum() self._init_version() self._init_type() + self._init_install_requires() def __repr__(self): return 'Package {0}'.format(self.name) @@ -229,6 +230,21 @@ def type(self): """ return self.__type + @property + def distribution_name(self): + """ + Return the Python distribution name or ``None`` for non-Python packages + """ + if self.__install_requires is None: + return None + for line in self.__install_requires.split('\n'): + line = line.strip() + if line.startswith('#'): + continue + for part in line.split(' '): + return part + return None + def __eq__(self, other): return self.tarball == other.tarball @@ -312,3 +328,10 @@ def _init_type(self): 'base', 'standard', 'optional', 'experimental' ] self.__type = package_type + + def _init_install_requires(self): + try: + with open(os.path.join(self.path, 'install-requires.txt')) as f: + self.__install_requires = f.read().strip() + except IOError: + self.__install_requires = None From b0f638d9b3db3e2a251d530217e8c7d090bce860 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 14 Oct 2022 13:35:54 +0900 Subject: [PATCH 311/350] Minor fixes --- build/sage_bootstrap/app.py | 2 +- build/sage_bootstrap/package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/sage_bootstrap/app.py b/build/sage_bootstrap/app.py index 51a315b4075..66da2665e84 100644 --- a/build/sage_bootstrap/app.py +++ b/build/sage_bootstrap/app.py @@ -151,7 +151,7 @@ def update_latest(self, package_name, commit=False): pkg = Package(package_name) dist_name = pkg.distribution_name if dist_name is None: - log.debug('Package %s does not have Python distribution info in install-requires.txt') + log.debug('%s does not have Python distribution info in install-requires.txt' % pkg) return if pkg.tarball_pattern.endswith('.whl'): source = 'wheel' diff --git a/build/sage_bootstrap/package.py b/build/sage_bootstrap/package.py index a32f21b24da..15b342223c4 100644 --- a/build/sage_bootstrap/package.py +++ b/build/sage_bootstrap/package.py @@ -241,7 +241,7 @@ def distribution_name(self): line = line.strip() if line.startswith('#'): continue - for part in line.split(' '): + for part in line.split(): return part return None From 3a41d7820772b076135ae3a953e51a6a27d658cd Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 14 Oct 2022 14:23:56 +0900 Subject: [PATCH 312/350] make doc-clean remove sage_docbuild --- src/doc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/Makefile b/src/doc/Makefile index 62fb1cafd18..2f76dfb9cb4 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -14,6 +14,7 @@ all: doc-html clean: rm -rf en/reference/*/sage + rm -rf en/reference/documentation/sage_docbuild rm -rf en/reference/sage rm -f common/*.pyc From 9696b346bd857f6ac8c2eaaacc6702de7e63120f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Oct 2022 22:38:36 -0700 Subject: [PATCH 313/350] .github/workflows/docker.yml: Use EXTRA_CONFIGURE_ARGS=--enable-fat-binary --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8eff13405f8..50fb2486de8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -128,6 +128,7 @@ jobs: FROM_DOCKER_REPOSITORY: ${{ inputs.from_docker_repository }} FROM_DOCKER_TARGET: ${{ inputs.from_docker_target }} FROM_DOCKER_TAG: ${{ inputs.from_docker_tag }} + EXTRA_CONFIGURE_ARGS: --enable-fat-binary steps: - name: Check out SageMath From 107b88e501af2dd436a65f2ff7f0563b7faed5ff Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 14 Oct 2022 14:52:52 +0900 Subject: [PATCH 314/350] Update furo wheel package correctly to 2022.9.29 --- build/pkgs/furo/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini index 2944243bfec..b2f2ee12484 100644 --- a/build/pkgs/furo/checksums.ini +++ b/build/pkgs/furo/checksums.ini @@ -1,5 +1,5 @@ tarball=furo-VERSION-py3-none-any.whl -sha1=7ea8c115b0e0af7fff19e2679d85ba7d7f93d0e8 -md5=a2afcdbaa1c2d8e7ee6358403a83df17 -cksum=4035919447 +sha1=c27ec5ecd6eb2bd30741d632a29fc1bbcc26e170 +md5=43edbca958fcdcb9df2683a81852a4e6 +cksum=1356193603 upstream_url=https://pypi.io/packages/py3/f/furo/furo-VERSION-py3-none-any.whl From c58f3f0ac1a934e59682bdc464e655f1a2198bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 14 Oct 2022 08:28:06 +0200 Subject: [PATCH 315/350] aesthetic commit --- src/sage/combinat/ribbon_tableau.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index 31b4fd2e2e2..dd4e179574b 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -23,7 +23,6 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.sets_cat import Sets from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ from sage.rings.integer import Integer from sage.combinat.combinat import CombinatorialElement from sage.combinat.skew_partition import SkewPartition, SkewPartitions @@ -146,9 +145,9 @@ def to_word(self): from sage.combinat.words.word import Word return Word([letter for row in reversed(self) for letter in row]) -# #################### -# Ribbon Tableaux # -# #################### +# =================== +# Ribbon Tableaux +# =================== class RibbonTableaux(UniqueRepresentation, Parent): @@ -567,9 +566,9 @@ def list_rec(nexts, current, part, weight, length): for curr_i in current] -# ############################# -# Spin and Cospin Polynomials # -# ############################# +# =============================== +# Spin and Cospin Polynomials +# =============================== def spin_rec(t, nexts, current, part, weight, length): """ Routine used for constructing the spin polynomial. @@ -684,7 +683,7 @@ def spin_polynomial(part, weight, length): sp = spin_polynomial_square(part, weight, length) t = SR.var('t') coeffs = sp.list() - return sum(c * t**(QQ(i) / 2) for i, c in enumerate(coeffs)) + return sum(c * t**(ZZ(i) / 2) for i, c in enumerate(coeffs)) def cospin_polynomial(part, weight, length): @@ -794,8 +793,6 @@ def graph_implementation_rec(skp, weight, length, function): for p in selection] return function(a, selection, skp, weight, length) -############################################################## - class MultiSkewTableau(CombinatorialElement): """ From 0f27e53660c5ddcdf97dcf6ce194064ea1ca0371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 14 Oct 2022 09:21:21 +0200 Subject: [PATCH 316/350] fix E502 in modular/ --- .../modular/modform/hecke_operator_on_qexp.py | 7 ++-- src/sage/modular/modform/space.py | 24 +++++++------- src/sage/modular/modform/vm_basis.py | 9 +++--- .../modform_hecketriangle/abstract_ring.py | 20 ++++++------ .../modform_hecketriangle/abstract_space.py | 28 +++++++--------- src/sage/modular/modform_hecketriangle/all.py | 28 ++++++++-------- .../graded_ring_element.py | 8 ++--- src/sage/modular/modsym/ambient.py | 14 ++++---- src/sage/modular/modsym/boundary.py | 32 ++++++++++--------- src/sage/modular/modsym/element.py | 4 +-- src/sage/modular/modsym/manin_symbol_list.py | 10 +++--- src/sage/modular/modsym/modular_symbols.py | 13 ++++---- src/sage/modular/modsym/p1list_nf.py | 6 ++-- 13 files changed, 99 insertions(+), 104 deletions(-) diff --git a/src/sage/modular/modform/hecke_operator_on_qexp.py b/src/sage/modular/modform/hecke_operator_on_qexp.py index 89de388f27f..dc6b293102f 100644 --- a/src/sage/modular/modform/hecke_operator_on_qexp.py +++ b/src/sage/modular/modform/hecke_operator_on_qexp.py @@ -109,10 +109,10 @@ def hecke_operator_on_qexp(f, n, k, eps=None, # formula v = [f[m*n] for m in range(prec)] else: - l = k-1 + l = k - 1 for m in range(prec): - am = sum([eps(d) * d**l * f[m*n//(d*d)] for \ - d in divisors(gcd(n, m)) if (m*n) % (d*d) == 0]) + am = sum([eps(d) * d**l * f[m*n//(d*d)] + for d in divisors(gcd(n, m)) if (m*n) % (d*d) == 0]) v.append(am) if _return_list: return v @@ -122,6 +122,7 @@ def hecke_operator_on_qexp(f, n, k, eps=None, R = f.parent() return R(v, prec) + def _hecke_operator_on_basis(B, V, n, k, eps): """ Does the work for hecke_operator_on_basis once the input diff --git a/src/sage/modular/modform/space.py b/src/sage/modular/modform/space.py index 69206f0e023..a16fd85d32c 100644 --- a/src/sage/modular/modform/space.py +++ b/src/sage/modular/modform/space.py @@ -54,7 +54,7 @@ # # Distributed under the terms of the GNU General Public License (GPL) # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ######################################################################### from sage.arith.misc import gcd @@ -81,7 +81,8 @@ from . import defaults from . import hecke_operator_on_qexp -WARN=False +WARN = False + def is_ModularFormsSpace(x): r""" @@ -528,8 +529,8 @@ def echelon_basis(self): W = self._q_expansion_module() pr = W.degree() B = self.q_echelon_basis(pr) - E = [self(F.linear_combination_of_basis(W.coordinates(f.padded_list(pr)))) \ - for f in B] + E = [self(F.linear_combination_of_basis(W.coordinates(f.padded_list(pr)))) + for f in B] return Sequence(E, cr=True, immutable=True) @cached_method @@ -537,10 +538,10 @@ def integral_basis(self): """ Return an integral basis for this space of modular forms. - EXAMPLES: In this example the integral and echelon bases are - different. + EXAMPLES: - :: + In this example the integral and echelon bases are + different. :: sage: m = ModularForms(97,2,prec=10) sage: s = m.cuspidal_subspace() @@ -908,8 +909,8 @@ def __add__(self, right): """ from sage.modular.modform.submodule import ModularFormsSubmodule if self.ambient_module() != right.ambient_module(): - raise ArithmeticError(("Sum of %s and %s not defined because " + \ - "they do not lie in a common ambient space.")%\ + raise ArithmeticError(("Sum of %s and %s not defined because " + + "they do not lie in a common ambient space.") % (self, right)) if self.is_ambient(): return self @@ -1381,8 +1382,9 @@ def basis(self): 1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6) ] """ - return Sequence([self.element_class(self, x) for \ - x in self.free_module().basis()], immutable=True, cr=True) + return Sequence([self.element_class(self, x) + for x in self.free_module().basis()], + immutable=True, cr=True) def gen(self, n): """ diff --git a/src/sage/modular/modform/vm_basis.py b/src/sage/modular/modform/vm_basis.py index be690b7b503..21e2fcd7477 100644 --- a/src/sage/modular/modform/vm_basis.py +++ b/src/sage/modular/modform/vm_basis.py @@ -248,8 +248,8 @@ def _delta_poly(prec=10): stop = int((-1+math.sqrt(1+8*prec))/2.0) # make list of index/value pairs for the sparse poly - values = [(n*(n+1)//2, ((-2*n-1) if (n & 1) else (2*n+1))) \ - for n in range(stop+1)] + values = [(n*(n+1)//2, ((-2*n-1) if (n & 1) else (2*n+1))) + for n in range(stop + 1)] for (i1, v1) in values: for (i2, v2) in values: @@ -260,15 +260,14 @@ def _delta_poly(prec=10): f = Fmpz_poly(v) t = verbose('made series') - f = f*f + f = f * f f._unsafe_mutate_truncate(prec) t = verbose('squared (2 of 3)', t) - f = f*f + f = f * f f._unsafe_mutate_truncate(prec - 1) t = verbose('squared (3 of 3)', t) f = f.left_shift(1) t = verbose('shifted', t) - return f diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index 5a9b0e86258..0ff086c0a60 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -222,23 +222,21 @@ def _coerce_map_from_(self, S): sage: MR4.has_coerce_map_from(MF2) True """ - from .space import FormsSpace_abstract from .functors import _common_subgroup - if ( isinstance(S, FormsRing_abstract)\ - and self._group == _common_subgroup(self._group, S._group)\ - and self._analytic_type >= S._analytic_type\ - and self.base_ring().has_coerce_map_from(S.base_ring()) ): + if (isinstance(S, FormsRing_abstract) + and self._group == _common_subgroup(self._group, S._group) + and self._analytic_type >= S._analytic_type + and self.base_ring().has_coerce_map_from(S.base_ring())): return True - elif isinstance(S, FormsRing_abstract): + if isinstance(S, FormsRing_abstract): return False - elif isinstance(S, FormsSpace_abstract): - raise RuntimeError( "This case should not occur." ) + if isinstance(S, FormsSpace_abstract): + raise RuntimeError("this case should not occur") # return self._coerce_map_from_(S.graded_ring()) - elif (self.AT("holo") <= self._analytic_type) and (self.coeff_ring().has_coerce_map_from(S)): + if (self.AT("holo") <= self._analytic_type) and (self.coeff_ring().has_coerce_map_from(S)): return True - else: - return False + return False def _an_element_(self): r""" diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index e7c59012429..90c786b1c9f 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -6,16 +6,14 @@ - Jonas Jermann (2013): initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.modules.free_module_element import is_FreeModuleElement @@ -323,19 +321,19 @@ def _coerce_map_from_(self, S): from .space import ZeroForm from .subspace import SubSpaceForms - if ( isinstance(S, ZeroForm)): + if isinstance(S, ZeroForm): return True - elif ( isinstance(S, SubSpaceForms)\ - and isinstance(self, SubSpaceForms) ): + if (isinstance(S, SubSpaceForms) + and isinstance(self, SubSpaceForms)): if (self.ambient_space().has_coerce_map_from(S.ambient_space())): S2 = S.change_ambient_space(self.ambient_space()) return self.module().has_coerce_map_from(S2.module()) else: return False - elif ( isinstance(S, FormsSpace_abstract)\ - and self.graded_ring().has_coerce_map_from(S.graded_ring())\ - and S.weight() == self._weight\ - and S.ep() == self._ep\ + elif ( isinstance(S, FormsSpace_abstract) + and self.graded_ring().has_coerce_map_from(S.graded_ring()) + and S.weight() == self._weight + and S.ep() == self._ep and not isinstance(self, SubSpaceForms)): return True else: @@ -1743,10 +1741,8 @@ def construct_form(self, laurent_series, order_1=ZZ(0), check=True, rationalize= if (len(coefficients) == 0): return self(0) - rat = sum([\ - coefficients[j] * self.F_basis_pol(exponents[j], order_1=order_1)\ - for j in range(ZZ(len(coefficients))) - ]) + rat = sum([coefficients[j] * self.F_basis_pol(exponents[j], order_1=order_1) + for j in range(ZZ(len(coefficients)))]) el = self(rat) diff --git a/src/sage/modular/modform_hecketriangle/all.py b/src/sage/modular/modform_hecketriangle/all.py index 728c7f729a9..cd236efc334 100644 --- a/src/sage/modular/modform_hecketriangle/all.py +++ b/src/sage/modular/modform_hecketriangle/all.py @@ -2,28 +2,28 @@ AUTHORS: - Jonas Jermann (2013): initial version - """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** from .hecke_triangle_groups import HeckeTriangleGroup -from .series_constructor import MFSeriesConstructor +from .series_constructor import MFSeriesConstructor -from .graded_ring import ( QuasiMeromorphicModularFormsRing, QuasiWeakModularFormsRing, QuasiModularFormsRing,\ - QuasiCuspFormsRing, MeromorphicModularFormsRing, WeakModularFormsRing,\ - ModularFormsRing, CuspFormsRing ) +from .graded_ring import (QuasiMeromorphicModularFormsRing, + QuasiWeakModularFormsRing, QuasiModularFormsRing, + QuasiCuspFormsRing, MeromorphicModularFormsRing, + WeakModularFormsRing, + ModularFormsRing, CuspFormsRing) -from .space import ( QuasiMeromorphicModularForms, QuasiWeakModularForms, QuasiModularForms, QuasiCuspForms,\ - MeromorphicModularForms, WeakModularForms, ModularForms, CuspForms,\ - ZeroForm ) +from .space import (QuasiMeromorphicModularForms, QuasiWeakModularForms, + QuasiModularForms, QuasiCuspForms, + MeromorphicModularForms, WeakModularForms, ModularForms, + CuspForms, ZeroForm) -from .subspace import ModularFormsSubSpace +from .subspace import ModularFormsSubSpace diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index d7b3a5094b6..b6d01bf0c37 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -2167,12 +2167,10 @@ def evaluate(self, tau, prec = None, num_prec = None, check=False): pass # The general case - num_prec = max(\ - ZZ(getattr(tau,'prec',lambda: num_prec)()),\ - num_prec\ - ) + num_prec = max(ZZ(getattr(tau, 'prec', lambda: num_prec)()), num_prec) + tau = tau.n(num_prec) - (x,y,z,d) = self.parent().rat_field().gens() + (x, y, z, d) = self.parent().rat_field().gens() if (self.is_homogeneous() and self.is_modular()): q_exp = self.q_expansion_fixed_d(prec=prec, d_num_prec=num_prec) diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index 4f9b23bfc28..627f1c567e7 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -2651,9 +2651,9 @@ def _repr_(self): sage: M # indirect doctest Modular Symbols space of dimension 32 for Gamma_0(37) of weight 6 with sign 0 over Rational Field """ - return ("Modular Symbols space of dimension %s for Gamma_0(%s) of weight %s with sign %s " + \ - "over %s")%(self.dimension(), self.level(),self.weight(), self.sign(), - self.base_ring()) + return ("Modular Symbols space of dimension %s for Gamma_0(%s) of weight %s with sign %s " + + "over %s") % (self.dimension(), self.level(),self.weight(), self.sign(), + self.base_ring()) def _cuspidal_submodule_dimension_formula(self): r""" @@ -3607,10 +3607,10 @@ def _repr_(self): sage: M # indirect doctest Modular Symbols space of dimension 2 and level 5, weight 3, character [zeta4], sign 0, over Cyclotomic Field of order 4 and degree 2 """ - return ("Modular Symbols space of dimension %s and level %s, weight %s, character %s, sign %s, " + \ - "over %s")%(self.dimension(), self.level(), self.weight(), - self.character()._repr_short_(), self.sign(), self.base_ring()) - + return ("Modular Symbols space of dimension %s and level %s, weight %s, character %s, sign %s, " + + "over %s") % (self.dimension(), self.level(), self.weight(), + self.character()._repr_short_(), self.sign(), + self.base_ring()) def _cuspidal_submodule_dimension_formula(self): r""" diff --git a/src/sage/modular/modsym/boundary.py b/src/sage/modular/modsym/boundary.py index fa24249edc8..ec41f8c36dd 100644 --- a/src/sage/modular/modsym/boundary.py +++ b/src/sage/modular/modsym/boundary.py @@ -569,7 +569,7 @@ def __call__(self, x): y = {i: xi for i, xi in enumerate(x)} return BoundarySpaceElement(self, y) - raise TypeError("Coercion of %s (of type %s) into %s not (yet) defined."%(x, type(x), self)) + raise TypeError("Coercion of %s (of type %s) into %s not (yet) defined." % (x, type(x), self)) def _repr_(self): """ @@ -580,10 +580,10 @@ def _repr_(self): sage: sage.modular.modsym.boundary.BoundarySpace(Gamma0(3), 2)._repr_() 'Space of Boundary Modular Symbols of weight 2 for Congruence Subgroup Gamma0(3) with sign 0 and character [1] over Rational Field' """ - return ("Space of Boundary Modular Symbols of weight %s for" + \ + return ("Space of Boundary Modular Symbols of weight %s for" + " %s with sign %s and character %s over %s") % ( - self.weight(), self.group(), self.sign(), - self.character()._repr_short_(), self.base_ring()) + self.weight(), self.group(), self.sign(), + self.character()._repr_short_(), self.base_ring()) def _cusp_index(self, cusp): """ @@ -806,8 +806,8 @@ def _repr_(self): sage: ModularSymbols(Gamma1(5), 3, sign=1).boundary_space()._repr_() 'Boundary Modular Symbols space for Gamma_1(5) of weight 3 over Rational Field' """ - return ("Boundary Modular Symbols space for Gamma_1(%s) of weight %s " + \ - "over %s") % (self.level(),self.weight(), self.base_ring()) + return ("Boundary Modular Symbols space for Gamma_1(%s) of weight %s " + + "over %s") % (self.level(), self.weight(), self.base_ring()) def _is_equiv(self, c1, c2): """ @@ -946,19 +946,19 @@ def _coerce_cusp(self, c): # if sign: if (c.is_infinity() and sign != (-1)**self.weight()) or \ - (c.is_zero() and sign== -1): + (c.is_zero() and sign == -1): self._zero_cusps.append(c) del self._known_gens[-1] return self(0) elif (not c.is_infinity() and not c.is_zero()): t, eps = self._is_equiv(c, -c) - if t and ((eps == 1 and sign == -1) or \ + if t and ((eps == 1 and sign == -1) or (eps == -1 and sign != (-1)**self.weight())): self._zero_cusps.append(c) del self._known_gens[-1] return self(0) - return BoundarySpaceElement(self, {(len(g)-1):1}) + return BoundarySpaceElement(self, {(len(g)-1): 1}) class BoundarySpace_wtk_gamma_h(BoundarySpace): @@ -1016,8 +1016,8 @@ def _repr_(self): sage: ModularSymbols(GammaH(7,[2]), 4).boundary_space()._repr_() 'Boundary Modular Symbols space for Congruence Subgroup Gamma_H(7) with H generated by [2] of weight 4 over Rational Field' """ - return ("Boundary Modular Symbols space for %s of weight %s " + \ - "over %s") % (self.group(),self.weight(), self.base_ring()) + return ("Boundary Modular Symbols space for %s of weight %s " + + "over %s") % (self.group(), self.weight(), self.base_ring()) def _is_equiv(self, c1, c2): """ @@ -1205,13 +1205,13 @@ def _coerce_cusp(self, c): return self(0) elif (not c.is_infinity() and not c.is_zero()): t, eps = self._is_equiv(c, -c) - if t and ((eps == 1 and sign == -1) or \ + if t and ((eps == 1 and sign == -1) or (eps == -1 and sign != (-1)**self.weight())): self._zero_cusps.append(c) del self._known_gens[-1] return self(0) - return BoundarySpaceElement(self, {(len(g)-1):1}) + return BoundarySpaceElement(self, {(len(g)-1): 1}) class BoundarySpace_wtk_eps(BoundarySpace): @@ -1263,9 +1263,11 @@ def _repr_(self): sage: ModularSymbols(DirichletGroup(6).0, 4).boundary_space()._repr_() 'Boundary Modular Symbols space of level 6, weight 4, character [-1] and dimension 0 over Rational Field' """ - return ("Boundary Modular Symbols space of level %s, weight %s, character %s " + \ + return ("Boundary Modular Symbols space of level %s, weight %s, character %s " + "and dimension %s over %s") % (self.level(), self.weight(), - self.character()._repr_short_(), self.rank(), self.base_ring()) + self.character()._repr_short_(), + self.rank(), + self.base_ring()) def _is_equiv(self, c1, c2): """ diff --git a/src/sage/modular/modsym/element.py b/src/sage/modular/modsym/element.py index 0735a58308e..cc81faad50d 100644 --- a/src/sage/modular/modsym/element.py +++ b/src/sage/modular/modsym/element.py @@ -291,8 +291,8 @@ def manin_symbol_rep(self): v = self.element() manin_symbols = A.ambient_hecke_module().manin_symbols_basis() F = formal_sum.FormalSums(A.base_ring()) - ms = F([(v[i], manin_symbols[i]) for i in \ - range(v.degree()) if v[i] != 0], check=False, reduce=False) + ms = F([(v[i], manin_symbols[i]) for i in range(v.degree()) + if v[i] != 0], check=False, reduce=False) self.__manin_symbols = ms return self.__manin_symbols diff --git a/src/sage/modular/modsym/manin_symbol_list.py b/src/sage/modular/modsym/manin_symbol_list.py index 187db53bd16..182a35ffe32 100644 --- a/src/sage/modular/modsym/manin_symbol_list.py +++ b/src/sage/modular/modsym/manin_symbol_list.py @@ -16,7 +16,7 @@ - :class:`ManinSymbolList_character` """ -#***************************************************************************** +# **************************************************************************** # Sage: Open Source Mathematical Software # # Copyright (C) 2005 William Stein @@ -30,8 +30,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.modular.modsym.p1list as p1list import sage.modular.modsym.g1list as g1list @@ -949,8 +949,8 @@ def __init__(self, character, weight): # The list returned from P1List is guaranteed to be sorted. # Thus each list constructed below is also sorted. This is # important since the index function assumes the list is sorted. - L = [(i, u, v) for i in range(weight-2+1) \ - for u, v in self.__P1.list()] + L = [(i, u, v) for i in range(weight - 2 + 1) + for u, v in self.__P1.list()] self.__list = L ManinSymbolList.__init__(self, weight, L) diff --git a/src/sage/modular/modsym/modular_symbols.py b/src/sage/modular/modsym/modular_symbols.py index c832cb8be05..30a1aa2c0b8 100644 --- a/src/sage/modular/modsym/modular_symbols.py +++ b/src/sage/modular/modsym/modular_symbols.py @@ -14,8 +14,7 @@ sage: loads(dumps(s)) == s True """ - -#***************************************************************************** +# **************************************************************************** # Sage: Open Source Mathematical Software # # Copyright (C) 2005, 2009 William Stein @@ -29,8 +28,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.modular.cusps as cusps from sage.modular.modsym.apply import apply_to_monomial from sage.modular.modsym.manin_symbol import ManinSymbol @@ -316,11 +315,11 @@ def apply(self, g): space = self.__space i = self.__i k = space.weight() - a,b,c,d = tuple(g) - coeffs = apply_to_monomial(i, k-2, d, -b, -c, a) + a, b, c, d = tuple(g) + coeffs = apply_to_monomial(i, k - 2, d, -b, -c, a) g_alpha = self.__alpha.apply(g) g_beta = self.__beta.apply(g) - return formal_sum.FormalSum([(coeffs[j], ModularSymbol(space, j, g_alpha, g_beta)) \ + return formal_sum.FormalSum([(coeffs[j], ModularSymbol(space, j, g_alpha, g_beta)) for j in reversed(range(k-1)) if coeffs[j] != 0]) def __manin_symbol_rep(self, alpha): diff --git a/src/sage/modular/modsym/p1list_nf.py b/src/sage/modular/modsym/p1list_nf.py index 222caacca80..96f553658c1 100644 --- a/src/sage/modular/modsym/p1list_nf.py +++ b/src/sage/modular/modsym/p1list_nf.py @@ -1199,6 +1199,6 @@ def psi(N): raise ValueError("psi only defined for integral ideals") from sage.misc.misc_c import prod - return prod([(np+1)*np**(e-1) \ - for np,e in [(p.absolute_norm(),e) \ - for p,e in N.factor()]]) + return prod([(np + 1) * np**(e - 1) + for np, e in [(p.absolute_norm(), e) + for p, e in N.factor()]]) From b2af690766e1439a85eb9ad38bc1cca330b12ef0 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 14 Oct 2022 20:52:24 +0900 Subject: [PATCH 317/350] Fix an errorneous example --- src/sage/schemes/projective/projective_morphism.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 86e54cbf1fe..30afbb10ab1 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2292,11 +2292,14 @@ def __eq__(self, other): True sage: C = Curve(x^2 + y^2 - z^2) - sage: A. = AffineSpace(QQ, 1) - sage: f = C.hom([(x + z)/y], A) - sage: g = C.hom([y/(z - x)], A) + sage: P. = ProjectiveSpace(QQ, 1) + sage: f = C.hom([x + z, y], P) + sage: g = C.hom([y, z - x], P) sage: f == g True + sage: h = C.hom([z, x - y], P) + sage: f == h + False """ Y = self.codomain() From d36ed98544ee0e74941dbdffe021798124e4c176 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 14 Oct 2022 10:51:07 -0700 Subject: [PATCH 318/350] tox.ini (python3.*-minimal): Provide system liblzma so that system python can be accepted; not system xz --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9754fc319cf..89541088306 100644 --- a/tox.ini +++ b/tox.ini @@ -510,7 +510,7 @@ setenv = CONFIG_CONFIGURE_ARGS_1=--with-system-python3=yes python3_spkg: CONFIG_CONFIGURE_ARGS_1=--without-system-python3 python3.8,python3.9,python3.10,python3.11: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} - python3.8,python3.9,python3.10,python3.11: EXTRA_SAGE_PACKAGES=_python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} _bootstrap xz bzip2 libffi libpng + python3.8,python3.9,python3.10,python3.11: EXTRA_SAGE_PACKAGES=_python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} _bootstrap liblzma bzip2 libffi libpng macos-python3_xcode: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/usr/bin/python3 macos-{python3_xcode,nohomebrew}-{python3.8}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # Homebrew keg installs From 83401857c21f50fbe41b59ed286a98fe4c67d0ae Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 15 Oct 2022 08:06:20 +0200 Subject: [PATCH 319/350] trac #34123: fix doctest --- src/sage/graphs/edge_connectivity.pyx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index adb382cbeb8..54152821203 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -74,12 +74,11 @@ cdef class GabowEdgeConnectivity: sage: G = graphs.RandomBarabasiAlbert(100, 2) sage: D = DiGraph(G) - sage: GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() - 2 - sage: GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() - 2 - sage: GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() - 2 + sage: ec1 = GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() + sage: ec2 = GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() + sage: ec3 = GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() + sage: ec1 == ec2 and ec2 == ec3 + True TESTS: From 017e300cb7958405662cf7d21a85b5c4ddba2c7a Mon Sep 17 00:00:00 2001 From: Dennis Jahn Date: Sat, 15 Oct 2022 11:48:21 +0200 Subject: [PATCH 320/350] changed the references --- src/sage/categories/weyl_groups.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index 47ca72306f0..4e6a8d30511 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -1,10 +1,5 @@ r""" Weyl Groups - -REFERENCES: - -.. [Dye] Dyer. *Bruhat intervals, polyhedral cones and Kazhdan-Lusztig-Stanley polynomials*. Math.Z., 215(2):223-236, 1994. -.. [JahStu] Jahn and Stump. *Bruhat intervals, subword complexes and brick polyhedra for finite Coxeter groups*. Preprint, available at :arxiv:`2103.03715`, 2021. """ #***************************************************************************** # Copyright (C) 2009 Nicolas M. Thiery @@ -207,8 +202,8 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): REFERENCES: - - [Dye]_ - - [JahStu]_ + - [Dy1994]_ + - [JS2021]_ """ from sage.modules.free_module_element import vector if side == 'upper': From c488beb779d383377059ff37df8015d6e98d7db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 16 Oct 2022 11:20:17 +0200 Subject: [PATCH 321/350] full pep8 for elliptic_curves/cardinality.py --- .../schemes/elliptic_curves/cardinality.py | 273 +++++++++--------- 1 file changed, 135 insertions(+), 138 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/cardinality.py b/src/sage/schemes/elliptic_curves/cardinality.py index ea12ffa0965..cc93b9ecf74 100644 --- a/src/sage/schemes/elliptic_curves/cardinality.py +++ b/src/sage/schemes/elliptic_curves/cardinality.py @@ -2,28 +2,23 @@ Specific algorithms to compute cardinality of elliptic curves over a finite field Since point counting now uses PARI/GP, this code is only used when a -specific algorithm was specified or when the j-invariant lies in a -subfield. +specific algorithm was specified or when the j-invariant lies in a subfield. AUTHORS: - John Cremona (2008-2009): Original point counting code -- Jeroen Demeyer (2017-2018): Refactored and moved to - ``cardinality.py``. +- Jeroen Demeyer (2017-2018): Refactored and moved to ``cardinality.py``. """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008-2009 John Cremona # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** - - +# https://www.gnu.org/licenses/ +# **************************************************************************** from .constructor import EllipticCurve, EllipticCurve_from_j from sage.schemes.curves.projective_curve import Hasse_bounds from sage.rings.all import Integer, ZZ, GF, polygen @@ -40,19 +35,19 @@ def _cardinality_with_j_invariant_1728(self): An example with q=p=1 (mod 4):: - sage: F=GF(10009) + sage: F = GF(10009) sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,11^i,0])) for i in range(4)] [10016, 10210, 10004, 9810] An example with q=p=3 (mod 4):: - sage: F=GF(10007) + sage: F = GF(10007) sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,5^i,0])) for i in range(4)] [10008, 10008, 10008, 10008] An example with `q=p^2`, p=3 (mod 4):: - sage: F.=GF(10007^2,'a') + sage: F. = GF(10007^2,'a') sage: [_cardinality_with_j_invariant_1728(EllipticCurve(F,[0,0,0,a^i,0])) for i in range(4)] [100160064, 100140050, 100120036, 100140050] @@ -90,11 +85,11 @@ def _cardinality_with_j_invariant_1728(self): Examples with `q=3^d`, d even (6 isomorphism classes):: - sage: F.=GF(3^18,'g') - sage: i=F(-1).sqrt() - sage: a=g^8 # has trace 1 - sage: ais= [[0,0,0,1,0],[0,0,0,1,i*a],[0,0,0,g,0],[0,0,0,g^3,0],[0,0,0,g^2,0], [0,0,0,g^2,i*a*g^3]] - sage: curves=[EllipticCurve(F,ai) for ai in ais] + sage: F. = GF(3^18,'g') + sage: i = F(-1).sqrt() + sage: a = g^8 # has trace 1 + sage: ais = [[0,0,0,1,0],[0,0,0,1,i*a],[0,0,0,g,0],[0,0,0,g^3,0],[0,0,0,g^2,0], [0,0,0,g^2,i*a*g^3]] + sage: curves = [EllipticCurve(F,ai) for ai in ais] sage: all((e1 == e2 or not e1.is_isomorphic(e2)) for e1 in curves for e2 in curves) True sage: [_cardinality_with_j_invariant_1728(e) for e in curves] @@ -104,7 +99,7 @@ def _cardinality_with_j_invariant_1728(self): Check that a bug noted at :trac:`15667` is fixed:: - sage: F.=GF(3^6,'a') + sage: F. = GF(3^6,'a') sage: EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a, a^4 + a^3 + 2*a + 1]).cardinality() 784 sage: EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a, a^4 + a^3 + 2*a + 1]).cardinality_exhaustive() @@ -116,27 +111,27 @@ def _cardinality_with_j_invariant_1728(self): pass k = self.base_ring() - assert self.j_invariant()==k(1728) + assert self.j_invariant() == k(1728) q = k.cardinality() p = k.characteristic() d = k.degree() - x=polygen(ZZ) + x = polygen(ZZ) # p=2, j=0=1728 # # Number of isomorphism classes is 3 (in odd degree) or 7 (in even degree) # - if p==2: - if d%2==1: + if p == 2: + if d % 2: # The 3 classes are represented, independently of d, # by [0,0,1,0,0], [0,0,1,1,0], [0,0,1,1,1] - E=EllipticCurve(k,[0,0,1,0,0]) + E = EllipticCurve(k, [0, 0, 1, 0, 0]) if self.is_isomorphic(E): t = 0 else: - n = (d+1)//2 + n = (d + 1) // 2 t = 2**n - n = n%4 + n = n % 4 if n == 0 or n == 1: t = -t E = EllipticCurve(k, [0, 0, 1, 1, 1]) @@ -153,31 +148,31 @@ def _cardinality_with_j_invariant_1728(self): # unity, so the traces are 2*pi, -2*pi, 0, -pi, +pi; # -pi, +pi. delta = self.discriminant() - discube = (delta**((q-1)//3) == k(1)) - pi = (-2)**(d//2) + discube = (delta**((q - 1) // 3) == k(1)) + pi = (-2)**(d // 2) if discube: a = k.gen() b = a while b.trace() == 0: b *= a - if self.is_isomorphic(EllipticCurve(k,[0,0,1,b,0])): + if self.is_isomorphic(EllipticCurve(k, [0, 0, 1, b, 0])): t = 0 else: - t = 2*pi - if not self.is_isomorphic(EllipticCurve(k,[0,0,1,0,0])): + t = 2 * pi + if not self.is_isomorphic(EllipticCurve(k, [0, 0, 1, 0, 0])): t = -t else: t = pi - if self.is_isomorphic(EllipticCurve(k,[0,0,delta,0,0])): + if self.is_isomorphic(EllipticCurve(k, [0, 0, delta, 0, 0])): t = -t # p=3, j=0=1728 # # Number of isomorphism classes is 4 (odd degree) or 6 (even degree) # - elif p==3: - if d%2==1: + elif p == 3: + if d % 2: # The 4 classes are represented by [0,0,0,1,0], # [0,0,0,-1,0], [0,0,0,-1,a], [0,0,0,-1,-a] where a # has trace 1 @@ -188,13 +183,13 @@ def _cardinality_with_j_invariant_1728(self): u = delta.sqrt() if not u.is_square(): u = -u - tr = ((self.a3()**2+self.a6())/u).trace() - if tr==0: + tr = ((self.a3()**2 + self.a6()) / u).trace() + if tr == 0: t = 0 else: - d2 = (d+1)//2 + d2 = (d + 1) // 2 t = 3**d2 - if d2%2 == 1: + if d2 % 2: t = -t if tr == -1: t = -t @@ -207,13 +202,13 @@ def _cardinality_with_j_invariant_1728(self): # The curve is isomorphic to [0,0,0,A4,A6] - A4 = self.a4() - self.a1()*self.a3() # = -b4 = 2*b4 + A4 = self.a4() - self.a1() * self.a3() # = -b4 = 2*b4 if A4.is_square(): u = A4.sqrt() - t = (-3)**(d//2) + t = (-3)**(d // 2) i = k(-1).sqrt() A6 = self.a3()**2 + self.a6() # = b6 - if (A6/(i*u*A4)).trace()==0: + if (A6 / (i * u * A4)).trace() == 0: t *= 2 else: t *= -1 @@ -226,16 +221,16 @@ def _cardinality_with_j_invariant_1728(self): # # Number of isomorphism classes is 4 if q=1 (mod 4), else 2 # - elif p%4==3: - if d%2==1: + elif p % 4 == 3: + if d % 2: t = 0 else: - t = (-p)**(d//2) - w = (self.c4()/k(48))**((q-1)//4) + t = (-p)**(d // 2) + w = (self.c4() / k(48))**((q - 1) // 4) if w == 1: - t = 2*t + t = 2 * t elif w == -1: - t = -2*t + t = -2 * t else: t = 0 @@ -243,31 +238,31 @@ def _cardinality_with_j_invariant_1728(self): # N(pi)=p and N(pi-1)=0 (mod 8). # else: - R = ZZ.extension(x**2+1,'i') + R = ZZ.extension(x**2 + 1, 'i') i = R.gen(1) pi = R.fraction_field().factor(p)[0][0].gens_reduced()[0] - a,b = pi.list() - if a%2==0: - a,b = -b,a - if (a+b+1)%4==0: - a,b = -a,-b - pi = a+b*i # Now pi=a+b*i with (a,b)=(1,0),(3,2) mod 4 + a, b = pi.list() + if a % 2 == 0: + a, b = -b, a + if (a + b + 1) % 4 == 0: + a, b = -a, -b + pi = a + b * i # Now pi=a+b*i with (a,b)=(1,0),(3,2) mod 4 # Lift to Frobenius for [0,0,0,-1,0] over GF(p^d): - if d>1: + if d > 1: pi = pi**d - a,b = pi.list() + a, b = pi.list() # Compute appropriate quartic twist: - w = (self.c4()/k(48))**((q-1)//4) - if w==1: - t = 2*a - elif w==-1: - t = -2*a - elif k(b)==w*k(a): - t = 2*b + w = (self.c4() / k(48))**((q - 1) // 4) + if w == 1: + t = 2 * a + elif w == -1: + t = -2 * a + elif k(b) == w * k(a): + t = 2 * b else: - t = -2*b + t = -2 * b return Integer(q + 1 - t) @@ -282,19 +277,19 @@ def _cardinality_with_j_invariant_0(self): An example with q=p=1 (mod 6):: - sage: F=GF(1009) + sage: F = GF(1009) sage: [_cardinality_with_j_invariant_0(EllipticCurve(F,[0,0,0,0,11^i])) for i in range(6)] [948, 967, 1029, 1072, 1053, 991] An example with q=p=5 (mod 6):: - sage: F=GF(1013) + sage: F = GF(1013) sage: [_cardinality_with_j_invariant_0(EllipticCurve(F,[0,0,0,0,3^i])) for i in range(6)] [1014, 1014, 1014, 1014, 1014, 1014] An example with `q=p^2`, p=5 (mod 6):: - sage: F.=GF(1013^2,'a') + sage: F. = GF(1013^2,'a') sage: [_cardinality_with_j_invariant_0(EllipticCurve(F,[0,0,0,0,a^i])) for i in range(6)] [1028196, 1027183, 1025157, 1024144, 1025157, 1027183] @@ -302,29 +297,29 @@ def _cardinality_with_j_invariant_0(self): :func:`_cardinality_with_j_invariant_1728`. """ k = self.base_ring() - assert self.j_invariant()==k(0) + assert self.j_invariant() == k.zero() p = k.characteristic() - if p==2 or p==3: # then 0==1728 + if p == 2 or p == 3: # then 0==1728 return _cardinality_with_j_invariant_1728(self) q = k.cardinality() d = k.degree() - x=polygen(ZZ) + x = polygen(ZZ) # p>3, j=0 # # Number of isomorphism classes is 4 if q=1 (mod 4), else 2 # - if p%6==5: - if d%2==1: + if p % 6 == 5: + if d % 2: t = 0 else: - t = (-p)**(d//2) - w = (self.c6()/k(-864))**((q-1)//6) + t = (-p)**(d // 2) + w = (self.c6() / k(-864))**((q - 1) // 6) if w == 1: - t = 2*t + t = 2 * t elif w == -1: - t = -2*t + t = -2 * t elif w**3 == 1: t = -t @@ -332,45 +327,46 @@ def _cardinality_with_j_invariant_0(self): # N(pi)=p and N(pi-1)=0 (mod 12). # else: - R = ZZ.extension(x**2-x+1,'zeta6') + R = ZZ.extension(x**2 - x + 1, 'zeta6') zeta6 = R.gen(1) pi = R.fraction_field().factor(p)[0][0].gens_reduced()[0] while (pi - 1).norm() % 12: pi *= zeta6 - a,b = pi.list() - z = k(-b)/k(a) # a *specific* 6th root of unity in k + a, b = pi.list() + z = k(-b) / k(a) # a *specific* 6th root of unity in k # Now pi=a+b*zeta6 with N(pi-1)=0 (mod 12) # Lift to Frobenius for [0,0,0,0,1] over GF(p^d): - if d>1: + if d > 1: pi = pi**d - a,b = pi.list() + a, b = pi.list() # Compute appropriate sextic twist: - w = (self.c6()/k(-864))**((q-1)//6) + w = (self.c6() / k(-864))**((q - 1) // 6) if w == 1: - t = 2*a+b # = Trace(pi) + t = 2 * a + b # = Trace(pi) elif w == -1: - t = -2*a-b # = Trace(-pi) + t = -2 * a - b # = Trace(-pi) elif w == z: - t = a-b # = Trace(pi*zeta6) + t = a - b # = Trace(pi*zeta6) elif w == z**2: - t = -a-2*b # = Trace(pi*zeta6**2) + t = -a - 2 * b # = Trace(pi*zeta6**2) elif w == z**4: - t = b-a # = Trace(pi*zeta6**4) + t = b - a # = Trace(pi*zeta6**4) elif w == z**5: - t = a+2*b # = Trace(pi*zeta6**5) + t = a + 2 * b # = Trace(pi*zeta6**5) return Integer(q + 1 - t) def cardinality_exhaustive(self): r""" - Return the cardinality of self over the base field. Simply adds up - the number of points with each x-coordinate: only used for small - field sizes! + Return the cardinality of ``self`` over the base field. + + This simply adds up the number of points with each x-coordinate: + only used for small field sizes! EXAMPLES:: @@ -382,13 +378,14 @@ def cardinality_exhaustive(self): sage: E.cardinality_exhaustive() 64 """ - self._order = Integer(1+sum([len(self.lift_x(x,all=True)) for x in self.base_field()])) + self._order = Integer(1 + sum(len(self.lift_x(x, all=True)) + for x in self.base_field())) return self._order def cardinality_bsgs(self, verbose=False): r""" - Return the cardinality of self over the base field. + Return the cardinality of ``self`` over the base field. ALGORITHM: A variant of "Mestre's trick" extended to all finite fields by Cremona and Sutherland, 2008. @@ -404,15 +401,15 @@ def cardinality_bsgs(self, verbose=False): EXAMPLES:: - sage: p=next_prime(10^3) - sage: E=EllipticCurve(GF(p),[3,4]) + sage: p = next_prime(10^3) + sage: E = EllipticCurve(GF(p),[3,4]) sage: E.cardinality_bsgs() 1020 - sage: E=EllipticCurve(GF(3^4,'a'),[1,1]) + sage: E = EllipticCurve(GF(3^4,'a'),[1,1]) sage: E.cardinality_bsgs() 64 - sage: F.=GF(101^3,'a') - sage: E=EllipticCurve([2*a^2 + 48*a + 27, 89*a^2 + 76*a + 24]) + sage: F. = GF(101^3,'a') + sage: E = EllipticCurve([2*a^2 + 48*a + 27, 89*a^2 + 76*a + 24]) sage: E.cardinality_bsgs() 1031352 """ @@ -431,12 +428,12 @@ def cardinality_bsgs(self, verbose=False): bounds = Hasse_bounds(q) lower, upper = bounds - B = upper-q-1 # = floor(2*sqrt(q)) + B = upper - q - 1 # = floor(2*sqrt(q)) a = ZZ(0) N1 = N2 = M = ZZ(1) kmin = -B kmax = B - q1 = q+1 + q1 = q + 1 # Throughout, we have #E=q+1-t where |t|<=B and t=a+k*M = a # (mod M) where kmin <= k <= kmax. @@ -445,28 +442,28 @@ def cardinality_bsgs(self, verbose=False): # kmin=kmax. if q > 2**10: - N1 = ZZ(2)**sum([e for P,e in E1._p_primary_torsion_basis(2)]) - N2 = ZZ(2)**sum([e for P,e in E2._p_primary_torsion_basis(2)]) + N1 = ZZ(2)**sum([e for P, e in E1._p_primary_torsion_basis(2)]) + N2 = ZZ(2)**sum([e for P, e in E2._p_primary_torsion_basis(2)]) if q > 2**20: - N1 *= ZZ(3)**sum([e for P,e in E1._p_primary_torsion_basis(3)]) - N2 *= ZZ(3)**sum([e for P,e in E2._p_primary_torsion_basis(3)]) + N1 *= ZZ(3)**sum([e for P, e in E1._p_primary_torsion_basis(3)]) + N2 *= ZZ(3)**sum([e for P, e in E2._p_primary_torsion_basis(3)]) if q > 2**40: - N1 *= ZZ(5)**sum([e for P,e in E1._p_primary_torsion_basis(5)]) - N2 *= ZZ(5)**sum([e for P,e in E2._p_primary_torsion_basis(5)]) + N1 *= ZZ(5)**sum([e for P, e in E1._p_primary_torsion_basis(5)]) + N2 *= ZZ(5)**sum([e for P, e in E2._p_primary_torsion_basis(5)]) # We now know that t=q+1 (mod N1) and t=-(q+1) (mod N2) a = q1 M = N1 - g,u,v = M.xgcd(N2) # g==u*M+v*N2 - if N2>g: - a = (a*v*N2-q1*u*M)//g - M *= (N2//g) # = lcm(M,N2) - a = a%M + g, u, v = M.xgcd(N2) # g==u*M+v*N2 + if N2 > g: + a = (a * v * N2 - q1 * u * M) // g + M *= (N2 // g) # = lcm(M,N2) + a = a % M if verbose: print("(a,M)=", (a, M)) - kmin = ((-B-a)/M).ceil() - kmax = ((B-a)/M).floor() - if kmin==kmax: - self._order = q1-a-kmin*M + kmin = ((-B - a) / M).ceil() + kmax = ((B - a) / M).floor() + if kmin == kmax: + self._order = q1 - a - kmin * M if verbose: print("no random points were needed") return self._order @@ -478,51 +475,51 @@ def cardinality_bsgs(self, verbose=False): # points on each curve. For large q it is worth initializing # these with the full order of the (2,3,5)-torsion which are # often non-trivial. - while kmax!=kmin: + while kmax != kmin: # Get a random point on E1 and find its order, using the # Hasse bounds and the fact that we know that the group # order is a multiple of N1: - n = order_from_bounds(E1.random_point(),bounds,N1,operation='+') + n = order_from_bounds(E1.random_point(), bounds, N1, operation='+') if verbose: print("New point on E has order ", n) # update N1 and M N1 = N1.lcm(n) - g,u,v = M.xgcd(n) # g==u*M+v*n - if n>g: + g, u, v = M.xgcd(n) # g==u*M+v*n + if n > g: # update congruence a (mod M) with q+1 (mod n) - a = (a*v*n+q1*u*M)//g - M *= (n//g) # = lcm(M,n) - a = a%M + a = (a * v * n + q1 * u * M) // g + M *= (n // g) # = lcm(M,n) + a = a % M if verbose: print("(a,M)=", (a, M)) - kmin = ((-B-a)/M).ceil() - kmax = ((B-a)/M).floor() - if kmin==kmax: - self._order = q1-a-kmin*M + kmin = ((-B - a) / M).ceil() + kmax = ((B - a) / M).floor() + if kmin == kmax: + self._order = q1 - a - kmin * M return self._order if verbose: - print("number of possibilities is now ",kmax-kmin+1) + print("number of possibilities is now ", kmax - kmin + 1) # Get a random point on E2 and find its order, using the # Hasse bounds and the fact that we know that the group # order is a multiple of N2: - n = order_from_bounds(E2.random_point(),bounds,N2,operation='+') + n = order_from_bounds(E2.random_point(), bounds, N2, operation='+') if verbose: print("New point on E' has order ", n) # update N2 and M N2 = N2.lcm(n) - g,u,v = M.xgcd(n) # g==u*M+v*n - if n>g: + g, u, v = M.xgcd(n) # g==u*M+v*n + if n > g: # update congruence a (mod M) with -(q+1) (mod n) - a = (a*v*n-q1*u*M)//g - M *= (n//g) # = lcm(M,n) - a = a%M + a = (a * v * n - q1 * u * M) // g + M *= (n // g) # = lcm(M,n) + a = a % M if verbose: print("(a,M)=", (a, M)) - kmin = ((-B-a)/M).ceil() - kmax = ((B-a)/M).floor() - if kmin==kmax: - self._order = q1-a-kmin*M + kmin = ((-B - a) / M).ceil() + kmax = ((B - a) / M).floor() + if kmin == kmax: + self._order = q1 - a - kmin * M return self._order if verbose: print("number of possibilities is now ", kmax - kmin + 1) @@ -598,4 +595,4 @@ def _cardinality_subfield(self, jpol): return N else: q = k.cardinality() - return 2*(q+1) - N + return 2 * (q + 1) - N From 9080ed5a295e04d273d165be689eebdef8578a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 16 Oct 2022 20:22:23 +0200 Subject: [PATCH 322/350] a few details in Brandt modules --- src/sage/modular/quatalg/brandt.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/sage/modular/quatalg/brandt.py b/src/sage/modular/quatalg/brandt.py index 996e9287697..f639137bbf0 100644 --- a/src/sage/modular/quatalg/brandt.py +++ b/src/sage/modular/quatalg/brandt.py @@ -218,6 +218,7 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.rational_field import QQ from sage.rings.ring import CommutativeRing from sage.structure.richcmp import richcmp, richcmp_method @@ -490,7 +491,7 @@ def quaternion_order_with_given_level(A, level): level = abs(level) N = A.discriminant() N1 = gcd(level, N) - M1 = level / N1 + M1 = level // N1 O = maximal_order(A) # if N1 != 1: @@ -1034,7 +1035,7 @@ def hecke_matrix(self, n, algorithm='default', sparse=False, B=None): """ n = ZZ(n) if n <= 0: - raise IndexError("n must be positive.") + raise IndexError("n must be positive") if n not in self._hecke_matrices: if algorithm == 'default': try: @@ -1055,7 +1056,7 @@ def hecke_matrix(self, n, algorithm='default', sparse=False, B=None): elif algorithm == 'brandt': T = self._compute_hecke_matrix_brandt(n, sparse=sparse) else: - raise ValueError("unknown algorithm '%s'" % algorithm) + raise ValueError(f"unknown algorithm '{algorithm}'") T.set_immutable() self._hecke_matrices[n] = T return self._hecke_matrices[n] @@ -1517,7 +1518,7 @@ def brandt_series(self, prec, var='q'): [ 1/6 + 2*t^2 + O(t^3) 1/6 + t + O(t^3)] """ A = self._brandt_series_vectors(prec) - R = QQ[[var]] + R = PowerSeriesRing(QQ, var) n = len(A[0]) return matrix(R, n, n, [[R(x.list()[:prec], prec) for x in Y] for Y in A]) @@ -1560,7 +1561,7 @@ def eisenstein_subspace(self): V = A.kernel() return V - def is_cuspidal(self): + def is_cuspidal(self) -> bool: r""" Return whether ``self`` is cuspidal, i.e. has no Eisenstein part. @@ -1584,7 +1585,7 @@ def monodromy_weights(self): fixed choice of basis. The weight of an ideal class `[I]` is half the number of units of the right order `I`. - NOTE: The base ring must be `\QQ` or `\ZZ`. + .. NOTE:: The base ring must be `\QQ` or `\ZZ`. EXAMPLES:: @@ -1619,9 +1620,9 @@ def monodromy_weights(self): return tuple(a[1] / a[0] / 2 for a in thetas) -############################################################################# -# Benchmarking -############################################################################# +# ==================== +# Benchmarking +# ==================== def benchmark_magma(levels, silent=False): """ INPUT: From 6d31aad9f67f9ff414b4dbdce70444d9f0b69004 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Mon, 17 Oct 2022 00:28:27 +0200 Subject: [PATCH 323/350] Updated SageMath version to 9.8.beta2 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 25 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 999a424d8d2..bfc70cb35aa 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.8.beta1", - "version": "9.8.beta1", + "title": "sagemath/sage: 9.8.beta2", + "version": "9.8.beta2", "upload_type": "software", - "publication_date": "2022-09-29", + "publication_date": "2022-10-16", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.8.beta1", + "identifier": "https://github.com/sagemath/sage/tree/9.8.beta2", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index 5a632a27b46..a62ad931e8c 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.8.beta1, Release Date: 2022-09-29 +SageMath version 9.8.beta2, Release Date: 2022-10-16 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 9a76bd27545..9fe6d411d8c 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=2f4aa4b3eaa90d73b67907839f761af1f33ef978 -md5=4d3a0c6c5cc46758789f117cc5c64a9c -cksum=3260232553 +sha1=fc62adb78d1bfe0550aeead0e334c65fd62ab948 +md5=35bf13a54ceb4b127196394ddc1d3dfd +cksum=7184729 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index d30e2e584d2..88084f87852 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -cfb40bc006de1c9273edfd4519d8d8021d9c5ff5 +7acd286410f4a87b7d4be79473e2d90f9fdbe79e diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 8e33acc92e6..1a0b2bc1457 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 9.8b1 +sage-conf ~= 9.8b2 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index a2cc79f66c9..93266bbb15b 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 9.8b1 +sage-docbuild ~= 9.8b2 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 050098266b7..2c6b94be041 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 9.8b1 +sage-setup ~= 9.8b2 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index ca58fa64648..fdcef24cdd4 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 9.8b1 +sage-sws2rst ~= 9.8b2 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 82d6db622ed..7ecd279caab 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 9.8b1 +sagelib ~= 9.8b2 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index f5c2a080bae..cb1cb7106c8 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 9.8b1 +sagemath-categories ~= 9.8b2 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 5ac02d56d50..8138a64abd8 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 9.8b1 +sagemath-environment ~= 9.8b2 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 24f5473ae33..ee5931a4236 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 9.8b1 +sagemath-objects ~= 9.8b2 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 9d91ae25d19..4445ac6e934 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 9.8b1 +sagemath-repl ~= 9.8b2 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/src/VERSION.txt b/src/VERSION.txt index 737bfe2c1d2..0d493e35378 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.8.beta1 +9.8.beta2 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 4f92b35ee39..7942e09574b 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.8.beta1' -SAGE_RELEASE_DATE='2022-09-29' -SAGE_VERSION_BANNER='SageMath version 9.8.beta1, Release Date: 2022-09-29' +SAGE_VERSION='9.8.beta2' +SAGE_RELEASE_DATE='2022-10-16' +SAGE_VERSION_BANNER='SageMath version 9.8.beta2, Release Date: 2022-10-16' diff --git a/src/sage/version.py b/src/sage/version.py index 96d65f23372..7961b87efa6 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.8.beta1' -date = '2022-09-29' -banner = 'SageMath version 9.8.beta1, Release Date: 2022-09-29' +version = '9.8.beta2' +date = '2022-10-16' +banner = 'SageMath version 9.8.beta2, Release Date: 2022-10-16' From 30259c6c8a695c528e48b9e6bd9e18eb8a67eab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 17 Oct 2022 01:00:20 -0300 Subject: [PATCH 324/350] Fix a doctest failure due to a small numerical issue This only triggers when running maxima-sbcl on 32 bit, which gives: sage: maxima('exp(-sqrt(x))').nintegral('x',0,1) (0.5284822353142306, 4.163291933423352e-11, 231, 0) Compare to the "normal" result (64 bit, maxima-ecl on 32 bit): sage: maxima('exp(-sqrt(x))').nintegral('x',0,1) (0.5284822353142306, 4.163314137883845e-11, 231, 0) Since the difference is in the bound for the error in the numerical integration, it doesn't seem very important. --- src/sage/interfaces/maxima_abstract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 3c563149393..3fb1a53a893 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1523,7 +1523,7 @@ def nintegral(self, var='x', a=0, b=1, EXAMPLES:: sage: maxima('exp(-sqrt(x))').nintegral('x',0,1) - (0.5284822353142306, 4.1633141378838...e-11, 231, 0) + (0.5284822353142306, 4.163...e-11, 231, 0) Note that GP also does numerical integration, and can do so to very high precision very quickly:: From 779b1dff1ab6f73624ec2b2f6e2394d74c1efc9d Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 17 Oct 2022 12:22:41 +0100 Subject: [PATCH 325/350] update topcom to 1.1.2 --- build/pkgs/topcom/checksums.ini | 9 +- build/pkgs/topcom/package-version.txt | 2 +- .../topcom/patches/no_vendor_cddlib.patch | 2189 +++++++++++++++++ 3 files changed, 2195 insertions(+), 5 deletions(-) create mode 100644 build/pkgs/topcom/patches/no_vendor_cddlib.patch diff --git a/build/pkgs/topcom/checksums.ini b/build/pkgs/topcom/checksums.ini index 8c0bffb0731..764c422b5ac 100644 --- a/build/pkgs/topcom/checksums.ini +++ b/build/pkgs/topcom/checksums.ini @@ -1,4 +1,5 @@ -tarball=topcom-VERSION.tar.bz2 -sha1=e772365e7115289dfb1f75f28c335ec9d5feb0f1 -md5=117708cc3fdbb3368631c69e3cc95f1c -cksum=340369649 +tarball=TOPCOM-1_1_2.tgz +sha1=65db8c00309f3bf8467ee5ba9da109c196db3461 +md5=dbda1ae7946251c9502444ee9b0a2c62 +cksum=1598684291 +upstream_url=https://users.ox.ac.uk/~coml0531/tmp/TOPCOM-1_1_2.tgz diff --git a/build/pkgs/topcom/package-version.txt b/build/pkgs/topcom/package-version.txt index 793949533eb..45a1b3f4452 100644 --- a/build/pkgs/topcom/package-version.txt +++ b/build/pkgs/topcom/package-version.txt @@ -1 +1 @@ -0.17.7 +1.1.2 diff --git a/build/pkgs/topcom/patches/no_vendor_cddlib.patch b/build/pkgs/topcom/patches/no_vendor_cddlib.patch new file mode 100644 index 00000000000..b9e6c97a4ec --- /dev/null +++ b/build/pkgs/topcom/patches/no_vendor_cddlib.patch @@ -0,0 +1,2189 @@ +diff --git a/INSTALL b/INSTALL +index 9d4fccc..8865734 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -1,284 +1,368 @@ +-Remark concerning consistent 32 resp. 64 bit compilation +-======================================================== ++Installation Instructions ++************************* + +-The easiest way to guarantee consistent compilation is +-to configure with explicit setting of CFLAGS and CXXFLAGS +-to "-m32" or "-m64". This can be achieved by calling ++ Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software ++Foundation, Inc. + +- ./configure [other-configure-options-see-below] CFLAGS="-m64" CXXFLAGS="-m64" ++ Copying and distribution of this file, with or without modification, ++are permitted in any medium without royalty provided the copyright ++notice and this notice are preserved. This file is offered as-is, ++without warranty of any kind. + +-This way, all C/C++-Compilations are carried out with +-the corresponding compiler flag. +- +- +-Remark concerning external packages gmp, cdd, and qsopt_ex +-========================================================== +- +-If gmp, cddlib, or qsopt_ex are missing on your system then configure will +-build the version coming with TOPCOM in the `external' subdirectory +-of the TOPCOM root directory. +- +-If $(TOPCOM_DIRECTORY) is the root directory of the TOPCOM package, then +-the necessary files are installed into +- +- $(TOPCOM_DIRECTORY)/external/include +- $(TOPCOM_DIRECTORY)/external/lib ++Basic Installation ++================== + ++ Briefly, the shell command './configure && make && make install' ++should configure, build, and install this package. The following ++more-detailed instructions are generic; see the 'README' file for ++instructions specific to this package. Some packages provide this ++'INSTALL' file but do not implement all of the features documented ++below. The lack of an optional feature in a given package is not ++necessarily a bug. More recommendations for GNU packages can be found ++in *note Makefile Conventions: (standards)Makefile Conventions. + +-Remark concerning the pacakged cddlib LP solver library +-======================================================= ++ The 'configure' shell script attempts to guess correct values for ++various system-dependent variables used during compilation. It uses ++those values to create a 'Makefile' in each directory of the package. ++It may also create one or more '.h' files containing system-dependent ++definitions. Finally, it creates a shell script 'config.status' that ++you can run in the future to recreate the current configuration, and a ++file 'config.log' containing compiler output (useful mainly for ++debugging 'configure'). ++ ++ It can also use an optional file (typically called 'config.cache' and ++enabled with '--cache-file=config.cache' or simply '-C') that saves the ++results of its tests to speed up reconfiguring. Caching is disabled by ++default to prevent problems with accidental use of stale cache files. + +-The packaaged LP solver in cddlib is not thread-safe out of the box. +-Therefore, the version packaged with TOPCOM has been patched to version +-0.94j-TOPCOM. This patched version will be compiled with C++ and +-has thread_local global variables. This is enough to make cddlib +-threadsafe, thus, parallel enumeration can be used. ++ If you need to do unusual things to compile the package, please try ++to figure out how 'configure' could check whether to do them, and mail ++diffs or instructions to the address given in the 'README' so they can ++be considered for the next release. If you are using the cache, and at ++some point 'config.cache' contains results you don't want to keep, you ++may remove or edit it. ++ ++ The file 'configure.ac' (or 'configure.in') is used to create ++'configure' by a program called 'autoconf'. You need 'configure.ac' if ++you want to change it or regenerate 'configure' using a newer version of ++'autoconf'. ++ ++ The simplest way to compile this package is: ++ ++ 1. 'cd' to the directory containing the package's source code and type ++ './configure' to configure the package for your system. ++ ++ Running 'configure' might take a while. While running, it prints ++ some messages telling which features it is checking for. ++ ++ 2. Type 'make' to compile the package. ++ ++ 3. Optionally, type 'make check' to run any self-tests that come with ++ the package, generally using the just-built uninstalled binaries. ++ ++ 4. Type 'make install' to install the programs and any data files and ++ documentation. When installing into a prefix owned by root, it is ++ recommended that the package be configured and built as a regular ++ user, and only the 'make install' phase executed with root ++ privileges. ++ ++ 5. Optionally, type 'make installcheck' to repeat any self-tests, but ++ this time using the binaries in their final installed location. ++ This target does not install anything. Running this target as a ++ regular user, particularly if the prior 'make install' required ++ root privileges, verifies that the installation completed ++ correctly. ++ ++ 6. You can remove the program binaries and object files from the ++ source code directory by typing 'make clean'. To also remove the ++ files that 'configure' created (so you can compile the package for ++ a different kind of computer), type 'make distclean'. There is ++ also a 'make maintainer-clean' target, but that is intended mainly ++ for the package's developers. If you use it, you may have to get ++ all sorts of other programs in order to regenerate files that came ++ with the distribution. + ++ 7. Often, you can also type 'make uninstall' to remove the installed ++ files again. In practice, not all packages have tested that ++ uninstallation works correctly, even though it is required by the ++ GNU Coding Standards. + +-Remark concerning the pacakged qsopt_ex LP solver library +-========================================================= ++ 8. Some packages, particularly those that use Automake, provide 'make ++ distcheck', which can by used by developers to test that all other ++ targets like 'make install' and 'make uninstall' work correctly. ++ This target is generally not run by end users. + +-Configuring with option ++Compilers and Options ++===================== + +- ./configure --enable-qsoptex ++ Some systems require unusual options for compilation or linking that ++the 'configure' script does not know about. Run './configure --help' ++for details on some of the pertinent environment variables. + +-compiles a binary with QSOpt_ex support. ++ You can give 'configure' initial values for configuration parameters ++by setting variables in the command line or in the environment. Here is ++an example: + +-The packaaged LP solver QSOpt_ex is very fast but not threadsafe. +-Therefore, if you use it (option --qsoptex), then no parallel enumeration +-will be carried out. Still, the internal memory managament +-of qsopt_ex may core-dump at the very end of the run. +-I have no idea why. This all happens after the TOPCOM computations +-have finished. So, the results should be ok anyway. ++ ./configure CC=c99 CFLAGS=-g LIBS=-lposix + ++ *Note Defining Variables::, for more details. + +-Remark concerning the soplex LP solver library (versions >= 6.0.0) +-================================================================== ++Compiling For Multiple Architectures ++==================================== + +-The academic licence of soplex does not allow a common delivery within +-the TOPCOM package. Therefore, if you want to use soplex you must +-install it in a place where it can be found by the compiler and +-the linker. This is slightly tedious but rewarding, since +-soplex is faster than cddlib. ++ You can compile the package for more than one kind of computer at the ++same time, by placing the object files for each architecture in their ++own directory. To do this, you can use GNU 'make'. 'cd' to the ++directory where you want the object files and executables to go and run ++the 'configure' script. 'configure' automatically checks for the source ++code in the directory that 'configure' is in and in '..'. This is known ++as a "VPATH" build. ++ ++ With a non-GNU 'make', it is safer to compile the package for one ++architecture at a time in the source code directory. After you have ++installed the package for one architecture, use 'make distclean' before ++reconfiguring for another architecture. ++ ++ On MacOS X 10.5 and later systems, you can create libraries and ++executables that work on multiple system types--known as "fat" or ++"universal" binaries--by specifying multiple '-arch' options to the ++compiler but only a single '-arch' option to the preprocessor. Like ++this: + +-Using soplex requires libsoplex.a in ${TOPCOM_DIRECTORY}/external/lib and +-all the soplex includes in ${TOPCOM_DIRECTORY}/external/include. +-As 6.0.0 of soplex, the boost includes are required in the same place. +-This changed, e.g., the access to the underlying gmp rationals. +-Therefore, versions of soplex prior to 6.0.0 are not supported out +-of the box. ++ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ ++ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ ++ CPP="gcc -E" CXXCPP="g++ -E" + +-In order to use soplex, I recommend to place symbolic links in +-${TOPCOM_DIRECTORY}/external/lib to the libraries and all the soplex includes +-in ${TOPCOM_DIRECTORY}/external/include. +-(This method supports that non-superusers can install TOPCOM locally +-without the help of a system-administrator.) ++ This is not guaranteed to produce working output in all cases, you ++may have to build one architecture at a time and combine the results ++using the 'lipo' tool if you have problems. + +-Summarized, if you have the includes and the libs of soplex 6.0.0 +-or later below ${SOPLEX_INCLUDES_DIR} and ${SOPLEX_LIBS_DIR}, resp., +-and boost below ${BOOST_INCLUDES_DIR}, then you can start with ++Installation Names ++================== + +- ./configure --enable-soplex ++ By default, 'make install' installs the package's commands under ++'/usr/local/bin', include files under '/usr/local/include', etc. You ++can specify an installation prefix other than '/usr/local' by giving ++'configure' the option '--prefix=PREFIX', where PREFIX must be an ++absolute file name. + +-to activate the soplex support in TOPCOM. Then you can place +-the symbolic links by ++ You can specify separate installation prefixes for ++architecture-specific files and architecture-independent files. If you ++pass the option '--exec-prefix=PREFIX' to 'configure', the package uses ++PREFIX as the prefix for installing programs and libraries. ++Documentation and other data files still use the regular prefix. + +- cd ${TOPCOM_DIRECTORY}/external/ +- cd include +- ln -s ${SOPLEX_INCLUDES_DIR}/soplex* . +- ln -s ${BOOST_INCLUDES_DIR}/boost . +- cd ../lib +- ln -s ${SOPLEX_LIBS_DIR}/libsoplex*.a . +- cd ../.. ++ In addition, if you use an unusual directory layout you can give ++options like '--bindir=DIR' to specify different values for particular ++kinds of files. Run 'configure --help' for a list of the directories ++you can set and what kinds of files go in them. In general, the default ++for these options is expressed in terms of '${prefix}', so that ++specifying just '--prefix' will affect all of the other directory ++specifications that were not explicitly provided. ++ ++ The most portable way to affect installation locations is to pass the ++correct locations to 'configure'; however, many packages provide one or ++both of the following shortcuts of passing variable assignments to the ++'make install' command line to change installation locations without ++having to reconfigure or recompile. ++ ++ The first method involves providing an override variable for each ++affected directory. For example, 'make install ++prefix=/alternate/directory' will choose an alternate location for all ++directory configuration variables that were expressed in terms of ++'${prefix}'. Any directories that were specified during 'configure', ++but not in terms of '${prefix}', must each be overridden at install time ++for the entire installation to be relocated. The approach of makefile ++variable overrides for each directory variable is required by the GNU ++Coding Standards, and ideally causes no recompilation. However, some ++platforms have known limitations with the semantics of shared libraries ++that end up requiring recompilation when using this method, particularly ++noticeable in packages that use GNU Libtool. ++ ++ The second method involves providing the 'DESTDIR' variable. For ++example, 'make install DESTDIR=/alternate/directory' will prepend ++'/alternate/directory' before all installation names. The approach of ++'DESTDIR' overrides is not required by the GNU Coding Standards, and ++does not work on platforms that have drive letters. On the other hand, ++it does better at avoiding recompilation issues, and works well even ++when some directory options were not specified in terms of '${prefix}' ++at 'configure' time. + +-to link the includes and libraries to the right place where TOPCOM can +-find them. Finally, just ++Optional Features ++================= + +- make +- make install ++ If the package supports it, you can cause programs to be installed ++with an extra prefix or suffix on their names by giving 'configure' the ++option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. ++ ++ Some packages pay attention to '--enable-FEATURE' options to ++'configure', where FEATURE indicates an optional part of the package. ++They may also pay attention to '--with-PACKAGE' options, where PACKAGE ++is something like 'gnu-as' or 'x' (for the X Window System). The ++'README' should mention any '--enable-' and '--with-' options that the ++package recognizes. + +-and you are set. ++ For packages that use the X Window System, 'configure' can usually ++find the X include and library files automatically, but if it doesn't, ++you can use the 'configure' options '--x-includes=DIR' and ++'--x-libraries=DIR' to specify their locations. + ++ Some packages offer the ability to configure how verbose the ++execution of 'make' will be. For these packages, running './configure ++--enable-silent-rules' sets the default to minimal output, which can be ++overridden with 'make V=1'; while running './configure ++--disable-silent-rules' sets the default to verbose, which can be ++overridden with 'make V=0'. + +-Basic Installation ++Particular systems + ================== + +- These are generic installation instructions. ++ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC ++is not installed, it is recommended to use the following options in ++order to use an ANSI C compiler: + +- The `configure' shell script attempts to guess correct values for +-various system-dependent variables used during compilation. It uses +-those values to create a `Makefile' in each directory of the package. +-It may also create one or more `.h' files containing system-dependent +-definitions. Finally, it creates a shell script `config.status' that +-you can run in the future to recreate the current configuration, a file +-`config.cache' that saves the results of its tests to speed up +-reconfiguring, and a file `config.log' containing compiler output +-(useful mainly for debugging `configure'). ++ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +- If you need to do unusual things to compile the package, please try +-to figure out how `configure' could check whether to do them, and mail +-diffs or instructions to the address given in the `README' so they can +-be considered for the next release. If at some point `config.cache' +-contains results you don't want to keep, you may remove or edit it. ++and if that doesn't work, install pre-built binaries of GCC for HP-UX. + +- The file `configure.in' is used to create `configure' by a program +-called `autoconf'. You only need `configure.in' if you want to change +-it or regenerate `configure' using a newer version of `autoconf'. ++ HP-UX 'make' updates targets which have the same time stamps as their ++prerequisites, which makes it generally unusable when shipped generated ++files such as 'configure' are involved. Use GNU 'make' instead. + +-The simplest way to compile this package is: ++ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot ++parse its '' header file. The option '-nodtk' can be used as a ++workaround. If GNU CC is not installed, it is therefore recommended to ++try + +- 1. `cd' to the directory containing the package's source code and type +- `./configure' to configure the package for your system. If you're +- using `csh' on an old version of System V, you might need to type +- `sh ./configure' instead to prevent `csh' from trying to execute +- `configure' itself. ++ ./configure CC="cc" + +- Running `configure' takes awhile. While running, it prints some +- messages telling which features it is checking for. ++and if that doesn't work, try + +- 2. Type `make' to compile the package. ++ ./configure CC="cc -nodtk" + +- 3. Optionally, type `make check' to run any self-tests that come with +- the package. ++ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This ++directory contains several dysfunctional programs; working variants of ++these programs are available in '/usr/bin'. So, if you need '/usr/ucb' ++in your 'PATH', put it _after_ '/usr/bin'. + +- 4. Type `make install' to install the programs and any data files and +- documentation. ++ On Haiku, software installed for all users goes in '/boot/common', ++not '/usr/local'. It is recommended to use the following options: + +- 5. You can remove the program binaries and object files from the +- source code directory by typing `make clean'. To also remove the +- files that `configure' created (so you can compile the package for +- a different kind of computer), type `make distclean'. There is +- also a `make maintainer-clean' target, but that is intended mainly +- for the package's developers. If you use it, you may have to get +- all sorts of other programs in order to regenerate files that came +- with the distribution. ++ ./configure --prefix=/boot/common + +-Compilers and Options +-===================== +- +- Some systems require unusual options for compilation or linking that +-the `configure' script does not know about. You can give `configure' +-initial values for variables by setting them in the environment. Using +-a Bourne-compatible shell, you can do that on the command line like +-this: +- CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure ++Specifying the System Type ++========================== + +-Or on systems that have the `env' program, you can do it like this: +- env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure ++ There may be some features 'configure' cannot figure out ++automatically, but needs to determine by the type of machine the package ++will run on. Usually, assuming the package is built to be run on the ++_same_ architectures, 'configure' can figure that out, but if it prints ++a message saying it cannot guess the machine type, give it the ++'--build=TYPE' option. TYPE can either be a short name for the system ++type, such as 'sun4', or a canonical name which has the form: + +-Compiling For Multiple Architectures +-==================================== ++ CPU-COMPANY-SYSTEM + +- You can compile the package for more than one kind of computer at the +-same time, by placing the object files for each architecture in their +-own directory. To do this, you must use a version of `make' that +-supports the `VPATH' variable, such as GNU `make'. `cd' to the +-directory where you want the object files and executables to go and run +-the `configure' script. `configure' automatically checks for the +-source code in the directory that `configure' is in and in `..'. ++where SYSTEM can have one of these forms: + +- If you have to use a `make' that does not supports the `VPATH' +-variable, you have to compile the package for one architecture at a time +-in the source code directory. After you have installed the package for +-one architecture, use `make distclean' before reconfiguring for another +-architecture. ++ OS ++ KERNEL-OS + +-Installation Names +-================== ++ See the file 'config.sub' for the possible values of each field. If ++'config.sub' isn't included in this package, then this package doesn't ++need to know the machine type. + +- By default, `make install' will install the package's files in +-`/usr/local/bin', `/usr/local/man', etc. You can specify an +-installation prefix other than `/usr/local' by giving `configure' the +-option `--prefix=PATH'. ++ If you are _building_ compiler tools for cross-compiling, you should ++use the option '--target=TYPE' to select the type of system they will ++produce code for. + +- You can specify separate installation prefixes for +-architecture-specific files and architecture-independent files. If you +-give `configure' the option `--exec-prefix=PATH', the package will use +-PATH as the prefix for installing programs and libraries. +-Documentation and other data files will still use the regular prefix. ++ If you want to _use_ a cross compiler, that generates code for a ++platform different from the build platform, you should specify the ++"host" platform (i.e., that on which the generated programs will ++eventually be run) with '--host=TYPE'. + +- In addition, if you use an unusual directory layout you can give +-options like `--bindir=PATH' to specify different values for particular +-kinds of files. Run `configure --help' for a list of the directories +-you can set and what kinds of files go in them. ++Sharing Defaults ++================ + +- If the package supports it, you can cause programs to be installed +-with an extra prefix or suffix on their names by giving `configure' the +-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. ++ If you want to set default values for 'configure' scripts to share, ++you can create a site shell script called 'config.site' that gives ++default values for variables like 'CC', 'cache_file', and 'prefix'. ++'configure' looks for 'PREFIX/share/config.site' if it exists, then ++'PREFIX/etc/config.site' if it exists. Or, you can set the ++'CONFIG_SITE' environment variable to the location of the site script. ++A warning: not all 'configure' scripts look for a site script. + +-Optional Features +-================= ++Defining Variables ++================== + +- Some packages pay attention to `--enable-FEATURE' options to +-`configure', where FEATURE indicates an optional part of the package. +-They may also pay attention to `--with-PACKAGE' options, where PACKAGE +-is something like `gnu-as' or `x' (for the X Window System). The +-`README' should mention any `--enable-' and `--with-' options that the +-package recognizes. ++ Variables not defined in a site shell script can be set in the ++environment passed to 'configure'. However, some packages may run ++configure again during the build, and the customized values of these ++variables may be lost. In order to avoid this problem, you should set ++them in the 'configure' command line, using 'VAR=value'. For example: + +- For packages that use the X Window System, `configure' can usually +-find the X include and library files automatically, but if it doesn't, +-you can use the `configure' options `--x-includes=DIR' and +-`--x-libraries=DIR' to specify their locations. ++ ./configure CC=/usr/local2/bin/gcc + +-Specifying the System Type +-========================== ++causes the specified 'gcc' to be used as the C compiler (unless it is ++overridden in the site shell script). + +- There may be some features `configure' can not figure out +-automatically, but needs to determine by the type of host the package +-will run on. Usually `configure' can figure that out, but if it prints +-a message saying it can not guess the host type, give it the +-`--host=TYPE' option. TYPE can either be a short name for the system +-type, such as `sun4', or a canonical name with three fields: +- CPU-COMPANY-SYSTEM ++Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an ++Autoconf limitation. Until the limitation is lifted, you can use this ++workaround: + +-See the file `config.sub' for the possible values of each field. If +-`config.sub' isn't included in this package, then this package doesn't +-need to know the host type. ++ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +- If you are building compiler tools for cross-compiling, you can also +-use the `--target=TYPE' option to select the type of system they will +-produce code for and the `--build=TYPE' option to select the type of +-system on which you are compiling the package. ++'configure' Invocation ++====================== + +-Sharing Defaults +-================ ++ 'configure' recognizes the following options to control how it ++operates. + +- If you want to set default values for `configure' scripts to share, +-you can create a site shell script called `config.site' that gives +-default values for variables like `CC', `cache_file', and `prefix'. +-`configure' looks for `PREFIX/share/config.site' if it exists, then +-`PREFIX/etc/config.site' if it exists. Or, you can set the +-`CONFIG_SITE' environment variable to the location of the site script. +-A warning: not all `configure' scripts look for a site script. ++'--help' ++'-h' ++ Print a summary of all of the options to 'configure', and exit. + +-Operation Controls +-================== ++'--help=short' ++'--help=recursive' ++ Print a summary of the options unique to this package's ++ 'configure', and exit. The 'short' variant lists options used only ++ in the top level, while the 'recursive' variant lists options also ++ present in any nested packages. + +- `configure' recognizes the following options to control how it +-operates. ++'--version' ++'-V' ++ Print the version of Autoconf used to generate the 'configure' ++ script, and exit. + +-`--cache-file=FILE' +- Use and save the results of the tests in FILE instead of +- `./config.cache'. Set FILE to `/dev/null' to disable caching, for +- debugging `configure'. ++'--cache-file=FILE' ++ Enable the cache: use and save the results of the tests in FILE, ++ traditionally 'config.cache'. FILE defaults to '/dev/null' to ++ disable caching. + +-`--help' +- Print a summary of the options to `configure', and exit. ++'--config-cache' ++'-C' ++ Alias for '--cache-file=config.cache'. + +-`--quiet' +-`--silent' +-`-q' ++'--quiet' ++'--silent' ++'-q' + Do not print messages saying which checks are being made. To +- suppress all normal output, redirect it to `/dev/null' (any error ++ suppress all normal output, redirect it to '/dev/null' (any error + messages will still be shown). + +-`--srcdir=DIR' ++'--srcdir=DIR' + Look for the package's source code in directory DIR. Usually +- `configure' can determine that directory automatically. ++ 'configure' can determine that directory automatically. + +-`--version' +- Print the version of Autoconf used to generate the `configure' +- script, and exit. ++'--prefix=DIR' ++ Use DIR as the installation prefix. *note Installation Names:: for ++ more details, including other options available for fine-tuning the ++ installation locations. ++ ++'--no-create' ++'-n' ++ Run the configure checks, but stop before creating any output ++ files. + +-`configure' also accepts some other, not widely useful, options. ++'configure' also accepts some other, not widely useful, options. Run ++'configure --help' for more details. +diff --git a/Makefile.am b/Makefile.am +index 17f6960..992689e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,7 +1,5 @@ + SUBDIRS = wrap-gmp-gmpxx lib-src-reg lib-src src-reg src examples share + EXTRA_DIST = external/Makefile +-EXTRA_DIST += external/gmp-6.2.1.tar.bz2 +-EXTRA_DIST += external/cddlib-0.94j-TOPCOMb.tar.gz + EXTRA_DIST += external/qsopt_ex-2.5.10.3.tar.gz + EXTRA_DIST += external/gmpxx-patch + +diff --git a/Makefile.in b/Makefile.in +index b9902f5..93002b8 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -211,6 +211,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -286,6 +287,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -295,9 +297,8 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + SUBDIRS = wrap-gmp-gmpxx lib-src-reg lib-src src-reg src examples share +-EXTRA_DIST = external/Makefile external/gmp-6.2.1.tar.bz2 \ +- external/cddlib-0.94j-TOPCOMb.tar.gz \ +- external/qsopt_ex-2.5.10.3.tar.gz external/gmpxx-patch ++EXTRA_DIST = external/Makefile external/qsopt_ex-2.5.10.3.tar.gz \ ++ external/gmpxx-patch + all: all-recursive + + .SUFFIXES: +@@ -524,6 +525,10 @@ dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + ++dist-zstd: distdir ++ tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst ++ $(am__post_remove_distdir) ++ + dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 +@@ -566,6 +571,8 @@ distcheck: dist + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ ++ *.tar.zst*) \ ++ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) +@@ -742,7 +749,7 @@ uninstall-am: + am--refresh check check-am clean clean-cscope clean-generic \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ +- distcheck distclean distclean-generic distclean-tags \ ++ dist-zstd distcheck distclean distclean-generic distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ +diff --git a/aclocal.m4 b/aclocal.m4 +index 8c6b78f..e4b15fc 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1,6 +1,6 @@ +-# generated automatically by aclocal 1.16.1 -*- Autoconf -*- ++# generated automatically by aclocal 1.16.2 -*- Autoconf -*- + +-# Copyright (C) 1996-2018 Free Software Foundation, Inc. ++# Copyright (C) 1996-2020 Free Software Foundation, Inc. + + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. + If you have problems, you may need to regenerate the build system entirely. + To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +-# Copyright (C) 2002-2018 Free Software Foundation, Inc. ++# Copyright (C) 2002-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], + [am__api_version='1.16' + dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to + dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.16.1], [], ++m4_if([$1], [1.16.2], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl + ]) + +@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) + # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. + # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. + AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.16.1])dnl ++[AM_AUTOMAKE_VERSION([1.16.2])dnl + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl + _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + + # AM_AUX_DIR_EXPAND -*- Autoconf -*- + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` + + # AM_CONDITIONAL -*- Autoconf -*- + +-# Copyright (C) 1997-2018 Free Software Foundation, Inc. ++# Copyright (C) 1997-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( + Usually this means the macro was only invoked conditionally.]]) + fi])]) + +-# Copyright (C) 1999-2018 Free Software Foundation, Inc. ++# Copyright (C) 1999-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl + + # Generate code to set up dependency tracking. -*- Autoconf -*- + +-# Copyright (C) 1999-2018 Free Software Foundation, Inc. ++# Copyright (C) 1999-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -371,7 +371,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments +- for automatic dependency tracking. Try re-running configure with the ++ for automatic dependency tracking. If GNU make was not used, consider ++ re-running the configure script with MAKE="gmake" (or whatever is ++ necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi +@@ -398,7 +400,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], + + # Do all the work for Automake. -*- Autoconf -*- + +-# Copyright (C) 1996-2018 Free Software Foundation, Inc. ++# Copyright (C) 1996-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -595,7 +597,7 @@ for _am_header in $config_headers :; do + done + echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -616,7 +618,7 @@ if test x"${install_sh+set}" != xset; then + fi + AC_SUBST([install_sh])]) + +-# Copyright (C) 2003-2018 Free Software Foundation, Inc. ++# Copyright (C) 2003-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -637,7 +639,7 @@ AC_SUBST([am__leading_dot])]) + + # Check to see how 'make' treats includes. -*- Autoconf -*- + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -680,7 +682,7 @@ AC_SUBST([am__quote])]) + + # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +-# Copyright (C) 1997-2018 Free Software Foundation, Inc. ++# Copyright (C) 1997-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -719,7 +721,7 @@ fi + + # Helper functions for option handling. -*- Autoconf -*- + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -748,7 +750,7 @@ AC_DEFUN([_AM_SET_OPTIONS], + AC_DEFUN([_AM_IF_OPTION], + [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +-# Copyright (C) 1999-2018 Free Software Foundation, Inc. ++# Copyright (C) 1999-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -795,7 +797,7 @@ AC_LANG_POP([C])]) + # For backward compatibility. + AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -814,7 +816,7 @@ AC_DEFUN([AM_RUN_LOG], + + # Check to make sure that the build environment is sane. -*- Autoconf -*- + +-# Copyright (C) 1996-2018 Free Software Foundation, Inc. ++# Copyright (C) 1996-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -895,7 +897,7 @@ AC_CONFIG_COMMANDS_PRE( + rm -f conftest.file + ]) + +-# Copyright (C) 2009-2018 Free Software Foundation, Inc. ++# Copyright (C) 2009-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -955,7 +957,7 @@ AC_SUBST([AM_BACKSLASH])dnl + _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl + ]) + +-# Copyright (C) 2001-2018 Free Software Foundation, Inc. ++# Copyright (C) 2001-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -983,7 +985,7 @@ fi + INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +-# Copyright (C) 2006-2018 Free Software Foundation, Inc. ++# Copyright (C) 2006-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1002,7 +1004,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + + # Check how to create a tarball. -*- Autoconf -*- + +-# Copyright (C) 2004-2018 Free Software Foundation, Inc. ++# Copyright (C) 2004-2020 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +diff --git a/compile b/compile +index 99e5052..23fcba0 100755 +--- a/compile ++++ b/compile +@@ -3,7 +3,7 @@ + + scriptversion=2018-03-07.03; # UTC + +-# Copyright (C) 1999-2018 Free Software Foundation, Inc. ++# Copyright (C) 1999-2020 Free Software Foundation, Inc. + # Written by Tom Tromey . + # + # This program is free software; you can redistribute it and/or modify +@@ -53,7 +53,7 @@ func_file_conv () + MINGW*) + file_conv=mingw + ;; +- CYGWIN*) ++ CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) +@@ -67,7 +67,7 @@ func_file_conv () + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; +- cygwin/*) ++ cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) +diff --git a/configure b/configure +index 7aebaca..6afa3b8 100755 +--- a/configure ++++ b/configure +@@ -627,6 +627,7 @@ USE_SOPLEX_FALSE + USE_SOPLEX_TRUE + USE_QSOPTEX_FALSE + USE_QSOPTEX_TRUE ++CPP + USE_LOCAL_GMP_FALSE + USE_LOCAL_GMP_TRUE + EGREP +@@ -705,6 +706,7 @@ infodir + docdir + oldincludedir + includedir ++runstatedir + localstatedir + sharedstatedir + sysconfdir +@@ -744,7 +746,8 @@ CPPFLAGS + CXX + CXXFLAGS + CCC +-CXXCPP' ++CXXCPP ++CPP' + + + # Initialize some variables set by options. +@@ -783,6 +786,7 @@ datadir='${datarootdir}' + sysconfdir='${prefix}/etc' + sharedstatedir='${prefix}/com' + localstatedir='${prefix}/var' ++runstatedir='${localstatedir}/run' + includedir='${prefix}/include' + oldincludedir='/usr/include' + docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +@@ -1035,6 +1039,15 @@ do + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + ++ -runstatedir | --runstatedir | --runstatedi | --runstated \ ++ | --runstate | --runstat | --runsta | --runst | --runs \ ++ | --run | --ru | --r) ++ ac_prev=runstatedir ;; ++ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ ++ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ ++ | --run=* | --ru=* | --r=*) ++ runstatedir=$ac_optarg ;; ++ + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ +@@ -1172,7 +1185,7 @@ fi + for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ +- libdir localedir mandir ++ libdir localedir mandir runstatedir + do + eval ac_val=\$$ac_var + # Remove trailing slashes. +@@ -1325,6 +1338,7 @@ Fine tuning of the installation directories: + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] +@@ -1388,6 +1402,7 @@ Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor ++ CPP C preprocessor + + Use these variables to override the choices made by `configure' or to help + it to find libraries and programs with nonstandard names/locations. +@@ -1742,6 +1757,130 @@ $as_echo "$ac_res" >&6; } + + } # ac_fn_cxx_check_header_compile + ++# ac_fn_c_try_cpp LINENO ++# ---------------------- ++# Try to preprocess conftest.$ac_ext, and return whether this succeeded. ++ac_fn_c_try_cpp () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if { { ac_try="$ac_cpp conftest.$ac_ext" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++$as_echo "$ac_try_echo"; } >&5 ++ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ++ ac_status=$? ++ if test -s conftest.err; then ++ grep -v '^ *+' conftest.err >conftest.er1 ++ cat conftest.er1 >&5 ++ mv -f conftest.er1 conftest.err ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } > conftest.i && { ++ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || ++ test ! -s conftest.err ++ }; then : ++ ac_retval=0 ++else ++ $as_echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_retval=1 ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ as_fn_set_status $ac_retval ++ ++} # ac_fn_c_try_cpp ++ ++# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES ++# ------------------------------------------------------- ++# Tests whether HEADER exists, giving a warning if it cannot be compiled using ++# the include files in INCLUDES and setting the cache variable VAR ++# accordingly. ++ac_fn_c_check_header_mongrel () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ if eval \${$3+:} false; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++else ++ # Is the header compilable? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 ++$as_echo_n "checking $2 usability... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++#include <$2> ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_header_compiler=yes ++else ++ ac_header_compiler=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 ++$as_echo "$ac_header_compiler" >&6; } ++ ++# Is the header present? ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 ++$as_echo_n "checking $2 presence... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include <$2> ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ac_header_preproc=yes ++else ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 ++$as_echo "$ac_header_preproc" >&6; } ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( ++ yes:no: ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 ++$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++ no:yes:* ) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 ++$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 ++$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 ++$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 ++$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ++ ;; ++esac ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ eval "$3=\$ac_header_compiler" ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++fi ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_header_mongrel ++ + # ac_fn_c_try_link LINENO + # ----------------------- + # Try to link conftest.$ac_ext, and return whether this succeeded. +@@ -4801,7 +4940,218 @@ $as_echo "$as_me: gmpxx.h not found on system - building gmp locally ..." >&6;} + $as_echo "$as_me: ... done" >&6;} + fi + +-make -C external cdd ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 ++$as_echo_n "checking how to run the C preprocessor... " >&6; } ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if ${ac_cv_prog_CPP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 ++$as_echo "$CPP" >&6; } ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer to if __STDC__ is defined, since ++ # exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ Syntax error ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ ++else ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether nonexistent headers ++ # can be detected and how. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++_ACEOF ++if ac_fn_c_try_cpp "$LINENO"; then : ++ # Broken: success on invalid input. ++continue ++else ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.i conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.i conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then : ++ ++else ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "C preprocessor \"$CPP\" fails sanity check ++See \`config.log' for more details" "$LINENO" 5; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++for ac_header in cddlib/setoper.h ++do : ++ ac_fn_c_check_header_mongrel "$LINENO" "cddlib/setoper.h" "ac_cv_header_cddlib_setoper_h" "$ac_includes_default" ++if test "x$ac_cv_header_cddlib_setoper_h" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_CDDLIB_SETOPER_H 1 ++_ACEOF ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dd_free_global_constants" >&5 ++$as_echo_n "checking for library containing dd_free_global_constants... " >&6; } ++if ${ac_cv_search_dd_free_global_constants+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dd_free_global_constants (); ++int ++main () ++{ ++return dd_free_global_constants (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' cddgmp; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_dd_free_global_constants=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_dd_free_global_constants+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_dd_free_global_constants+:} false; then : ++ ++else ++ ac_cv_search_dd_free_global_constants=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dd_free_global_constants" >&5 ++$as_echo "$ac_cv_search_dd_free_global_constants" >&6; } ++ac_res=$ac_cv_search_dd_free_global_constants ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++else ++ as_fn_error $? "Can't use cddgmp library" "$LINENO" 5 ++fi ++ ++ ++else ++ as_fn_error $? "Can't find cdd library headers" "$LINENO" 5 ++fi ++ ++done ++ + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether QSOpt_ex support was enabled" >&5 + $as_echo_n "checking whether QSOpt_ex support was enabled... " >&6; } +@@ -6276,7 +6626,9 @@ $as_echo X/"$am_mf" | + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + as_fn_error $? "Something went wrong bootstrapping makefile fragments +- for automatic dependency tracking. Try re-running configure with the ++ for automatic dependency tracking. If GNU make was not used, consider ++ re-running the configure script with MAKE=\"gmake\" (or whatever is ++ necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). + See \`config.log' for more details" "$LINENO" 5; } +diff --git a/configure.ac b/configure.ac +index 2372711..430f01b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -43,8 +43,10 @@ else + AC_MSG_NOTICE([... done]) + fi + +-dnl Make libcddgmp: +-make -C external cdd ++ ++AC_CHECK_HEADERS([cddlib/setoper.h],[ ++ AC_SEARCH_LIBS([dd_free_global_constants],[cddgmp], [], [AC_MSG_ERROR([Can't use cddgmp library])]) ++ ], [AC_MSG_ERROR([Can't find cdd library headers])]) + + dnl Check for requests for third-party packages: + dnl Check for qsopt_ex: +diff --git a/depcomp b/depcomp +index 65cbf70..6b39162 100755 +--- a/depcomp ++++ b/depcomp +@@ -3,7 +3,7 @@ + + scriptversion=2018-03-07.03; # UTC + +-# Copyright (C) 1999-2018 Free Software Foundation, Inc. ++# Copyright (C) 1999-2020 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +diff --git a/examples/Makefile.in b/examples/Makefile.in +index 92a0212..30ac680 100644 +--- a/examples/Makefile.in ++++ b/examples/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -129,6 +129,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -204,6 +205,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/install-sh b/install-sh +index 8175c64..20d8b2e 100755 +--- a/install-sh ++++ b/install-sh +@@ -451,7 +451,18 @@ do + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. +- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && ++ (umask $cp_umask && ++ { test -z "$stripcmd" || { ++ # Create $dsttmp read-write so that cp doesn't create it read-only, ++ # which would cause strip to fail. ++ if test -z "$doit"; then ++ : >"$dsttmp" # No need to fork-exec 'touch'. ++ else ++ $doit touch "$dsttmp" ++ fi ++ } ++ } && ++ $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # +diff --git a/lib-src-reg/LPinterface.hh b/lib-src-reg/LPinterface.hh +index 6522dbe..622a224 100644 +--- a/lib-src-reg/LPinterface.hh ++++ b/lib-src-reg/LPinterface.hh +@@ -21,8 +21,8 @@ + #include "LabelSet.hh" + #include "Rational.h" + +-#include "setoper.h" +-#include "cdd.h" ++#include ++#include + + namespace topcom { + +diff --git a/lib-src-reg/Makefile.in b/lib-src-reg/Makefile.in +index 977f8f8..368b2a5 100644 +--- a/lib-src-reg/Makefile.in ++++ b/lib-src-reg/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -214,6 +214,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -289,6 +290,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in +index 4407b62..a3d3316 100644 +--- a/lib-src/Makefile.in ++++ b/lib-src/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -267,6 +267,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -342,6 +343,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/missing b/missing +index 625aeb1..8d0eaad 100755 +--- a/missing ++++ b/missing +@@ -3,7 +3,7 @@ + + scriptversion=2018-03-07.03; # UTC + +-# Copyright (C) 1996-2018 Free Software Foundation, Inc. ++# Copyright (C) 1996-2020 Free Software Foundation, Inc. + # Originally written by Fran,cois Pinard , 1996. + + # This program is free software; you can redistribute it and/or modify +diff --git a/share/Makefile.in b/share/Makefile.in +index 23488b7..2326a9e 100644 +--- a/share/Makefile.in ++++ b/share/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -129,6 +129,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -204,6 +205,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +diff --git a/src-reg/Makefile.am b/src-reg/Makefile.am +index ed4a016..2ad9026 100644 +--- a/src-reg/Makefile.am ++++ b/src-reg/Makefile.am +@@ -4,7 +4,9 @@ checkregularity_SOURCES = checkregularity.cc + + LDADD = ../lib-src/libTOPCOM.a \ + ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a ++ -lgmpxx -lgmp ++ ++ + if USE_QSOPTEX + LDADD += ../external/lib/libqsopt_ex.a + endif +@@ -12,12 +14,6 @@ endif + if USE_SOPLEX + LDADD += ../external/lib/libsoplex.a + endif +-if USE_LOCAL_GMP +-LDADD += ../external/lib/libgmpxx.a \ +- ../external/lib/libgmp.a +-else +-LIBS += -lgmpxx -lgmp +-endif + + AM_CPPFLAGS += -I../lib-src + AM_CPPFLAGS += -I../lib-src-reg +diff --git a/src-reg/Makefile.in b/src-reg/Makefile.in +index f4b7c08..7ccd2f7 100644 +--- a/src-reg/Makefile.in ++++ b/src-reg/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -89,10 +89,6 @@ POST_UNINSTALL = : + bin_PROGRAMS = checkregularity$(EXEEXT) + @USE_QSOPTEX_TRUE@am__append_1 = ../external/lib/libqsopt_ex.a + @USE_SOPLEX_TRUE@am__append_2 = ../external/lib/libsoplex.a +-@USE_LOCAL_GMP_TRUE@am__append_3 = ../external/lib/libgmpxx.a \ +-@USE_LOCAL_GMP_TRUE@ ../external/lib/libgmp.a +- +-@USE_LOCAL_GMP_FALSE@am__append_4 = -lgmpxx -lgmp + subdir = src-reg + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/configure.ac +@@ -108,8 +104,7 @@ am_checkregularity_OBJECTS = checkregularity.$(OBJEXT) + checkregularity_OBJECTS = $(am_checkregularity_OBJECTS) + checkregularity_LDADD = $(LDADD) + checkregularity_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + AM_V_P = $(am__v_P_@AM_V@) + am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) + am__v_P_0 = false +@@ -184,6 +179,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -205,7 +201,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ + INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ + LDFLAGS = @LDFLAGS@ + LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ $(am__append_4) ++LIBS = @LIBS@ + LTLIBOBJS = @LTLIBOBJS@ + MAKEINFO = @MAKEINFO@ + MKDIR_P = @MKDIR_P@ +@@ -259,6 +255,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -268,9 +265,8 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + checkregularity_SOURCES = checkregularity.cc +-LDADD = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++LDADD = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a -lgmpxx \ ++ -lgmp $(am__append_1) $(am__append_2) + all: all-am + + .SUFFIXES: +diff --git a/src/Makefile.am b/src/Makefile.am +index c97ecc5..e20e1c3 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -122,20 +122,15 @@ santos_dim4_triang_SOURCES = santos_dim4_triang.cc + santos_22_triang_SOURCES = santos_22_triang.cc + + LDADD = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a ++ ../lib-src-reg/libCHECKREG.a ++ + if USE_QSOPTEX + LDADD += ../external/lib/libqsopt_ex.a + endif + if USE_SOPLEX + LDADD += ../external/lib/libsoplex.a + endif +-if USE_LOCAL_GMP +-LDADD += ../external/lib/libgmpxx.a \ +- ../external/lib/libgmp.a +-else + LIBS += -lgmpxx -lgmp +-endif + + + AM_CPPFLAGS += -I../lib-src +diff --git a/src/Makefile.in b/src/Makefile.in +index 47a6ac0..bcca997 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -115,10 +115,6 @@ bin_PROGRAMS = B_A$(EXEEXT) B_A_center$(EXEEXT) B_D$(EXEEXT) \ + santos_dim4_triang$(EXEEXT) santos_22_triang$(EXEEXT) + @USE_QSOPTEX_TRUE@am__append_1 = ../external/lib/libqsopt_ex.a + @USE_SOPLEX_TRUE@am__append_2 = ../external/lib/libsoplex.a +-@USE_LOCAL_GMP_TRUE@am__append_3 = ../external/lib/libgmpxx.a \ +-@USE_LOCAL_GMP_TRUE@ ../external/lib/libgmp.a +- +-@USE_LOCAL_GMP_FALSE@am__append_4 = -lgmpxx -lgmp + subdir = src + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/configure.ac +@@ -134,362 +130,302 @@ am_B_A_OBJECTS = B_A.$(OBJEXT) + B_A_OBJECTS = $(am_B_A_OBJECTS) + B_A_LDADD = $(LDADD) + B_A_DEPENDENCIES = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++ $(am__append_1) $(am__append_2) + am_B_A_center_OBJECTS = B_A_center.$(OBJEXT) + B_A_center_OBJECTS = $(am_B_A_center_OBJECTS) + B_A_center_LDADD = $(LDADD) + B_A_center_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_B_D_OBJECTS = B_D.$(OBJEXT) + B_D_OBJECTS = $(am_B_D_OBJECTS) + B_D_LDADD = $(LDADD) + B_D_DEPENDENCIES = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++ $(am__append_1) $(am__append_2) + am_B_D_center_OBJECTS = B_D_center.$(OBJEXT) + B_D_center_OBJECTS = $(am_B_D_center_OBJECTS) + B_D_center_LDADD = $(LDADD) + B_D_center_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_B_S_OBJECTS = B_S.$(OBJEXT) + B_S_OBJECTS = $(am_B_S_OBJECTS) + B_S_LDADD = $(LDADD) + B_S_DEPENDENCIES = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++ $(am__append_1) $(am__append_2) + am_B_S_center_OBJECTS = B_S_center.$(OBJEXT) + B_S_center_OBJECTS = $(am_B_S_center_OBJECTS) + B_S_center_LDADD = $(LDADD) + B_S_center_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_Dnxk_OBJECTS = Dnxk.$(OBJEXT) + Dnxk_OBJECTS = $(am_Dnxk_OBJECTS) + Dnxk_LDADD = $(LDADD) + Dnxk_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_binomial_OBJECTS = binomial.$(OBJEXT) + binomial_OBJECTS = $(am_binomial_OBJECTS) + binomial_LDADD = $(LDADD) + binomial_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_check_OBJECTS = check.$(OBJEXT) + check_OBJECTS = $(am_check_OBJECTS) + check_LDADD = $(LDADD) + check_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2allfinetriangs_OBJECTS = chiro2allfinetriangs.$(OBJEXT) + chiro2allfinetriangs_OBJECTS = $(am_chiro2allfinetriangs_OBJECTS) + chiro2allfinetriangs_LDADD = $(LDADD) + chiro2allfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2alltriangs_OBJECTS = chiro2alltriangs.$(OBJEXT) + chiro2alltriangs_OBJECTS = $(am_chiro2alltriangs_OBJECTS) + chiro2alltriangs_LDADD = $(LDADD) + chiro2alltriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2circuits_OBJECTS = chiro2circuits.$(OBJEXT) + chiro2circuits_OBJECTS = $(am_chiro2circuits_OBJECTS) + chiro2circuits_LDADD = $(LDADD) + chiro2circuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2cocircuits_OBJECTS = chiro2cocircuits.$(OBJEXT) + chiro2cocircuits_OBJECTS = $(am_chiro2cocircuits_OBJECTS) + chiro2cocircuits_LDADD = $(LDADD) + chiro2cocircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2dual_OBJECTS = chiro2dual.$(OBJEXT) + chiro2dual_OBJECTS = $(am_chiro2dual_OBJECTS) + chiro2dual_LDADD = $(LDADD) + chiro2dual_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2finetriang_OBJECTS = chiro2finetriang.$(OBJEXT) + chiro2finetriang_OBJECTS = $(am_chiro2finetriang_OBJECTS) + chiro2finetriang_LDADD = $(LDADD) + chiro2finetriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2finetriangs_OBJECTS = chiro2finetriangs.$(OBJEXT) + chiro2finetriangs_OBJECTS = $(am_chiro2finetriangs_OBJECTS) + chiro2finetriangs_LDADD = $(LDADD) + chiro2finetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2mintriang_OBJECTS = chiro2mintriang.$(OBJEXT) + chiro2mintriang_OBJECTS = $(am_chiro2mintriang_OBJECTS) + chiro2mintriang_LDADD = $(LDADD) + chiro2mintriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2nallfinetriangs_OBJECTS = chiro2nallfinetriangs.$(OBJEXT) + chiro2nallfinetriangs_OBJECTS = $(am_chiro2nallfinetriangs_OBJECTS) + chiro2nallfinetriangs_LDADD = $(LDADD) + chiro2nallfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2nalltriangs_OBJECTS = chiro2nalltriangs.$(OBJEXT) + chiro2nalltriangs_OBJECTS = $(am_chiro2nalltriangs_OBJECTS) + chiro2nalltriangs_LDADD = $(LDADD) + chiro2nalltriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2ncircuits_OBJECTS = chiro2ncircuits.$(OBJEXT) + chiro2ncircuits_OBJECTS = $(am_chiro2ncircuits_OBJECTS) + chiro2ncircuits_LDADD = $(LDADD) + chiro2ncircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2ncocircuits_OBJECTS = chiro2ncocircuits.$(OBJEXT) + chiro2ncocircuits_OBJECTS = $(am_chiro2ncocircuits_OBJECTS) + chiro2ncocircuits_LDADD = $(LDADD) + chiro2ncocircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2nfinetriangs_OBJECTS = chiro2nfinetriangs.$(OBJEXT) + chiro2nfinetriangs_OBJECTS = $(am_chiro2nfinetriangs_OBJECTS) + chiro2nfinetriangs_LDADD = $(LDADD) + chiro2nfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2ntriangs_OBJECTS = chiro2ntriangs.$(OBJEXT) + chiro2ntriangs_OBJECTS = $(am_chiro2ntriangs_OBJECTS) + chiro2ntriangs_LDADD = $(LDADD) + chiro2ntriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2placingtriang_OBJECTS = chiro2placingtriang.$(OBJEXT) + chiro2placingtriang_OBJECTS = $(am_chiro2placingtriang_OBJECTS) + chiro2placingtriang_LDADD = $(LDADD) + chiro2placingtriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_chiro2triangs_OBJECTS = chiro2triangs.$(OBJEXT) + chiro2triangs_OBJECTS = $(am_chiro2triangs_OBJECTS) + chiro2triangs_LDADD = $(LDADD) + chiro2triangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_cocircuits2facets_OBJECTS = cocircuits2facets.$(OBJEXT) + cocircuits2facets_OBJECTS = $(am_cocircuits2facets_OBJECTS) + cocircuits2facets_LDADD = $(LDADD) + cocircuits2facets_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_cross_OBJECTS = cross.$(OBJEXT) + cross_OBJECTS = $(am_cross_OBJECTS) + cross_LDADD = $(LDADD) + cross_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_cube_OBJECTS = cube.$(OBJEXT) + cube_OBJECTS = $(am_cube_OBJECTS) + cube_LDADD = $(LDADD) + cube_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_cyclic_OBJECTS = cyclic.$(OBJEXT) + cyclic_OBJECTS = $(am_cyclic_OBJECTS) + cyclic_LDADD = $(LDADD) + cyclic_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_hypersimplex_OBJECTS = hypersimplex.$(OBJEXT) + hypersimplex_OBJECTS = $(am_hypersimplex_OBJECTS) + hypersimplex_LDADD = $(LDADD) + hypersimplex_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_kDn_OBJECTS = kDn.$(OBJEXT) + kDn_OBJECTS = $(am_kDn_OBJECTS) + kDn_LDADD = $(LDADD) + kDn_DEPENDENCIES = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++ $(am__append_1) $(am__append_2) + am_lattice_OBJECTS = lattice.$(OBJEXT) + lattice_OBJECTS = $(am_lattice_OBJECTS) + lattice_LDADD = $(LDADD) + lattice_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_permutahedron_OBJECTS = permutahedron.$(OBJEXT) + permutahedron_OBJECTS = $(am_permutahedron_OBJECTS) + permutahedron_LDADD = $(LDADD) + permutahedron_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2allfinetriangs_OBJECTS = points2allfinetriangs.$(OBJEXT) + points2allfinetriangs_OBJECTS = $(am_points2allfinetriangs_OBJECTS) + points2allfinetriangs_LDADD = $(LDADD) + points2allfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2alltriangs_OBJECTS = points2alltriangs.$(OBJEXT) + points2alltriangs_OBJECTS = $(am_points2alltriangs_OBJECTS) + points2alltriangs_LDADD = $(LDADD) + points2alltriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2chiro_OBJECTS = points2chiro.$(OBJEXT) + points2chiro_OBJECTS = $(am_points2chiro_OBJECTS) + points2chiro_LDADD = $(LDADD) + points2chiro_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2circuits_OBJECTS = points2circuits.$(OBJEXT) + points2circuits_OBJECTS = $(am_points2circuits_OBJECTS) + points2circuits_LDADD = $(LDADD) + points2circuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2cocircuits_OBJECTS = points2cocircuits.$(OBJEXT) + points2cocircuits_OBJECTS = $(am_points2cocircuits_OBJECTS) + points2cocircuits_LDADD = $(LDADD) + points2cocircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2facets_OBJECTS = points2facets.$(OBJEXT) + points2facets_OBJECTS = $(am_points2facets_OBJECTS) + points2facets_LDADD = $(LDADD) + points2facets_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2finetriang_OBJECTS = points2finetriang.$(OBJEXT) + points2finetriang_OBJECTS = $(am_points2finetriang_OBJECTS) + points2finetriang_LDADD = $(LDADD) + points2finetriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2finetriangs_OBJECTS = points2finetriangs.$(OBJEXT) + points2finetriangs_OBJECTS = $(am_points2finetriangs_OBJECTS) + points2finetriangs_LDADD = $(LDADD) + points2finetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2flips_OBJECTS = points2flips.$(OBJEXT) + points2flips_OBJECTS = $(am_points2flips_OBJECTS) + points2flips_LDADD = $(LDADD) + points2flips_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2gale_OBJECTS = points2gale.$(OBJEXT) + points2gale_OBJECTS = $(am_points2gale_OBJECTS) + points2gale_LDADD = $(LDADD) + points2gale_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2mintriang_OBJECTS = points2mintriang.$(OBJEXT) + points2mintriang_OBJECTS = $(am_points2mintriang_OBJECTS) + points2mintriang_LDADD = $(LDADD) + points2mintriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2nallfinetriangs_OBJECTS = points2nallfinetriangs.$(OBJEXT) + points2nallfinetriangs_OBJECTS = $(am_points2nallfinetriangs_OBJECTS) + points2nallfinetriangs_LDADD = $(LDADD) + points2nallfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2nalltriangs_OBJECTS = points2nalltriangs.$(OBJEXT) + points2nalltriangs_OBJECTS = $(am_points2nalltriangs_OBJECTS) + points2nalltriangs_LDADD = $(LDADD) + points2nalltriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2ncircuits_OBJECTS = points2ncircuits.$(OBJEXT) + points2ncircuits_OBJECTS = $(am_points2ncircuits_OBJECTS) + points2ncircuits_LDADD = $(LDADD) + points2ncircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2ncocircuits_OBJECTS = points2ncocircuits.$(OBJEXT) + points2ncocircuits_OBJECTS = $(am_points2ncocircuits_OBJECTS) + points2ncocircuits_LDADD = $(LDADD) + points2ncocircuits_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2nfinetriangs_OBJECTS = points2nfinetriangs.$(OBJEXT) + points2nfinetriangs_OBJECTS = $(am_points2nfinetriangs_OBJECTS) + points2nfinetriangs_LDADD = $(LDADD) + points2nfinetriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2nflips_OBJECTS = points2nflips.$(OBJEXT) + points2nflips_OBJECTS = $(am_points2nflips_OBJECTS) + points2nflips_LDADD = $(LDADD) + points2nflips_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2ntriangs_OBJECTS = points2ntriangs.$(OBJEXT) + points2ntriangs_OBJECTS = $(am_points2ntriangs_OBJECTS) + points2ntriangs_LDADD = $(LDADD) + points2ntriangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2placingtriang_OBJECTS = points2placingtriang.$(OBJEXT) + points2placingtriang_OBJECTS = $(am_points2placingtriang_OBJECTS) + points2placingtriang_LDADD = $(LDADD) + points2placingtriang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2prettyprint_OBJECTS = points2prettyprint.$(OBJEXT) + points2prettyprint_OBJECTS = $(am_points2prettyprint_OBJECTS) + points2prettyprint_LDADD = $(LDADD) + points2prettyprint_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2symmetries_OBJECTS = points2symmetries.$(OBJEXT) + points2symmetries_OBJECTS = $(am_points2symmetries_OBJECTS) + points2symmetries_LDADD = $(LDADD) + points2symmetries_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2triangs_OBJECTS = points2triangs.$(OBJEXT) + points2triangs_OBJECTS = $(am_points2triangs_OBJECTS) + points2triangs_LDADD = $(LDADD) + points2triangs_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2vertices_OBJECTS = points2vertices.$(OBJEXT) + points2vertices_OBJECTS = $(am_points2vertices_OBJECTS) + points2vertices_LDADD = $(LDADD) + points2vertices_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_points2volume_OBJECTS = points2volume.$(OBJEXT) + points2volume_OBJECTS = $(am_points2volume_OBJECTS) + points2volume_LDADD = $(LDADD) + points2volume_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_santos_22_triang_OBJECTS = santos_22_triang.$(OBJEXT) + santos_22_triang_OBJECTS = $(am_santos_22_triang_OBJECTS) + santos_22_triang_LDADD = $(LDADD) + santos_22_triang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_santos_dim4_triang_OBJECTS = santos_dim4_triang.$(OBJEXT) + santos_dim4_triang_OBJECTS = $(am_santos_dim4_triang_OBJECTS) + santos_dim4_triang_LDADD = $(LDADD) + santos_dim4_triang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + am_santos_triang_OBJECTS = santos_triang.$(OBJEXT) + santos_triang_OBJECTS = $(am_santos_triang_OBJECTS) + santos_triang_LDADD = $(LDADD) + santos_triang_DEPENDENCIES = ../lib-src/libTOPCOM.a \ +- ../lib-src-reg/libCHECKREG.a ../external/lib/libcddgmp.a \ +- $(am__append_1) $(am__append_2) $(am__append_3) ++ ../lib-src-reg/libCHECKREG.a $(am__append_1) $(am__append_2) + AM_V_P = $(am__v_P_@AM_V@) + am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) + am__v_P_0 = false +@@ -657,6 +593,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -678,7 +615,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ + INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ + LDFLAGS = @LDFLAGS@ + LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ $(am__append_4) ++LIBS = @LIBS@ -lgmpxx -lgmp + LTLIBOBJS = @LTLIBOBJS@ + MAKEINFO = @MAKEINFO@ + MKDIR_P = @MKDIR_P@ +@@ -732,6 +669,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ +@@ -801,8 +739,7 @@ santos_triang_SOURCES = santos_triang.cc + santos_dim4_triang_SOURCES = santos_dim4_triang.cc + santos_22_triang_SOURCES = santos_22_triang.cc + LDADD = ../lib-src/libTOPCOM.a ../lib-src-reg/libCHECKREG.a \ +- ../external/lib/libcddgmp.a $(am__append_1) $(am__append_2) \ +- $(am__append_3) ++ $(am__append_1) $(am__append_2) + all: all-am + + .SUFFIXES: +diff --git a/wrap-gmp-gmpxx/Makefile.in b/wrap-gmp-gmpxx/Makefile.in +index 86f0be0..bd4c95f 100644 +--- a/wrap-gmp-gmpxx/Makefile.in ++++ b/wrap-gmp-gmpxx/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.16.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.2 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2018 Free Software Foundation, Inc. ++# Copyright (C) 1994-2020 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -178,6 +178,7 @@ AWK = @AWK@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ ++CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ +@@ -253,6 +254,7 @@ pdfdir = @pdfdir@ + prefix = @prefix@ + program_transform_name = @program_transform_name@ + psdir = @psdir@ ++runstatedir = @runstatedir@ + sbindir = @sbindir@ + sharedstatedir = @sharedstatedir@ + srcdir = @srcdir@ From 8eedb6cfe798ed8e429b8cc52589b2485686f92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 17 Oct 2022 14:50:04 +0200 Subject: [PATCH 326/350] fix the linter once again --- src/sage/combinat/species/all.py | 1 - src/sage/combinat/species/library.py | 14 ++++++++------ src/sage/schemes/elliptic_curves/hom.py | 9 ++++----- src/sage/schemes/elliptic_curves/hom_composite.py | 10 +++++++--- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 9480757bd88..6bda0eab5db 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -48,4 +48,3 @@ lazy_import("sage.combinat.species.recursive_species", "CombinatorialSpecies") lazy_import("sage.combinat.species", "library", as_="species") del lazy_import - diff --git a/src/sage/combinat/species/library.py b/src/sage/combinat/species/library.py index 1be68456688..d4235273a9f 100644 --- a/src/sage/combinat/species/library.py +++ b/src/sage/combinat/species/library.py @@ -1,7 +1,7 @@ """ Examples of Combinatorial Species """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Mike Hansen , # # Distributed under the terms of the GNU General Public License (GPL) @@ -13,8 +13,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from .set_species import SetSpecies from .partition_species import PartitionSpecies @@ -32,6 +32,7 @@ from sage.misc.cachefunc import cached_function + @cached_function def SimpleGraphSpecies(): """ @@ -66,7 +67,7 @@ def SimpleGraphSpecies(): E = SetSpecies() E2 = SetSpecies(size=2) WP = SubsetSpecies() - P2 = E2*E + P2 = E2 * E return WP.functorial_composition(P2) @@ -104,9 +105,10 @@ def BinaryTreeSpecies(): """ B = CombinatorialSpecies(min=1) X = SingletonSpecies() - B.define(X + B*B) + B.define(X + B * B) return B + @cached_function def BinaryForestSpecies(): """ @@ -141,5 +143,5 @@ def BinaryForestSpecies(): F = S(B) return F -del cached_function # so it doesn't get picked up by tab completion +del cached_function # so it doesn't get picked up by tab completion diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 9bc6e6bfd47..bdf2c969079 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -353,9 +353,9 @@ def scaling_factor(self): ... NotImplementedError: ... """ - #TODO: could have a default implementation that simply - # returns .formal()[1], but it seems safer to fail - # visibly to make sure we would notice regressions + # TODO: could have a default implementation that simply + # returns .formal()[1], but it seems safer to fail + # visibly to make sure we would notice regressions raise NotImplementedError('children must implement') def formal(self, prec=20): @@ -576,7 +576,7 @@ def is_injective(self): True """ if not self.is_separable(): - #TODO: should implement .separable_degree() or similar + # TODO: should implement .separable_degree() or similar raise NotImplementedError return self.degree() == 1 @@ -746,4 +746,3 @@ def compare_via_evaluation(left, right): assert False, "couldn't find a point of infinite order" else: raise NotImplementedError('not implemented for this base field') - diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 5d0b546488e..b2096eda5b8 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -91,6 +91,7 @@ # TODO: Implement sparse strategies? (cf. the SIKE cryptosystem) + def _eval_factored_isogeny(phis, P): """ This method pushes a point `P` through a given sequence ``phis`` @@ -115,6 +116,7 @@ def _eval_factored_isogeny(phis, P): P = phi(P) return P + def _compute_factored_isogeny_prime_power(P, l, e): """ This method takes a point `P` of order `l^e` and returns @@ -143,6 +145,7 @@ def _compute_factored_isogeny_prime_power(P, l, e): phis.append(phi) return phis + def _compute_factored_isogeny_single_generator(P): """ This method takes a point `P` and returns a sequence of @@ -169,6 +172,7 @@ def _compute_factored_isogeny_single_generator(P): phis += psis return phis + def _compute_factored_isogeny(kernel): """ This method takes a set of points on an elliptic curve @@ -195,6 +199,7 @@ def _compute_factored_isogeny(kernel): phis += psis return phis + class EllipticCurveHom_composite(EllipticCurveHom): _degree = None @@ -512,14 +517,14 @@ def _composition_impl(left, right): To: Elliptic Curve defined by y^2 + (I+1)*x*y = x^3 + I*x^2 + (-4)*x + (-6*I) over Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ if isinstance(left, EllipticCurveHom_composite): - if isinstance(right, WeierstrassIsomorphism) and hasattr(left.factors()[0], '_set_pre_isomorphism'): #XXX bit of a hack + if isinstance(right, WeierstrassIsomorphism) and hasattr(left.factors()[0], '_set_pre_isomorphism'): # XXX bit of a hack return EllipticCurveHom_composite.from_factors((left.factors()[0] * right,) + left.factors()[1:], strict=False) if isinstance(right, EllipticCurveHom_composite): return EllipticCurveHom_composite.from_factors(right.factors() + left.factors()) if isinstance(right, EllipticCurveHom): return EllipticCurveHom_composite.from_factors((right,) + left.factors()) if isinstance(right, EllipticCurveHom_composite): - if isinstance(left, WeierstrassIsomorphism) and hasattr(right.factors()[-1], '_set_post_isomorphism'): #XXX bit of a hack + if isinstance(left, WeierstrassIsomorphism) and hasattr(right.factors()[-1], '_set_post_isomorphism'): # XXX bit of a hack return EllipticCurveHom_composite.from_factors(right.factors()[:-1] + (left * right.factors()[-1],), strict=False) if isinstance(left, EllipticCurveHom): return EllipticCurveHom_composite.from_factors(right.factors() + (left,)) @@ -787,4 +792,3 @@ def make_default(): """ from sage.misc.superseded import deprecation deprecation(34410, 'calling EllipticCurveHom_composite.make_default() is no longer necessary') - From 1a277d834c7686dbad38e4f0c995cefba3fd327a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 17 Oct 2022 15:28:32 +0200 Subject: [PATCH 327/350] some care for trailing whitespaces (W2 and W3) --- src/sage/algebras/cellular_basis.py | 2 +- .../algebras/clifford_algebra_element.pyx | 1 - .../algebras/exterior_algebra_groebner.pyx | 1 - .../finite_dimensional_algebra_element.pyx | 1 - src/sage/algebras/jordan_algebra.py | 8 ++----- .../lie_algebras/classical_lie_algebra.py | 4 +--- .../lie_algebras/lie_algebra_element.pyx | 1 - .../quatalg/quaternion_algebra_cython.pyx | 2 -- src/sage/categories/crystals.py | 4 +--- .../examples/commutative_additive_monoids.py | 3 +-- src/sage/categories/examples/lie_algebras.py | 4 +--- ...ite_dimensional_lie_algebras_with_basis.py | 6 ++--- .../categories/finite_permutation_groups.py | 1 - src/sage/categories/functor.pyx | 2 -- src/sage/categories/homset.py | 6 ++--- src/sage/categories/poor_man_map.py | 9 ++++--- src/sage/categories/pushout.py | 2 +- .../super_lie_conformal_algebras.py | 2 +- src/sage/categories/weyl_groups.py | 2 +- src/sage/combinat/partition.py | 4 ++-- src/sage/combinat/permutation.py | 8 +++---- .../root_system/reflection_group_real.py | 2 +- src/sage/combinat/schubert_polynomial.py | 2 +- src/sage/combinat/similarity_class_type.py | 8 +++---- src/sage/groups/abelian_gps/abelian_group.py | 6 ++--- src/sage/groups/finitely_presented.py | 20 ++++++++-------- src/sage/groups/finitely_presented_named.py | 4 ++-- src/sage/groups/matrix_gps/group_element.pyx | 1 - src/sage/groups/matrix_gps/symplectic.py | 4 ++-- .../automorphism_group_canonical_label.pyx | 14 ----------- .../perm_gps/partn_ref/double_coset.pyx | 5 ---- .../perm_gps/partn_ref/refinement_binary.pyx | 2 -- .../perm_gps/partn_ref/refinement_python.pyx | 3 --- .../perm_gps/partn_ref/refinement_sets.pyx | 6 ----- src/sage/groups/raag.py | 2 +- src/sage/homology/chain_complex_morphism.py | 2 +- src/sage/homology/chain_homotopy.py | 2 +- src/sage/homology/hochschild_complex.py | 2 +- .../homology/simplicial_complex_morphism.py | 3 +-- src/sage/homology/simplicial_set_examples.py | 2 -- src/sage/knots/link.py | 7 +++--- src/sage/modules/fg_pid/fgp_element.py | 2 +- src/sage/modules/module.pyx | 2 -- src/sage/modules/module_functors.py | 11 +++++---- .../modules/vector_complex_double_dense.pyx | 2 -- src/sage/modules/vector_integer_sparse.pyx | 1 - src/sage/modules/vector_mod2_dense.pyx | 1 - src/sage/modules/vector_rational_sparse.pyx | 1 - src/sage/modules/with_basis/invariant.py | 3 ++- src/sage/quivers/morphism.py | 4 +--- src/sage/structure/formal_sum.py | 4 +--- src/sage/structure/global_options.py | 5 +--- src/sage/structure/mutability.pyx | 24 +++++++++---------- src/sage/structure/parent_base.pyx | 1 - src/sage/structure/parent_gens.pyx | 2 -- 55 files changed, 80 insertions(+), 153 deletions(-) diff --git a/src/sage/algebras/cellular_basis.py b/src/sage/algebras/cellular_basis.py index 9e484492954..42ce84307d5 100644 --- a/src/sage/algebras/cellular_basis.py +++ b/src/sage/algebras/cellular_basis.py @@ -1,4 +1,4 @@ -r""" +r""" Cellular Basis ============== diff --git a/src/sage/algebras/clifford_algebra_element.pyx b/src/sage/algebras/clifford_algebra_element.pyx index e065b6b70b9..c52a022e139 100644 --- a/src/sage/algebras/clifford_algebra_element.pyx +++ b/src/sage/algebras/clifford_algebra_element.pyx @@ -982,4 +982,3 @@ cdef class CohomologyRAAGElement(CliffordAlgebraElement): del d[tp] return self.__class__(self._parent, d) - diff --git a/src/sage/algebras/exterior_algebra_groebner.pyx b/src/sage/algebras/exterior_algebra_groebner.pyx index 3d01aaf03a1..cdd445e7253 100644 --- a/src/sage/algebras/exterior_algebra_groebner.pyx +++ b/src/sage/algebras/exterior_algebra_groebner.pyx @@ -715,4 +715,3 @@ cdef class GroebnerStrategyDegLex(GroebnerStrategy): from sage.combinat.combination import from_rank return FrozenBitset(from_rank(n, self.rank, deg)) - diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index 60148f063c4..b0ae904d3d2 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -640,4 +640,3 @@ cdef class FiniteDimensionalAlgebraElement(AlgebraElement): True """ return self.matrix().characteristic_polynomial() - diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index 0923934c514..f5824069797 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -397,7 +397,7 @@ def _latex_(self): from sage.misc.latex import latex return latex(self._x) - def __bool__(self): + def __bool__(self) -> bool: """ Return if ``self`` is non-zero. @@ -411,8 +411,6 @@ def __bool__(self): """ return bool(self._x) - - def __eq__(self, other): """ Check equality. @@ -817,7 +815,7 @@ def _latex_(self): from sage.misc.latex import latex return "{} + {}".format(latex(self._s), latex(self._v)) - def __bool__(self): + def __bool__(self) -> bool: """ Return if ``self`` is non-zero. @@ -834,8 +832,6 @@ def __bool__(self): """ return bool(self._s) or bool(self._v) - - def __eq__(self, other): """ Check equality. diff --git a/src/sage/algebras/lie_algebras/classical_lie_algebra.py b/src/sage/algebras/lie_algebras/classical_lie_algebra.py index 1ae47fa7a31..39f7be6c856 100644 --- a/src/sage/algebras/lie_algebras/classical_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/classical_lie_algebra.py @@ -1332,7 +1332,7 @@ def _unicode_art_(self): from sage.typeset.unicode_art import unicode_art return unicode_art(self._combined_matrix()) - def __bool__(self): + def __bool__(self) -> bool: r""" Return if ``self`` is nonzero. @@ -1346,8 +1346,6 @@ def __bool__(self): """ return bool(self._real) or bool(self._imag) - - def __hash__(self): r""" Return the hash of ``self``. diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index bb2859ba6bd..ffe27c69797 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -1997,4 +1997,3 @@ cdef class LyndonBracket(GradedLieBracket): if self._hash == -1: self._hash = hash(self._index_word) return self._hash - diff --git a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx index 88f65813eac..0d110aad7e3 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx @@ -260,5 +260,3 @@ def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense v.append(x) mpz_clear(tmp) return v - - diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index 32fad8ee75f..980bebc9f84 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -2187,7 +2187,7 @@ def _call_(self, x): cur = cur.e_string(s) return cur - def __bool__(self): + def __bool__(self) -> bool: """ Return if ``self`` is a non-zero morphism. @@ -2204,8 +2204,6 @@ def __bool__(self): """ return any(self._on_gens(mg) is not None for mg in self._gens) - - # TODO: Does this belong in the element_class of the Crystals() category? def to_module_generator(self, x): """ diff --git a/src/sage/categories/examples/commutative_additive_monoids.py b/src/sage/categories/examples/commutative_additive_monoids.py index c0930bec5d5..945826c22a5 100644 --- a/src/sage/categories/examples/commutative_additive_monoids.py +++ b/src/sage/categories/examples/commutative_additive_monoids.py @@ -112,7 +112,7 @@ def zero(self): return self(()) class Element(FreeCommutativeAdditiveSemigroup.Element): - def __bool__(self): + def __bool__(self) -> bool: """ Check if ``self`` is not the zero of the monoid @@ -126,6 +126,5 @@ def __bool__(self): """ return any(x for x in self.value.values()) - Example = FreeCommutativeAdditiveMonoid diff --git a/src/sage/categories/examples/lie_algebras.py b/src/sage/categories/examples/lie_algebras.py index cdde62e6760..3eafe0787f3 100644 --- a/src/sage/categories/examples/lie_algebras.py +++ b/src/sage/categories/examples/lie_algebras.py @@ -193,7 +193,7 @@ def __ne__(self, rhs): """ return not self.__eq__(rhs) - def __bool__(self): + def __bool__(self) -> bool: """ Check non-zero. @@ -207,8 +207,6 @@ def __bool__(self): """ return bool(self.value) - - def _add_(self, rhs): """ Add ``self`` and ``rhs``. diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index 2edc78c26e3..bfe0de224b2 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -837,7 +837,7 @@ def derived_subalgebra(self): the 0-dimensional abelian Lie algebra over Rational Field with basis matrix: [] - + If ``self`` is semisimple, then the derived subalgebra is ``self``:: sage: sl3 = LieAlgebra(QQ, cartan_type=['A',2]) @@ -1107,8 +1107,8 @@ def chevalley_eilenberg_complex(self, M=None, dual=False, sparse=True, ncpus=Non sage: E,F,H = g.basis() sage: n = g.subalgebra([F,H]) sage: ascii_art(n.chevalley_eilenberg_complex()) - [0] - [0 0] [2] + [0] + [0 0] [2] 0 <-- C_0 <------ C_1 <---- C_2 <-- 0 REFERENCES: diff --git a/src/sage/categories/finite_permutation_groups.py b/src/sage/categories/finite_permutation_groups.py index 9269bc8ac1c..59c00471e3f 100644 --- a/src/sage/categories/finite_permutation_groups.py +++ b/src/sage/categories/finite_permutation_groups.py @@ -232,7 +232,6 @@ def cycle_index(self, parent=None): return parent.sum_of_terms([C.an_element().cycle_type(), base_ring(C.cardinality())] for C in self.conjugacy_classes() ) / self.cardinality() - @cached_method def profile_series(self, variable='z'): diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index 77b95f0718c..ccf01cc9177 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -681,11 +681,9 @@ def ForgetfulFunctor(domain, codomain): sage: ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps) True - """ if domain == codomain: return IdentityFunctor(domain) if not domain.is_subcategory(codomain): raise ValueError("Forgetful functor not supported for domain %s" % domain) return ForgetfulFunctor_generic(domain, codomain) - diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 4fe021b86ca..2959e085716 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -734,7 +734,7 @@ def __hash__(self): """ return hash((self._domain, self._codomain, self.base())) - def __bool__(self): + def __bool__(self) -> bool: """ TESTS:: @@ -743,8 +743,6 @@ def __bool__(self): """ return True - - def homset_category(self): """ Return the category that this is a Hom in, i.e., this is typically @@ -1083,7 +1081,7 @@ def __ne__(self, other): True """ return not (self == other) - + def __contains__(self, x): """ Test whether the parent of the argument is ``self``. diff --git a/src/sage/categories/poor_man_map.py b/src/sage/categories/poor_man_map.py index 507705fb9f9..e9829c98fab 100644 --- a/src/sage/categories/poor_man_map.py +++ b/src/sage/categories/poor_man_map.py @@ -200,12 +200,12 @@ def __mul__(self, other): Note that the compatibility of the domains and codomains is for performance reasons only checked for proper parents. For example, the incompatibility is not detected here:: - + sage: f*g A map from (2, 3, 4) to (2, 3, 4) - + But it is detected here:: - + sage: g = PoorManMap(factorial, domain = ZZ, codomain = ZZ) sage: h = PoorManMap(sqrt, domain = RR, codomain = CC) sage: g*h @@ -214,7 +214,6 @@ def __mul__(self, other): ValueError: the codomain Complex Field with 53 bits of precision does not coerce into the domain Integer Ring sage: h*g A map from Integer Ring to Complex Field with 53 bits of precision - """ self_domain = self.domain() @@ -227,7 +226,7 @@ def __mul__(self, other): from sage.structure.parent import is_Parent if is_Parent(self_domain) and is_Parent(other_codomain): if not self_domain.has_coerce_map_from(other_codomain): - raise ValueError("the codomain %r does not coerce into the domain %r"%(other_codomain, self_domain)) + raise ValueError("the codomain %r does not coerce into the domain %r" % (other_codomain, self_domain)) codomain = self.codomain() try: diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 3136160f39d..760f97a3c4f 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -2851,7 +2851,7 @@ def __init__(self, I, names=None, as_field=False, domain=None, if codomain is None: codomain = Rings() Functor.__init__(self, domain, codomain) - + self.I = I if names is None: self.names = None diff --git a/src/sage/categories/super_lie_conformal_algebras.py b/src/sage/categories/super_lie_conformal_algebras.py index cc6167d6830..849a0fbdb13 100644 --- a/src/sage/categories/super_lie_conformal_algebras.py +++ b/src/sage/categories/super_lie_conformal_algebras.py @@ -47,7 +47,7 @@ def extra_super_categories(self): sage: LieConformalAlgebras(QQ).Super().super_categories() [Category of super modules over Rational Field, - Category of Lambda bracket algebras over Rational Field] + Category of Lambda bracket algebras over Rational Field] """ return [LambdaBracketAlgebras(self.base_ring())] diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index 47ca72306f0..38151756676 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -155,7 +155,7 @@ def pieri_factors(self, *args, **keywords): if hasattr(ct, "PieriFactors"): return ct.PieriFactors(self, *args, **keywords) raise NotImplementedError("Pieri factors for type {}".format(ct)) - + def bruhat_cone(self, x, y, side='upper', backend='cdd'): r""" Return the (upper or lower) Bruhat cone associated to the interval ``[x,y]``. diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 39bee4b8b53..844de2016da 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4771,7 +4771,7 @@ def vertical_border_strip_cells(self, k): sage: list(Partition([]).vertical_border_strip_cells(2)) [[(0, 0), (1, 0)]] sage: list(Partition([2,2]).vertical_border_strip_cells(2)) - [[(0, 2), (1, 2)], + [[(0, 2), (1, 2)], [(0, 2), (2, 0)], [(2, 0), (3, 0)]] sage: list(Partition([3,2,2]).vertical_border_strip_cells(2)) @@ -4812,7 +4812,7 @@ def vertical_border_strip_cells(self, k): for _ in range(iv[t]): current_strip.append((j, tmp[j])) j += 1 - j = sum(shelf[:t+1]) + j = sum(shelf[:t+1]) yield current_strip def horizontal_border_strip_cells(self, k): diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index f6d802e2beb..aa603896a44 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -2216,8 +2216,8 @@ def longest_increasing_subsequence_length(self) -> Integer: def longest_increasing_subsequences(self): r""" - Return the list of the longest increasing subsequences of ``self`` - + Return the list of the longest increasing subsequences of ``self``. + A theorem of Schensted ([Sch1961]_) states that an increasing subsequence of length `i` ends with the value entered in the `i`-th column of the p-tableau. The algorithm records which column of the @@ -2247,9 +2247,9 @@ def longest_increasing_subsequences(self): # getting the column in which each element is inserted first_row_p_tableau = [] columns = [] - D = DiGraph(n+2) + D = DiGraph(n + 2) for x in self._list: - j = bisect(first_row_p_tableau, x) + j = bisect(first_row_p_tableau, x) if j == len(first_row_p_tableau): if columns: for k in columns[-1]: diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index 9e5c2e2c1b0..7420f03d24a 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -706,7 +706,7 @@ def simple_root_index(self, i): [0, 1, 2] """ return self._index_set_inverse[i] - + def bruhat_cone(self, x, y, side='upper', backend='cdd'): r""" Return the (upper or lower) Bruhat cone associated to the interval ``[x,y]``. diff --git a/src/sage/combinat/schubert_polynomial.py b/src/sage/combinat/schubert_polynomial.py index 794dc7ee2c6..07d679ac65d 100644 --- a/src/sage/combinat/schubert_polynomial.py +++ b/src/sage/combinat/schubert_polynomial.py @@ -2,7 +2,7 @@ Schubert Polynomials -See :wikipedia:`Schubert_polynomial` and +See :wikipedia:`Schubert_polynomial` and `SymmetricFunctions.com `_. Schubert polynomials are representatives of cohomology classes in flag varieties. In `n` variables, they are indexed by permutations `w \in S_n`. They also form diff --git a/src/sage/combinat/similarity_class_type.py b/src/sage/combinat/similarity_class_type.py index 88515bb3cfe..e7c3f972ac3 100644 --- a/src/sage/combinat/similarity_class_type.py +++ b/src/sage/combinat/similarity_class_type.py @@ -156,7 +156,7 @@ class type, it is also possible to compute the number of classes of that type .. [PSS13] Prasad, A., Singla, P., and Spallone, S., *Similarity of matrices over local rings of length two*. :arxiv:`1212.6157` -.. [PR22] Prasad, A., Ram, S., *Splitting subspaces and a finite field +.. [PR22] Prasad, A., Ram, S., *Splitting subspaces and a finite field interpretation of the Touchard-Riordan formula*. :arxiv:`2205.11076` .. [R17] Ramaré, O., *Rationality of the zeta function of the subgroups of @@ -170,7 +170,7 @@ class type, it is also possible to compute the number of classes of that type - Amritanshu Prasad (2013-09-09): added functions for similarity classes over rings of length two -- Amritanshu Prasad (2022-07-31): added computation of similarity class type of +- Amritanshu Prasad (2022-07-31): added computation of similarity class type of a given matrix and invariant subspace generating function """ # **************************************************************************** @@ -387,7 +387,7 @@ def invariant_subspace_generating_function(la, q=None, t=None): u = invariant_subspace_generating_function(la[1:], q=q, t=t) return R((t**(la[0]+1) * q**(sum(la[1:])) * u.substitute(t=t/q) - u.substitute(t=t*q)) / (t - 1)) - + class PrimarySimilarityClassType(Element, metaclass=InheritComparisonClasscallMetaclass): r""" @@ -1068,7 +1068,7 @@ def invariant_subspace_generating_function(self, q=None, t=None): .. MATH:: \sum_{j\geq 0} a_j(q) t^j, - + where `a_j(q)` denotes the number of `j`-dimensional invariant subspaces of dimensiona `j` for any matrix with the similarity class type ``self`` with entries in a field of order `q`. diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index 8a6afa76bbb..215b516b464 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -646,9 +646,9 @@ def is_trivial(self): """ return self.elementary_divisors() == () - def __bool__(self): + def __bool__(self) -> bool: """ - Returns True if this group is nontrivial. + Return ``True`` if this group is nontrivial. EXAMPLES:: @@ -662,8 +662,6 @@ def __bool__(self): """ return not self.is_trivial() - - @cached_method def dual_group(self, names="X", base_ring=None): """ diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index d953022d3da..8d6e443683c 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -146,9 +146,9 @@ class GroupMorphismWithGensImages(SetMorphism): Class used for morphisms from finitely presented groups to other groups. It just adds the images of the generators at the end of the representation. - + EXAMPLES:: - + sage: F = FreeGroup(3) sage: G = F / [F([1, 2, 3, 1, 2, 3]), F([1, 1, 1])] sage: H = AlternatingGroup(3) @@ -166,9 +166,9 @@ class GroupMorphismWithGensImages(SetMorphism): def _repr_defn(self): r""" Return the part of the representation that includes the images of the generators. - + EXAMPLES:: - + sage: F = FreeGroup(3) sage: G = F / [F([1,2,3,1,2,3]),F([1,1,1])] sage: H = AlternatingGroup(3) @@ -1427,17 +1427,17 @@ def simplified(self): Finitely presented group < e0 | e0^2 > """ return self.simplification_isomorphism().codomain() - + def epimorphisms(self, H): r""" Return the epimorphisms from `self` to `H`, up to automorphism of `H`. - + INPUT: - + - `H` -- Another group - + EXAMPLES:: - + sage: F = FreeGroup(3) sage: G = F / [F([1, 2, 3, 1, 2, 3]), F([1, 1, 1])] sage: H = AlternatingGroup(3) @@ -1468,7 +1468,7 @@ def epimorphisms(self, H): x2 |--> (1,2,3)] ALGORITHM: - + Uses libgap's GQuotients function. """ from sage.misc.misc_c import prod diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py index f1a6b223bfb..ef34854de8b 100644 --- a/src/sage/groups/finitely_presented_named.py +++ b/src/sage/groups/finitely_presented_named.py @@ -214,7 +214,7 @@ def FinitelyGeneratedHeisenbergPresentation(n=1, p=0): - ``p`` -- (optional) a prime number, where we construct the Heisenberg group over the finite field `\ZZ/p\ZZ` - + OUTPUT: Finitely generated Heisenberg group over the finite field @@ -249,7 +249,7 @@ def FinitelyGeneratedHeisenbergPresentation(n=1, p=0): [0 0 1] sage: p = 3 sage: Hp = groups.presentation.Heisenberg(p=3) - sage: Hp.order() == p**3 + sage: Hp.order() == p**3 True sage: Hnp = groups.presentation.Heisenberg(n=2, p=3) sage: len(Hnp.relations()) diff --git a/src/sage/groups/matrix_gps/group_element.pyx b/src/sage/groups/matrix_gps/group_element.pyx index e1bd8b15248..777b141beb0 100644 --- a/src/sage/groups/matrix_gps/group_element.pyx +++ b/src/sage/groups/matrix_gps/group_element.pyx @@ -823,4 +823,3 @@ def _unpickle_generic_element(G, mat): True """ return G.element_class(G, mat, False, False) - diff --git a/src/sage/groups/matrix_gps/symplectic.py b/src/sage/groups/matrix_gps/symplectic.py index 40c99099b5f..3715f531913 100644 --- a/src/sage/groups/matrix_gps/symplectic.py +++ b/src/sage/groups/matrix_gps/symplectic.py @@ -74,9 +74,9 @@ def Sp(n, R, var='a', invariant_form=None): - ``var`` -- (optional, default: ``'a'``) variable used to represent generator of the finite field, if needed - - ``invariant_form`` -- (optional) instances being accepted by + - ``invariant_form`` -- (optional) instances being accepted by the matrix-constructor which define a `n \times n` square matrix - over ``R`` describing the alternating form to be kept invariant + over ``R`` describing the alternating form to be kept invariant by the symplectic group EXAMPLES:: diff --git a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx index a03a4c2c672..ad30101e161 100644 --- a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +++ b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx @@ -895,17 +895,3 @@ cdef aut_gp_and_can_lab *get_aut_gp_and_can_lab(void *S, deallocate_agcl_work_space(work_space) return output - - - - - - - - - - - - - - diff --git a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx index 6daef964ebc..3f726879292 100644 --- a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx +++ b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx @@ -733,8 +733,3 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order if work_space_prealloc is NULL: deallocate_dc_work_space(work_space) return 1 if (possible and not unknown) else 0 - - - - - diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index f13fccf891a..e18fdf5f41a 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -1148,5 +1148,3 @@ def random_tests(num=50, n_max=50, k_max=6, nwords_max=200, perms_per_code=10, d num_codes += 2 print("All passed: %d random tests on %d codes." % (num_tests, num_codes)) - - diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx index 815b3bcc89d..a24b0499888 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx @@ -582,6 +582,3 @@ def double_coset_python(S1, S2, partition1, ordering2, n, output_py = False sig_free(output) return output_py - - - diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx index 6e80294db3c..912c9a31a0d 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx @@ -854,9 +854,3 @@ def sets_modulo_perm_group(list generators, int max_size, else: out_list.append(MemoryError()) return out_list - - - - - - diff --git a/src/sage/groups/raag.py b/src/sage/groups/raag.py index e8d626a32a4..736430e8af2 100644 --- a/src/sage/groups/raag.py +++ b/src/sage/groups/raag.py @@ -656,7 +656,7 @@ def __init__(self, R, A): if R not in Fields(): raise NotImplementedError("only implemented with coefficients in a field") self._group = A - + names = tuple(['e' + name[1:] for name in A.variable_names()]) from sage.graphs.independent_sets import IndependentSets from sage.sets.finite_enumerated_set import FiniteEnumeratedSet diff --git a/src/sage/homology/chain_complex_morphism.py b/src/sage/homology/chain_complex_morphism.py index a29ccaae1a7..b049b534e0b 100644 --- a/src/sage/homology/chain_complex_morphism.py +++ b/src/sage/homology/chain_complex_morphism.py @@ -140,7 +140,7 @@ def __init__(self, matrices, C, D, check=True): d = C.degree_of_differential() if d != D.degree_of_differential(): raise ValueError('degree of differential does not match') - + degrees = list(C.differential()) + list(D.differential()) degrees = sorted(set(degrees)) initial_matrices = dict(matrices) diff --git a/src/sage/homology/chain_homotopy.py b/src/sage/homology/chain_homotopy.py index 16a1c385edc..afeaee2430c 100644 --- a/src/sage/homology/chain_homotopy.py +++ b/src/sage/homology/chain_homotopy.py @@ -269,7 +269,7 @@ def is_homology_gradient_vector_field(self): if matrices[i] * self.domain().differential(i-deg) * matrices[i] != matrices[i]: return False return True - + def in_degree(self, n): """ The matrix representing this chain homotopy in degree ``n``. diff --git a/src/sage/homology/hochschild_complex.py b/src/sage/homology/hochschild_complex.py index ef68448c685..f372a08e0e8 100644 --- a/src/sage/homology/hochschild_complex.py +++ b/src/sage/homology/hochschild_complex.py @@ -669,7 +669,7 @@ def arrow_art(d): def _add_(self, other): """ Module addition - + EXAMPLES:: sage: F. = FreeAlgebra(ZZ) diff --git a/src/sage/homology/simplicial_complex_morphism.py b/src/sage/homology/simplicial_complex_morphism.py index 4673be7d414..889c266dc0a 100644 --- a/src/sage/homology/simplicial_complex_morphism.py +++ b/src/sage/homology/simplicial_complex_morphism.py @@ -3,11 +3,10 @@ The current version is :mod:`sage.topology.simplicial_complex_morphism`. """ - from sage.misc.superseded import deprecated_function_alias import sage.topology.simplicial_complex_morphism -is_SimplicialComplexMorphism = deprecated_function_alias(31925, +is_SimplicialComplexMorphism = deprecated_function_alias(31925, sage.topology.simplicial_complex_morphism.is_SimplicialComplexMorphism) SimplicialComplexMorphism = deprecated_function_alias(31925, sage.topology.simplicial_complex_morphism.SimplicialComplexMorphism) diff --git a/src/sage/homology/simplicial_set_examples.py b/src/sage/homology/simplicial_set_examples.py index 8a19cef5a86..8945e2b51de 100644 --- a/src/sage/homology/simplicial_set_examples.py +++ b/src/sage/homology/simplicial_set_examples.py @@ -4,7 +4,6 @@ The current version is :mod:`sage.topology.simplicial_set_examples`. """ - from sage.misc.superseded import deprecated_function_alias import sage.topology.simplicial_set_examples @@ -22,4 +21,3 @@ 'simplicial_data_from_kenzo_output', 'HopfMap']: exec('{} = deprecated_function_alias(31925, sage.topology.simplicial_set_examples.{})'.format(f, f)) - diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 10035f729ef..12e159db251 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1956,13 +1956,14 @@ def conway_polynomial(self): M = max(alex.exponents()) coeff = alex[M] alex -= coeff * binom**M - conway += coeff * t_poly**M + conway += coeff * t_poly**M return conway def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ): r""" - Return the Khovanov polynomial of ``self``. This is the Poincaré - polynomial of the Khovanov homology. + Return the Khovanov polynomial of ``self``. + + This is the Poincaré polynomial of the Khovanov homology. INPUT: diff --git a/src/sage/modules/fg_pid/fgp_element.py b/src/sage/modules/fg_pid/fgp_element.py index c2ed4590188..dadf8745f88 100644 --- a/src/sage/modules/fg_pid/fgp_element.py +++ b/src/sage/modules/fg_pid/fgp_element.py @@ -363,7 +363,7 @@ def _vector_(self, base_ring=None): - ``base_ring`` -- the desired base ring of the vector. OUTPUT: - + A vector over the base ring. EXAMPLES:: diff --git a/src/sage/modules/module.pyx b/src/sage/modules/module.pyx index 3b6875ce0d1..9d76034a926 100644 --- a/src/sage/modules/module.pyx +++ b/src/sage/modules/module.pyx @@ -302,5 +302,3 @@ def is_VectorSpace(x): return is_Module(x) and x.base_ring().is_field() except AttributeError: return False - - diff --git a/src/sage/modules/module_functors.py b/src/sage/modules/module_functors.py index 497120d02e8..c3977183c56 100644 --- a/src/sage/modules/module_functors.py +++ b/src/sage/modules/module_functors.py @@ -7,7 +7,7 @@ :class:`QuotientModuleFunctor` """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2017 Travis Scrimshaw # # This program is free software: you can redistribute it and/or modify @@ -15,8 +15,8 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** - +# **************************************************************************** + ############################################################## # Construction functor for quotient modules ############################################################## @@ -24,6 +24,7 @@ from sage.categories.pushout import ConstructionFunctor from sage.categories.modules import Modules + class QuotientModuleFunctor(ConstructionFunctor): r""" Construct the quotient of a module by a submodule. @@ -48,9 +49,9 @@ class QuotientModuleFunctor(ConstructionFunctor): QuotientModuleFunctor sage: F(A) == Q True - + The modules are constructed from the cover not the ambient module:: - + sage: F(B.ambient_module()) == Q False diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index cee4f2f7970..43f3322d627 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -113,5 +113,3 @@ def unpickle_v1(parent, entries, degree, is_mutable=None): if is_mutable is not None: v._is_immutable = not is_mutable return v - - diff --git a/src/sage/modules/vector_integer_sparse.pyx b/src/sage/modules/vector_integer_sparse.pyx index 01c45059880..de91aab408e 100644 --- a/src/sage/modules/vector_integer_sparse.pyx +++ b/src/sage/modules/vector_integer_sparse.pyx @@ -402,4 +402,3 @@ cdef int mpz_vector_cmp(mpz_vector* v, mpz_vector* w): elif c > 0: return 1 return 0 - diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 4798810c886..9d57897febe 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -512,4 +512,3 @@ def unpickle_v0(parent, entries, degree, is_immutable): mzd_write_bit(v._entries, 0, i, entries[i]%2) v._is_immutable = int(is_immutable) return v - diff --git a/src/sage/modules/vector_rational_sparse.pyx b/src/sage/modules/vector_rational_sparse.pyx index 78002a1a75f..14d0953b3df 100644 --- a/src/sage/modules/vector_rational_sparse.pyx +++ b/src/sage/modules/vector_rational_sparse.pyx @@ -409,4 +409,3 @@ cdef int mpq_vector_cmp(mpq_vector* v, mpq_vector* w): elif c > 0: return 1 return 0 - diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 33af946e8a0..12565a411e2 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -22,6 +22,7 @@ from sage.sets.family import Family from sage.matrix.constructor import Matrix + class FiniteDimensionalInvariantModule(SubmoduleWithBasis): r""" The invariant submodule under a semigroup action. @@ -65,7 +66,7 @@ class FiniteDimensionalInvariantModule(SubmoduleWithBasis): sage: [I.lift(b) for b in I.basis()] [M[1] + M[2] + M[3]] - + The we could also have the action be a right-action, instead of the default left-action:: diff --git a/src/sage/quivers/morphism.py b/src/sage/quivers/morphism.py index 04c45658d13..b8bb25657eb 100644 --- a/src/sage/quivers/morphism.py +++ b/src/sage/quivers/morphism.py @@ -562,7 +562,7 @@ def __ne__(self, other): # If all that holds just check the vectors return self._vector != other._vector - def __bool__(self): + def __bool__(self) -> bool: """ Return whether ``self`` is the zero morphism. @@ -586,8 +586,6 @@ def __bool__(self): """ return any(self._vector) - - def __mul__(self, other): """ This function overrides the ``*`` operator diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index 0e14ab6dd1e..73eeb69854e 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -265,7 +265,7 @@ def _rmul_(self, s): """ return self.__class__([(s*c, x) for (c, x) in self], check=False, parent=self.parent()) - def __bool__(self): + def __bool__(self) -> bool: """ EXAMPLES:: @@ -278,8 +278,6 @@ def __bool__(self): """ return not all(c.is_zero() for c, _ in self._data) - - def reduce(self): """ EXAMPLES:: diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index a529d39cd5e..8a3411bdc8f 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -613,7 +613,7 @@ def __rmul__(self, other): """ return other * self._options[self._name] - def __bool__(self): + def __bool__(self) -> bool: r""" Return the value of this option interpreted as a boolean. @@ -630,9 +630,6 @@ def __bool__(self): """ return bool(self._options[self._name]) - # for the less sensibly named python 2 family - - def __call__(self, *args, **kwds): r""" Get or set value of the option ``self``. diff --git a/src/sage/structure/mutability.pyx b/src/sage/structure/mutability.pyx index b35d26a3ccb..4aa466513c8 100644 --- a/src/sage/structure/mutability.pyx +++ b/src/sage/structure/mutability.pyx @@ -69,9 +69,9 @@ cdef class Mutability: cpdef _require_mutable(self): r""" Whenever mutability is required, this method can be called. - + EXAMPLES:: - + sage: class A(SageObject, Mutability): ....: def __init__(self, val): ....: self._val = val @@ -87,7 +87,7 @@ cdef class Mutability: Traceback (most recent call last): ... ValueError: object is immutable; please change a copy instead - + """ if self._is_immutable: raise ValueError("object is immutable; please change a copy instead") @@ -95,9 +95,9 @@ cdef class Mutability: cpdef _require_immutable(self): r""" Whenever immutability is required, this method can be called. - + EXAMPLES:: - + sage: class A(SageObject, Mutability): ....: def __init__(self, val): ....: self._val = val @@ -112,7 +112,7 @@ cdef class Mutability: Traceback (most recent call last): ... ValueError: object is mutable; please make it immutable first - + """ if not self._is_immutable: raise ValueError("object is mutable; please make it immutable first") @@ -160,11 +160,11 @@ cdef class Mutability: """ Return ``True`` if this object is mutable (can be changed) and ``False`` if it is not. - + To make this object immutable use ``self.set_immutable()``. - + EXAMPLES:: - + sage: v = Sequence([1,2,3,4/5]) sage: v[0] = 5 sage: v @@ -180,9 +180,9 @@ cdef class Mutability: def __getstate__(self): r""" Get the current state of ``self`` including the mutability status. - + TESTS:: - + sage: class A(SageObject, Mutability): ....: def __init__(self, val): ....: self._val = val @@ -203,7 +203,7 @@ cdef class Mutability: , ), {'_is_immutable': False, '_val': 4}) - + """ state = getattr(self, '__dict__', {}) state['_is_immutable'] = self._is_immutable diff --git a/src/sage/structure/parent_base.pyx b/src/sage/structure/parent_base.pyx index 91c62424dae..907f84ec89f 100644 --- a/src/sage/structure/parent_base.pyx +++ b/src/sage/structure/parent_base.pyx @@ -41,4 +41,3 @@ cdef class ParentWithBase(Parent_old): check_old_coerce(self) raise CoercionException("BUG: the base_extend method must be defined for '%s' (class '%s')" % (self, type(self))) - diff --git a/src/sage/structure/parent_gens.pyx b/src/sage/structure/parent_gens.pyx index 45e82720f43..c4155736e99 100644 --- a/src/sage/structure/parent_gens.pyx +++ b/src/sage/structure/parent_gens.pyx @@ -373,5 +373,3 @@ cdef class localvars: def __exit__(self, type, value, traceback): self._obj.__temporarily_change_names(self._orig[0], self._orig[1]) - - From 539da7dfabe48a9e5ecc8b7f44510afe3d63b614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 17 Oct 2022 15:36:17 +0200 Subject: [PATCH 328/350] spaces in matroids, plot, sets --- src/sage/matroids/lean_matrix.pyx | 1 - src/sage/matroids/matroid.pyx | 6 +++--- src/sage/plot/plot3d/transform.pyx | 1 - src/sage/sets/disjoint_set.pyx | 2 -- src/sage/sets/disjoint_union_enumerated_sets.py | 4 ++-- src/sage/sets/finite_enumerated_set.py | 4 +--- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 01aaefc2f27..6b3cf27bcf2 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -3682,4 +3682,3 @@ cdef class RationalMatrix(LeanMatrix): version = 0 data = (self.nrows(), self.ncols(), entries) return unpickle_rational_matrix, (version, data) - diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 7378d250e44..6c43b0d896d 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -7985,8 +7985,8 @@ cdef class Matroid(SageObject): for c in LM.chains(exclude=LM.maximal_elements()): if c: # the facets of IM are already present # get the cardinality of intersection of facet with IM - r = self.rank() - len(c) - + r = self.rank() - len(c) + # get candidate independent_sets for I in self.independent_r_sets(r): if I.issubset(c[0]): @@ -8012,7 +8012,7 @@ cdef class Matroid(SageObject): OUTPUT: - An instance of + An instance of :class:`MatroidUnion `. EXAMPLES:: diff --git a/src/sage/plot/plot3d/transform.pyx b/src/sage/plot/plot3d/transform.pyx index b140a1c1c41..299ea0ee25c 100644 --- a/src/sage/plot/plot3d/transform.pyx +++ b/src/sage/plot/plot3d/transform.pyx @@ -266,4 +266,3 @@ def rotate_arbitrary(v, double theta): (1 - cos_t)*z*z + cos_t ] return matrix(RDF, 3, 3, entries) - diff --git a/src/sage/sets/disjoint_set.pyx b/src/sage/sets/disjoint_set.pyx index 02cde67d017..aaa12438f15 100644 --- a/src/sage/sets/disjoint_set.pyx +++ b/src/sage/sets/disjoint_set.pyx @@ -887,7 +887,6 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): {{0}, {1, 2, 3, 4}} sage: d.to_digraph().edges(sort=True) [(0, 0, None), (1, 1, None), (2, 1, None), (3, 1, None), (4, 1, None)] - """ d = {} for i from 0 <= i < self.cardinality(): @@ -896,4 +895,3 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): d[e] = [p] from sage.graphs.graph import DiGraph return DiGraph(d) - diff --git a/src/sage/sets/disjoint_union_enumerated_sets.py b/src/sage/sets/disjoint_union_enumerated_sets.py index 7b95a9dc945..c1276dc9edf 100644 --- a/src/sage/sets/disjoint_union_enumerated_sets.py +++ b/src/sage/sets/disjoint_union_enumerated_sets.py @@ -542,11 +542,11 @@ def _element_constructor_facade(self, el): sage: p = X._element_constructor_((0, [])) # indirect doctest sage: p[1].parent() Partitions of the integer 0 - + Test that facade parents can create and properly access elements that are tuples (fixed by :trac:`22382`):: - sage: f = lambda mu: cartesian_product([mu.standard_tableaux(), + sage: f = lambda mu: cartesian_product([mu.standard_tableaux(), ....: mu.standard_tableaux()]) sage: tabs = DisjointUnionEnumeratedSets(Family(Partitions(4), f)) sage: s = StandardTableau([[1,3],[2,4]]) diff --git a/src/sage/sets/finite_enumerated_set.py b/src/sage/sets/finite_enumerated_set.py index d8745d13844..a2f5dc759ec 100644 --- a/src/sage/sets/finite_enumerated_set.py +++ b/src/sage/sets/finite_enumerated_set.py @@ -109,7 +109,7 @@ def __init__(self, elements): self._elements = elements Parent.__init__(self, facade=True, category=FiniteEnumeratedSets()) - def __bool__(self): + def __bool__(self) -> bool: r""" Conversion to boolean. @@ -122,8 +122,6 @@ def __bool__(self): """ return bool(self._elements) - - def _repr_(self): """ TESTS:: From ca00c97bc3c4beee54c28157634a919d4b7eebb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 17 Oct 2022 15:41:34 +0200 Subject: [PATCH 329/350] spaces in crypto, data_structures and symbolic --- src/sage/crypto/boolean_function.pyx | 1 - src/sage/crypto/sbox.pyx | 1 - src/sage/data_structures/binary_search.pyx | 1 - src/sage/data_structures/blas_dict.pyx | 1 - src/sage/symbolic/assumptions.py | 1 - src/sage/symbolic/callable.py | 2 +- src/sage/symbolic/complexity_measures.py | 5 +++-- src/sage/symbolic/expression.pyx | 2 +- 8 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index 887afd683fd..1584ca252ac 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -1464,4 +1464,3 @@ def random_boolean_function(n): sig_check() T.bits[i] = r.randrange(0,Integer(1)<<(sizeof(unsigned long)*8)) return B - diff --git a/src/sage/crypto/sbox.pyx b/src/sage/crypto/sbox.pyx index 6e08ba3501c..77b7a904cc2 100644 --- a/src/sage/crypto/sbox.pyx +++ b/src/sage/crypto/sbox.pyx @@ -2030,4 +2030,3 @@ def misty_construction(*args): 64 """ return sbox_construction(misty_substitute, list(args)) - diff --git a/src/sage/data_structures/binary_search.pyx b/src/sage/data_structures/binary_search.pyx index 030d50266e5..a53061c3efb 100644 --- a/src/sage/data_structures/binary_search.pyx +++ b/src/sage/data_structures/binary_search.pyx @@ -63,4 +63,3 @@ cdef Py_ssize_t binary_search0(Py_ssize_t* v, Py_ssize_t n, Py_ssize_t x): else: # only possibility is that v[k] == x return k return -1 - diff --git a/src/sage/data_structures/blas_dict.pyx b/src/sage/data_structures/blas_dict.pyx index 55364880150..df6bf29641e 100644 --- a/src/sage/data_structures/blas_dict.pyx +++ b/src/sage/data_structures/blas_dict.pyx @@ -448,4 +448,3 @@ cpdef dict convert_remove_zeroes(dict D, R): for index in for_removal: del D[index] return D - diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py index 706de96005d..4616fd2880b 100644 --- a/src/sage/symbolic/assumptions.py +++ b/src/sage/symbolic/assumptions.py @@ -883,7 +883,6 @@ class assuming: [x == -2, x == 2] sage: with assuming(x > 0): ....: solve(x^2 == 4,x) - ....: [x == 2] sage: assumptions() [] diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index 4a123ec0e33..e570b06bc98 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -358,7 +358,7 @@ def _repr_(self): sage: R._repr_() 'Callable function ring with arguments (x, y, theta)' - We verify that :trac:`12298` has been fixed:: + We verify that :trac:`12298` has been fixed:: sage: S = CallableSymbolicExpressionRing([var('z')]) sage: S._repr_() diff --git a/src/sage/symbolic/complexity_measures.py b/src/sage/symbolic/complexity_measures.py index 1b5823e38bf..528d1bf6906 100644 --- a/src/sage/symbolic/complexity_measures.py +++ b/src/sage/symbolic/complexity_measures.py @@ -6,6 +6,7 @@ return a number. """ + def string_length(expr): """ Returns the length of ``expr`` after converting it to a string. @@ -22,11 +23,11 @@ def string_length(expr): If the expression is longer on-screen, then a human would probably consider it more complex. - + EXAMPLES: This expression has three characters, ``x``, ``^``, and ``2``:: - + sage: from sage.symbolic.complexity_measures import string_length sage: f = x^2 sage: string_length(f) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 7ee103f8555..903a8541460 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -11901,7 +11901,7 @@ cdef class Expression(Expression_abc): Check that :trac:`33640` is fixed:: - sage: ((x + 1)^2 - 2*x - 1).factor() + sage: ((x + 1)^2 - 2*x - 1).factor() x^2 """ from sage.calculus.calculus import symbolic_expression_from_maxima_string From 50b7486518c54ac32c358e2811c188aea3842c84 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 17 Oct 2022 13:56:04 -0700 Subject: [PATCH 330/350] src/sage/misc/package_dir.py: Fix doctest after #32874 --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index abc64fe7f91..17e0ce7b72c 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -105,7 +105,7 @@ def read_distribution(src_file): EXAMPLES:: sage: from sage.env import SAGE_SRC - sage: from sage_setup.find import read_distribution + sage: from sage.misc.package_dir import read_distribution sage: read_distribution(os.path.join(SAGE_SRC, 'sage', 'graphs', 'graph_decompositions', 'tdlib.pyx')) 'sagemath-tdlib' sage: read_distribution(os.path.join(SAGE_SRC, 'sage', 'graphs', 'graph_decompositions', 'modular_decomposition.py')) From cd370cb74bc9ad49815be69d0d424bf2b02099d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 17 Oct 2022 18:01:17 +0200 Subject: [PATCH 331/350] change iterator for ordered set partitions --- src/sage/combinat/set_partition_ordered.py | 274 ++++++++++++++------- 1 file changed, 190 insertions(+), 84 deletions(-) diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index f2f201eb7f2..de11741b55f 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -25,36 +25,35 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from sage.arith.all import factorial, multinomial -from sage.sets.set import Set, Set_generic +from sage.categories.cartesian_product import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets -from sage.sets.finite_enumerated_set import FiniteEnumeratedSet -from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.structure.parent import Parent -from sage.structure.element import parent -from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.list_clone import ClonableArray -from sage.structure.richcmp import richcmp -from sage.rings.integer import Integer -from sage.rings.integer_ring import ZZ -from sage.combinat.combinatorial_map import combinatorial_map from sage.combinat.combinat import stirling_number2 +from sage.combinat.combinatorial_map import combinatorial_map from sage.combinat.composition import Composition, Compositions -from sage.combinat.words.words import Words from sage.combinat.words.finite_word import FiniteWord_class -import sage.combinat.permutation as permutation -from functools import reduce -from sage.categories.cartesian_product import cartesian_product +from sage.combinat.words.words import Words +from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass +from sage.misc.persist import register_unpickle_override +from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ +from sage.sets.finite_enumerated_set import FiniteEnumeratedSet +from sage.sets.set import Set, Set_generic +from sage.structure.list_clone import ClonableArray +from sage.structure.parent import Parent +from sage.structure.richcmp import richcmp +from sage.structure.unique_representation import UniqueRepresentation class OrderedSetPartition(ClonableArray, - metaclass=InheritComparisonClasscallMetaclass): + metaclass=InheritComparisonClasscallMetaclass): r""" An ordered partition of a set. An ordered set partition `p` of a set `s` is a list of pairwise disjoint nonempty subsets of `s` such that the union of these subsets is `s`. These subsets are called the parts of the partition. + We represent an ordered set partition as a list of sets. By extension, an ordered set partition of a nonnegative integer `n` is the set partition of the integers from `1` to `n`. The number of @@ -146,6 +145,10 @@ class OrderedSetPartition(ClonableArray, sage: OrderedSetPartition(from_word='bdab') [{3}, {1, 4}, {2}] + .. WARNING:: + + The elements of the underlying set should be hashable. + REFERENCES: :wikipedia:`Ordered_partition_of_a_set` @@ -179,15 +182,14 @@ def __classcall_private__(cls, parts=None, from_word=None): if parts is None and from_word is None: P = OrderedSetPartitions([]) return P.element_class(P, []) + W = Words(infinite=False) if from_word: - return OrderedSetPartitions().from_finite_word(Words()(from_word)) + return OrderedSetPartitions().from_finite_word(W(from_word)) # if `parts` looks like a sequence of "letters" then treat it like a word. - if parts in Words() or (parts and (parts[0] in ZZ or isinstance(parts[0], str))): - return OrderedSetPartitions().from_finite_word(Words()(parts)) - else: - P = OrderedSetPartitions(reduce(lambda x, y: x.union(y), - parts, frozenset())) - return P.element_class(P, parts) + if parts in W or (parts and (parts[0] in ZZ or isinstance(parts[0], str))): + return OrderedSetPartitions().from_finite_word(W(parts)) + P = OrderedSetPartitions(set(x for p in parts for x in p)) + return P.element_class(P, parts) def __init__(self, parent, s): """ @@ -199,8 +201,7 @@ def __init__(self, parent, s): sage: s = OS([[1, 3], [2, 4]]) sage: TestSuite(s).run() """ - self._base_set = reduce(lambda x, y: x.union(y), map(Set, s), Set([])) - ClonableArray.__init__(self, parent, [Set(elt) for elt in s]) + ClonableArray.__init__(self, parent, [Set(part) for part in s]) def _repr_(self): """ @@ -252,13 +253,23 @@ def base_set(self): EXAMPLES:: sage: OrderedSetPartition([[1], [2,3], [4]]).base_set() - {1, 2, 3, 4} + frozenset({1, 2, 3, 4}) sage: OrderedSetPartition([[1,2,3,4]]).base_set() - {1, 2, 3, 4} + frozenset({1, 2, 3, 4}) sage: OrderedSetPartition([]).base_set() - {} + frozenset() + + TESTS:: + + sage: S = OrderedSetPartitions() + sage: x = S([['a', 'c', 'e'], ['b', 'd']]) + sage: x.base_set() + frozenset({'a', 'b', 'c', 'd', 'e'}) """ - return Set([e for p in self for e in p]) + try: + return self.parent()._set + except AttributeError: # in OrderedSetPartitions_all + return frozenset(x for part in self for x in part) def base_set_cardinality(self): """ @@ -275,7 +286,7 @@ def base_set_cardinality(self): sage: OrderedSetPartition([[1,2,3,4]]).base_set_cardinality() 4 """ - return sum(len(x) for x in self) + return len(self.parent()._set) size = base_set_cardinality @@ -342,9 +353,10 @@ def sum(osps): sage: C = OrderedSetPartition.sum([A, B]); C [{2}, {1, 3}, {5}] sage: C.parent() - Ordered set partitions + Ordered set partitions of {1, 2, 3, 5} """ - return OrderedSetPartitions()(sum((list(i) for i in osps), [])) + lset = set(x for osp in osps for x in osp.base_set()) + return OrderedSetPartitions(lset)(sum((list(i) for i in osps), [])) def reversed(self): r""" @@ -365,7 +377,7 @@ def reversed(self): sage: OrderedSetPartition([]).reversed() [] """ - par = parent(self) + par = self.parent() return par(list(reversed(self))) def complement(self): @@ -403,7 +415,8 @@ def complement(self): m = min(base_set) M = max(base_set) mM = m + M - return OrderedSetPartitions()([[mM - i for i in part] for part in self]) + par = self.parent() + return par([[mM - i for i in part] for part in self]) def finer(self): """ @@ -435,12 +448,11 @@ def finer(self): [{4, 9}, {-1}, {2}], [{4, 9}, {-1, 2}]] """ - par = parent(self) + par = self.parent() if not self: return FiniteEnumeratedSet([self]) - else: - return FiniteEnumeratedSet([par(sum((list(i) for i in C), [])) - for C in cartesian_product([OrderedSetPartitions(X) for X in self])]) + return FiniteEnumeratedSet([par(sum((list(i) for i in C), [])) + for C in cartesian_product([OrderedSetPartitions(X) for X in self])]) def is_finer(self, co2): """ @@ -480,7 +492,7 @@ def is_finer(self, co2): i1 = 0 for j2 in co2: - sum1 = Set([]) + sum1 = Set() while len(sum1) < len(j2): sum1 += co1[i1] i1 += 1 @@ -536,9 +548,9 @@ def fatten(self, grouping): result = [None] * len(grouping) j = 0 for i in range(len(grouping)): - result[i] = sum(self[j:j+grouping[i]], Set([])) + result[i] = sum(self[j:j+grouping[i]], Set()) j += grouping[i] - return parent(self)(result) + return self.parent()(result) def fatter(self): """ @@ -614,7 +626,7 @@ def bottom_up_osp(X, comp): sage: buo = OrderedSetPartition.bottom_up_osp sage: parent(buo(Set([1, 4, 7, 9]), [2, 1, 1])) - Ordered set partitions + Ordered set partitions of {1, 4, 9, 7} sage: buo((3, 5, 6), (2, 1)) [{3, 5}, {6}] sage: buo([3, 5, 6], Composition([1, 2])) @@ -626,7 +638,7 @@ def bottom_up_osp(X, comp): for i in range(len(comp)): result[i] = Set(xs[j:j+comp[i]]) j += comp[i] - return OrderedSetPartitions()(result) + return OrderedSetPartitions(X)(result) def strongly_finer(self): """ @@ -654,13 +666,12 @@ def strongly_finer(self): [{4, 9}, {-1}, {2}], [{4, 9}, {-1, 2}]] """ - par = parent(self) + par = self.parent() if not self: return FiniteEnumeratedSet([self]) - else: - buo = OrderedSetPartition.bottom_up_osp - return FiniteEnumeratedSet([par(sum((list(P) for P in C), [])) - for C in cartesian_product([[buo(X, comp) for comp in Compositions(len(X))] for X in self])]) + buo = OrderedSetPartition.bottom_up_osp + return FiniteEnumeratedSet([par(sum((list(P) for P in C), [])) + for C in cartesian_product([[buo(X, comp) for comp in Compositions(len(X))] for X in self])]) def is_strongly_finer(self, co2): r""" @@ -703,7 +714,7 @@ def is_strongly_finer(self, co2): i1 = 0 for j2 in co2: - sum1 = Set([]) + sum1 = Set() while len(sum1) < len(j2): next = co1[i1] if sum1 and max(sum1) >= min(next): @@ -791,7 +802,7 @@ def to_packed_word(self): .. WARNING:: This assumes there is a total order on the underlying - set (``self._base_set``). + set. EXAMPLES:: @@ -799,16 +810,18 @@ def to_packed_word(self): sage: x = S([[3,5], [2], [1,4,6]]) sage: x.to_packed_word() word: 321313 + sage: x = S([['a', 'c', 'e'], ['b', 'd']]) sage: x.to_packed_word() word: 12121 """ - X = sorted(self._base_set) + X = sorted(self.base_set()) out = {} for i in range(len(self)): for letter in self[i]: out[letter] = i - return Words()([out[letter] + 1 for letter in X]) + W = Words(infinite=False) + return W([out[letter] + 1 for letter in X]) def number_of_inversions(self): r""" @@ -841,6 +854,7 @@ def number_of_inversions(self): num_invs += sum(1 for j in self[ell] if i < j) return ZZ(num_invs) + class OrderedSetPartitions(UniqueRepresentation, Parent): """ Return the combinatorial class of ordered set partitions of ``s``. @@ -898,6 +912,13 @@ class OrderedSetPartitions(UniqueRepresentation, Parent): [{'t'}, {'a', 'c'}], [{'t'}, {'a'}, {'c'}], [{'t'}, {'c'}, {'a'}]] + + TESTS:: + + sage: S = OrderedSetPartitions() + sage: x = S([[3,5], [2], [1,4,6]]) + sage: x.parent() + Ordered set partitions """ @staticmethod def __classcall_private__(cls, s=None, c=None): @@ -918,7 +939,7 @@ def __classcall_private__(cls, s=None, c=None): if isinstance(s, (int, Integer)): if s < 0: raise ValueError("s must be non-negative") - s = frozenset(range(1, s+1)) + s = frozenset(range(1, s + 1)) else: s = frozenset(s) @@ -950,12 +971,14 @@ def _element_constructor_(self, s): EXAMPLES:: sage: OS = OrderedSetPartitions(4) - sage: OS([[1,3],[2,4]]) + sage: x = OS([[1,3],[2,4]]); x [{1, 3}, {2, 4}] + sage: x.parent() + Ordered set partitions of {1, 2, 3, 4} """ if isinstance(s, OrderedSetPartition): raise ValueError("cannot convert %s into an element of %s" % (s, self)) - return self.element_class(self, list(s)) + return self.element_class(self, list(s)) # HERE the parent "self" is not good Element = OrderedSetPartition @@ -975,7 +998,7 @@ def __contains__(self, x): ... TypeError: X (=...1, 2...) must be a Set """ - #x must be a list + # x must be a list if not isinstance(x, (OrderedSetPartition, list, tuple)): return False @@ -986,7 +1009,7 @@ def __contains__(self, x): # Check to make sure each element of the list # is a nonempty set - u = Set([]) + u = Set() for s in x: if not s or not isinstance(s, (set, frozenset, Set_generic)): return False @@ -994,10 +1017,7 @@ def __contains__(self, x): # Make sure that the union of all the # sets is the original set - if u != Set(self._set): - return False - - return True + return len(u) == len(self._set) def from_finite_word(self, w): r""" @@ -1015,13 +1035,21 @@ def from_finite_word(self, w): sage: B = OrderedSetPartitions().from_finite_word([1,2,3,1,2,3,1,2,4]) sage: A == B True + + TESTS:: + + sage: A = OrderedSetPartitions().from_finite_word('abcabca') + sage: A.parent() + Ordered set partitions of {1, 2, 3, 4, 5, 6, 7} """ # TODO: fix this if statement. # In fact, what we need is for the underlying alphabet to be sortable. if isinstance(w, (list, tuple, str, FiniteWord_class)): - return self.element_class(self, Words()(w).to_ordered_set_partition()) - else: - raise ValueError("Something is wrong: `from_finite_word` expects an object of type list/tuple/str/Word representing a finite word, received {}.".format(str(w))) + W = Words(infinite=False) + s = frozenset(range(1, len(w) + 1)) + return self.element_class(self.subset(s), W(w).to_ordered_set_partition()) + raise TypeError(f"`from_finite_word` expects an object of type list/tuple/str/Word " + f"representing a finite word, received {w}") class OrderedSetPartitions_s(OrderedSetPartitions): @@ -1056,14 +1084,15 @@ def cardinality(self): sage: OrderedSetPartitions(5).cardinality() 541 """ - return sum([factorial(k)*stirling_number2(len(self._set), k) - for k in range(len(self._set)+1)]) + N = len(self._set) + return sum(factorial(k) * stirling_number2(N, k) + for k in range(N + 1)) def __iter__(self): """ EXAMPLES:: - sage: [ p for p in OrderedSetPartitions([1,2,3]) ] + sage: list(OrderedSetPartitions([1,2,3])) [[{1}, {2}, {3}], [{1}, {3}, {2}], [{2}, {1}, {3}], @@ -1262,21 +1291,99 @@ def __iter__(self): {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}, {37}, {38}, {39}, {40}, {41}, {42}] + + EXAMPLES:: + + sage: list(OrderedSetPartitions(range(5), [2,1,2])) + [[{0, 1}, {2}, {3, 4}], + [{0, 1}, {3}, {2, 4}], + ... + [{2, 4}, {3}, {0, 1}], + [{3, 4}, {2}, {0, 1}]] """ - comp = self.c - lset = [x for x in self._set] - l = len(self.c) - dcomp = [-1] + comp.descents(final_descent=True) + part_sizes = self.c + N = len(part_sizes) + if not N: + yield self.element_class(self, []) + return + + l = [] + lset = list(self._set) + for i, j in enumerate(part_sizes): + l.extend([i] * j) - p = [] - for j in range(l): - p += [j + 1] * comp[j] + pi = multiset_permutation_to_ordered_set_partition(l, N) + converted = [frozenset(lset[i] for i in part) for part in pi] + yield self.element_class(self, converted) - for x in permutation.Permutations_mset(p): - res = permutation.to_standard(x).inverse() - res = [lset[x - 1] for x in res] - yield self.element_class(self, [Set(res[dcomp[i]+1:dcomp[i+1]+1]) - for i in range(l)]) + while multiset_permutation_next_lex(l): + pi = multiset_permutation_to_ordered_set_partition(l, N) + converted = [frozenset(lset[i] for i in part) for part in pi] + yield self.element_class(self, converted) + + +def multiset_permutation_to_ordered_set_partition(l, m): + """ + Convert a multiset permutation to an ordered set partition. + + INPUT: + + - ``l`` -- a multiset permutation + + - ``m`` -- number of parts + + EXAMPLES:: + + sage: from sage.combinat.set_partition_ordered import multiset_permutation_to_ordered_set_partition + sage: l = [0, 0, 1, 1, 2] + sage: multiset_permutation_to_ordered_set_partition(l, 3) + [[0, 1], [2, 3], [4]] + """ + p = [[] for _ in range(m)] + for i, j in enumerate(l): + p[j].append(i) + return p + + +def multiset_permutation_next_lex(l): + r""" + Return the next multiset permutation after ``l``. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_ordered import multiset_permutation_next_lex + sage: l = [0, 0, 1, 1, 2] + sage: while multiset_permutation_next_lex(l): + ....: print(l) + [0, 0, 1, 2, 1] + [0, 0, 2, 1, 1] + [0, 1, 0, 1, 2] + [0, 1, 0, 2, 1] + [0, 1, 1, 0, 2] + [0, 1, 1, 2, 0] + ... + [1, 1, 2, 0, 0] + [1, 2, 0, 0, 1] + [1, 2, 0, 1, 0] + [1, 2, 1, 0, 0] + [2, 0, 0, 1, 1] + [2, 0, 1, 0, 1] + [2, 0, 1, 1, 0] + [2, 1, 0, 0, 1] + [2, 1, 0, 1, 0] + [2, 1, 1, 0, 0] + """ + i = len(l) - 2 + while i >= 0 and l[i] >= l[i + 1]: + i -= 1 + if i == -1: + return 0 + j = len(l) - 1 + while l[j] <= l[i]: + j -= 1 + l[i], l[j] = l[j], l[i] + l[i + 1:] = l[:i:-1] + return 1 class OrderedSetPartitions_all(OrderedSetPartitions): @@ -1368,7 +1475,7 @@ def __contains__(self, x): if x.parent() is self: return True gset = x.parent()._set - return gset == frozenset(range(1, len(gset)+1)) + return gset == frozenset(range(1, len(gset) + 1)) # x must be a list or a tuple if not isinstance(x, (list, tuple)): @@ -1380,8 +1487,8 @@ def __contains__(self, x): if not all(isinstance(s, (set, frozenset, Set_generic)) or len(s) == len(set(s)) for s in x): return False - X = set(reduce(lambda A,B: A.union(B), x, set())) - return len(X) == sum(len(s) for s in x) and X == set(range(1,len(X)+1)) + X = set(y for p in x for y in p) + return len(X) == sum(len(s) for s in x) and X == frozenset(range(1, len(X) + 1)) def _coerce_map_from_(self, X): """ @@ -1448,8 +1555,7 @@ def __setstate__(self, state): self.__class__ = OrderedSetPartitions_scomp n = state['_n'] k = state['_k'] - OrderedSetPartitions_scomp.__init__(self, range(state['_n']), (k, n-k)) + OrderedSetPartitions_scomp.__init__(self, range(state['_n']), (k, n - k)) -from sage.misc.persist import register_unpickle_override register_unpickle_override("sage.combinat.split_nk", "SplitNK_nk", SplitNK) From d531fb36cee5ab40447269e0534741ca0b3811cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 18 Oct 2022 11:23:23 +0200 Subject: [PATCH 332/350] fix W2 and W3 in geometry, rings, schemes --- .../hyperplane_arrangement/affine_subspace.py | 2 +- .../hyperplane_arrangement/check_freeness.py | 2 +- .../geometry/hyperplane_arrangement/plot.py | 6 +-- src/sage/geometry/ribbon_graph.py | 44 +++++++++---------- .../triangulation/point_configuration.py | 4 +- src/sage/rings/continued_fraction.py | 2 +- src/sage/rings/function_field/ideal.py | 2 +- src/sage/rings/number_field/number_field.py | 2 +- .../rings/number_field/splitting_field.py | 2 +- src/sage/rings/polynomial/all.py | 2 +- .../polynomial/laurent_polynomial_ideal.py | 16 +++---- src/sage/rings/qqbar.py | 2 +- src/sage/rings/quotient_ring_element.py | 2 +- src/sage/rings/universal_cyclotomic_field.py | 2 +- src/sage/schemes/elliptic_curves/ell_point.py | 2 +- .../hyperelliptic_curves/jacobian_morphism.py | 2 +- .../product_projective/rational_point.py | 4 +- .../riemann_surfaces/riemann_surface.py | 6 +-- 18 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/sage/geometry/hyperplane_arrangement/affine_subspace.py b/src/sage/geometry/hyperplane_arrangement/affine_subspace.py index 83f7463d4b9..7c1065553c4 100644 --- a/src/sage/geometry/hyperplane_arrangement/affine_subspace.py +++ b/src/sage/geometry/hyperplane_arrangement/affine_subspace.py @@ -131,7 +131,7 @@ def __hash__(self): """ # note that the point is not canonically chosen, but the linear part is return hash(self._linear_part) - + def _repr_(self): r""" String representation for an :class:`AffineSubspace`. diff --git a/src/sage/geometry/hyperplane_arrangement/check_freeness.py b/src/sage/geometry/hyperplane_arrangement/check_freeness.py index cbf766c8f7e..30f963612ec 100644 --- a/src/sage/geometry/hyperplane_arrangement/check_freeness.py +++ b/src/sage/geometry/hyperplane_arrangement/check_freeness.py @@ -120,7 +120,7 @@ def next_step(indices, prev, T): ret = next_step(I, Y, U) if ret is not None: return [prev] + ret - return None + return None T = matrix.identity(S, r) for i in indices: diff --git a/src/sage/geometry/hyperplane_arrangement/plot.py b/src/sage/geometry/hyperplane_arrangement/plot.py index bf2455a0ceb..875fa0de46e 100644 --- a/src/sage/geometry/hyperplane_arrangement/plot.py +++ b/src/sage/geometry/hyperplane_arrangement/plot.py @@ -410,7 +410,7 @@ def plot_hyperplane(hyperplane, **kwds): # the extra keywords have now been handled # now create the plot if hyperplane.dimension() == 0: # a point on a line - x, = hyperplane.A() + x, = hyperplane.A() d = hyperplane.b() p = point((d/x,0), size=pt_size, **kwds) if has_hyp_label: @@ -456,7 +456,7 @@ def plot_hyperplane(hyperplane, **kwds): s0, s1 = -3, 3 t0, t1 = -3, 3 p = parametric_plot3d(pnt+s*w[0]+t*w[1], (s,s0,s1), (t,t0,t1), **kwds) - if has_hyp_label: + if has_hyp_label: if has_offset: b0, b1, b2 = label_offset else: @@ -518,7 +518,7 @@ def legend_3d(hyperplane_arrangement, hyperplane_colors, length): for i in range(N): p += line([(0,0),(0,0)], color=hyperplane_colors[i], thickness=8, legend_label=labels[i], axes=False) - p.set_legend_options(title='Hyperplanes', loc='center', labelspacing=0.4, + p.set_legend_options(title='Hyperplanes', loc='center', labelspacing=0.4, fancybox=True, font_size='x-large', ncol=2) p.legend(True) return p diff --git a/src/sage/geometry/ribbon_graph.py b/src/sage/geometry/ribbon_graph.py index 60375b20ce2..d2a8d7de63a 100644 --- a/src/sage/geometry/ribbon_graph.py +++ b/src/sage/geometry/ribbon_graph.py @@ -460,16 +460,16 @@ def contract_edge(self, k): #the following two lines convert the list of tuples to list of lists aux_sigma = [list(x) for x in self._sigma.cycle_tuples(singletons=True)] aux_rho = [list(x) for x in self._rho.cycle_tuples()] - #The following ''if'' rules out the cases when we would be - #contracting a loop (which is not admissible since we would + #The following ''if'' rules out the cases when we would be + #contracting a loop (which is not admissible since we would #lose the topological type of the graph). - if (_find(aux_sigma, aux_rho[k][0])[0] == + if (_find(aux_sigma, aux_rho[k][0])[0] == _find(aux_sigma, aux_rho[k][1])[0]): raise ValueError("the edge is a loop and cannot be contracted") #We store in auxiliary variables the positions of the vertices #that are the ends of the edge to be contracted and we delete #from them the darts corresponding to the edge that is going - #to be contracted. We also delete the contracted edge + #to be contracted. We also delete the contracted edge #from aux_rho pos1 = _find(aux_sigma, aux_rho[k][0]) pos2 = _find(aux_sigma, aux_rho[k][1]) @@ -582,7 +582,7 @@ def extrude_edge(self, vertex, dart1, dart2): for val in val_one: repr_sigma += [[val]] - # We find which is the highest value a dart has, in order to + # We find which is the highest value a dart has, in order to # add new darts that do not conflict with previous ones. k = max(darts_rho) @@ -627,7 +627,7 @@ def genus(self): """ #We now use the same procedure as in _repr_ to get the vertices #of valency 1 and distinguish them from the extra singletons of - #the permutation sigma. + #the permutation sigma. repr_sigma = [list(x) for x in self._sigma.cycle_tuples()] repr_rho = [list(x) for x in self._rho.cycle_tuples()] darts_rho = flatten(repr_rho) @@ -637,10 +637,10 @@ def genus(self): #the total number of vertices of sigma is its number of cycles #of length >1 plus the number of singletons that are actually #vertices of valency 1 - + vertices = len(self._sigma.cycle_tuples()) + len(val_one) edges = len(self._rho.cycle_tuples()) - #formula for the genus using that the thickening is homotopically + #formula for the genus using that the thickening is homotopically #equivalent to the graph g = (-vertices + edges - self.number_boundaries() + 2) // 2 @@ -720,13 +720,13 @@ def boundary(self): bound = [] #since lists of tuples are not modifiable, we change the data to a - #list of lists + #list of lists aux_perm = (self._rho * self._sigma).cycle_tuples(singletons=True) - #the cycles of the permutation rho*sigma are in 1:1 correspondence with + #the cycles of the permutation rho*sigma are in 1:1 correspondence with #the boundary components of the thickening (see function number_boundaries()) #but they are not the labeled boundary components. - #With the next for, we convert the cycles of rho*sigma to actually + #With the next for, we convert the cycles of rho*sigma to actually #the labelling of the edges. Each edge, therefore, should appear twice for i,p in enumerate(aux_perm): @@ -799,16 +799,16 @@ def reduced(self): aux_sigma = [list(x) for x in aux_ribbon._sigma.cycle_tuples(singletons=True)] aux_rho = [list(x) for x in aux_ribbon._rho.cycle_tuples()] for j in range(len(aux_rho)): - if (_find(aux_sigma, aux_rho[j][0])[0] != + if (_find(aux_sigma, aux_rho[j][0])[0] != _find(aux_sigma, aux_rho[j][1])[0]): aux_ribbon = aux_ribbon.contract_edge(j) - aux_rho = [list(x) for + aux_rho = [list(x) for x in aux_ribbon._rho.cycle_tuples()] break #finally we change the data to a list of tuples and return the - #information as a ribbon graph. + #information as a ribbon graph. return aux_ribbon - + #the next function computes a basis of homology, it uses #the previous function. @@ -960,15 +960,15 @@ def homology_basis(self): basis = [[list(x)] for x in self.reduced()._rho.cycle_tuples()] - #Now we define center as the set of edges that were contracted - #in reduced() this set is contractible and can be define as the + #Now we define center as the set of edges that were contracted + #in reduced() this set is contractible and can be define as the #complement of reduced_rho in rho - center = [list(x) for x in self._rho.cycle_tuples() + center = [list(x) for x in self._rho.cycle_tuples() if (x not in self.reduced()._rho.cycle_tuples())] #We define an auxiliary list 'vertices' that will contain the - #vertices (cycles of sigma) corresponding to each half edge. + #vertices (cycles of sigma) corresponding to each half edge. vertices = [] @@ -1013,7 +1013,7 @@ def homology_basis(self): basis[i][j][0], basis[i][j][1] = \ basis[i][j][1], basis[i][j][0] - #the variable basis is a LIST of Lists of lists. Each List + #the variable basis is a LIST of Lists of lists. Each List #corresponds to an element of the basis and each list in a List #is just a 2-tuple which corresponds to an ''ordered'' edge of rho. @@ -1056,7 +1056,7 @@ def normalize(self): darts_rho = flatten(aux_rho) darts_sigma = flatten(aux_sigma) val_one = [x for x in darts_rho if x not in darts_sigma] - + #We add them to aux_sigma for i in range(len(val_one)): aux_sigma += [[val_one[i]]] @@ -1147,7 +1147,7 @@ def make_ribbon(g, r): repr_sigma[1].append(i+(2*g+2)+1) repr_rho += [[i+2,i+(2*g+2)+1]] - #finally we add an edge for each additional boundary component. + #finally we add an edge for each additional boundary component. max_dart = 4*g+2 for j in range(r-1): repr_sigma[0].insert(0, max_dart+2*(j+1)-1) diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 8d05c3bcb19..c244ad2c12e 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -1899,7 +1899,7 @@ def contained_simplex(self, large=True, initial_point=None, point_order=None): # PointConfiguration are actually ignored. if not points: return tuple() - + if initial_point is None: origin = points.pop() else: @@ -2005,7 +2005,7 @@ def facets_of_simplex(simplex): # input verification self._assert_is_affine() - + point_order_is_given = point_order is not None if point_order is None: point_order = list(self.points()) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index f4c10b009ad..a16137ff609 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -1018,7 +1018,7 @@ def __bool__(self): """ return bool(self.quotient(0)) or self.quotient(1) is not Infinity - + def is_zero(self): r""" diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 75e6a826cd2..1ce0b885f56 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -1266,7 +1266,7 @@ def __bool__(self): """ return self._hnf.nrows() != 0 - + def __hash__(self): """ diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index cfb71b38abf..a2f0e3d047c 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -6288,7 +6288,7 @@ def _normalize_prime_list(self, v): v = [] elif not isinstance(v, (list, tuple)): v = [v] - + v = [ZZ(p).abs() for p in v] v = sorted(set(v)) diff --git a/src/sage/rings/number_field/splitting_field.py b/src/sage/rings/number_field/splitting_field.py index 6dc15cc6bc9..d61b9f25226 100644 --- a/src/sage/rings/number_field/splitting_field.py +++ b/src/sage/rings/number_field/splitting_field.py @@ -378,7 +378,7 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No abort_rel_degree = abort_degree//absolute_degree if abort_rel_degree and rel_degree_divisor > abort_rel_degree: raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple) - + # First, factor polynomials in Lred and store the result in L verbose("SplittingData to factor: %s"%[s._repr_tuple() for s in Lred]) t = cputime() diff --git a/src/sage/rings/polynomial/all.py b/src/sage/rings/polynomial/all.py index a05a36ebca1..816db5efe2a 100644 --- a/src/sage/rings/polynomial/all.py +++ b/src/sage/rings/polynomial/all.py @@ -22,7 +22,7 @@ # Quotient of polynomial ring from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement - + # Univariate Polynomial Rings from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.polynomial_ring import polygen, polygens diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 24d8f05546b..f205371d822 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -112,7 +112,7 @@ def set_hint(self, hint): Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y, z over Rational Field """ self._hint = hint - + def hint(self): """ Return the hint of this ideal. @@ -130,7 +130,7 @@ def hint(self): Ideal (0) of Multivariate Polynomial Ring in x, y, z over Rational Field """ return self._hint - + # Comparisons, using the associated polynomial ideal. def _richcmp_(self, right_r, op): r""" @@ -192,9 +192,9 @@ def __contains__(self, f): f = self.ring()(f) g = f.__reduce__()[1][0] return (g in self.polynomial_ideal()) - + # Operations on ideals - + def change_ring(self, R, hint=None): """ Coerce an ideal into a new ring. @@ -313,7 +313,7 @@ def toric_coordinate_change(self, M, forward_hint=True): apply_to_hint = None return self.apply_map(lambda x, M=M: x.toric_coordinate_change(M), apply_to_hint=apply_to_hint) - + def __add__(self, other): """ Return the sum of two ideals in the same ring. @@ -361,7 +361,7 @@ def normalize_gens(self): Ideal (x - 1, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field """ return self.ring().ideal(self.groebner_basis(), hint=self._hint) - + # Structural queries and properties def polynomial_ideal(self, saturate=True): @@ -406,7 +406,7 @@ def polynomial_ideal(self, saturate=True): self._hint = I self._saturated = True return I - + def groebner_basis(self, saturate=True): """ Return the reduced Groebner basis for the specified term order. @@ -456,7 +456,7 @@ def is_binomial(self, groebner_basis=False): else: l = self.gens() return all(not f or f.number_of_terms() == 2 for f in l) - + def associated_primes(self): """ Return associated primes of this ideal. diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 7b7c957fdf4..e0aeed19815 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -4059,7 +4059,7 @@ def __bool__(self): self.exactify() return bool(self) - + def is_square(self): """ diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 69df8d3319e..e2f190a4b1c 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -153,7 +153,7 @@ def __bool__(self): """ return self.__rep not in self.parent().defining_ideal() - + def is_unit(self): """ diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index 2291f0ed393..d238bce3450 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -332,7 +332,7 @@ def __bool__(self): """ return bool(self._obj) - + def __reduce__(self): r""" diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 9c9038e0eb5..98c0dee32c7 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -523,7 +523,7 @@ def __bool__(self): """ return bool(self[2]) - + def has_finite_order(self): """ diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py index 7167fe2208a..5aa76b5c950 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py @@ -658,7 +658,7 @@ def __bool__(self): """ return self.__polys[0] != 1 - + def __neg__(self): r""" diff --git a/src/sage/schemes/product_projective/rational_point.py b/src/sage/schemes/product_projective/rational_point.py index b75ec0cde05..8c737f14e0b 100644 --- a/src/sage/schemes/product_projective/rational_point.py +++ b/src/sage/schemes/product_projective/rational_point.py @@ -134,7 +134,7 @@ def enum_product_projective_rational_field(X, B): m = R.num_components() iters = [ R[i].points_of_bounded_height(bound=B) for i in range(m) ] dim = [R[i].dimension_relative() + 1 for i in range(m)] - + dim_prefix = [0, dim[0]] # prefixes dim list for i in range(1, len(dim)): dim_prefix.append(dim_prefix[i] + dim[i]) @@ -540,5 +540,5 @@ def lift_all_points(): m.append(temp) rat_points = lift_all_points() - + return sorted(rat_points) diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index 87e02bc962b..facd90d0425 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -3082,7 +3082,7 @@ def initialise(z, i): # converge happens silently, thus allowing the user to get *an* # answer out of the integration, but numerical imprecision is to be # expected. As such, we set the maximum number of steps in the sequence - # of DE integrations to be lower in the latter case. + # of DE integrations to be lower in the latter case. if raise_errors: n_steps = self._prec - 1 else: @@ -3240,9 +3240,9 @@ def fv(hj, previous_estimate): Nh *= 2 # Note that throughout this loop there is a return statement, intended # to be activated when the sequence of integral approximations is - # deemed to have converged by the heuristic error. If this has no + # deemed to have converged by the heuristic error. If this has no # happened by the time we have gone through the process n_steps times, - # we have one final error handle. Again, this will throw an error if + # we have one final error handle. Again, this will throw an error if # the raise_errors flag is true, but will just return the answer otherwise. if raise_errors: raise ConvergenceError("Newton iteration fails to converge") From 7efd468620c0f78a195d0a501841915360f0e944 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 18 Oct 2022 18:42:05 +0900 Subject: [PATCH 333/350] Reviewer change by introducing a check argument. --- src/sage/combinat/set_partition_ordered.py | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index de11741b55f..2a75f41ba5f 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -154,7 +154,7 @@ class OrderedSetPartition(ClonableArray, :wikipedia:`Ordered_partition_of_a_set` """ @staticmethod - def __classcall_private__(cls, parts=None, from_word=None): + def __classcall_private__(cls, parts=None, from_word=None, check=True): """ Create a set partition from ``parts`` with the appropriate parent. @@ -189,9 +189,9 @@ def __classcall_private__(cls, parts=None, from_word=None): if parts in W or (parts and (parts[0] in ZZ or isinstance(parts[0], str))): return OrderedSetPartitions().from_finite_word(W(parts)) P = OrderedSetPartitions(set(x for p in parts for x in p)) - return P.element_class(P, parts) + return P.element_class(P, parts, check=check) - def __init__(self, parent, s): + def __init__(self, parent, s, check=True): """ Initialize ``self``. @@ -201,7 +201,7 @@ def __init__(self, parent, s): sage: s = OS([[1, 3], [2, 4]]) sage: TestSuite(s).run() """ - ClonableArray.__init__(self, parent, [Set(part) for part in s]) + ClonableArray.__init__(self, parent, [Set(part) for part in s], check=check) def _repr_(self): """ @@ -1109,7 +1109,7 @@ def __iter__(self): """ for x in Compositions(len(self._set)): for z in OrderedSetPartitions(self._set, x): - yield self.element_class(self, z) + yield self.element_class(self, z, check=False) class OrderedSetPartitions_sn(OrderedSetPartitions): @@ -1187,7 +1187,7 @@ def __iter__(self): """ for x in Compositions(len(self._set), length=self.n): for z in OrderedSetPartitions_scomp(self._set, x): - yield self.element_class(self, z) + yield self.element_class(self, z, check=False) class OrderedSetPartitions_scomp(OrderedSetPartitions): @@ -1304,7 +1304,7 @@ def __iter__(self): part_sizes = self.c N = len(part_sizes) if not N: - yield self.element_class(self, []) + yield self.element_class(self, [], check=False) return l = [] @@ -1314,22 +1314,21 @@ def __iter__(self): pi = multiset_permutation_to_ordered_set_partition(l, N) converted = [frozenset(lset[i] for i in part) for part in pi] - yield self.element_class(self, converted) + yield self.element_class(self, converted, check=False) while multiset_permutation_next_lex(l): pi = multiset_permutation_to_ordered_set_partition(l, N) converted = [frozenset(lset[i] for i in part) for part in pi] - yield self.element_class(self, converted) + yield self.element_class(self, converted, check=False) def multiset_permutation_to_ordered_set_partition(l, m): - """ + r""" Convert a multiset permutation to an ordered set partition. INPUT: - ``l`` -- a multiset permutation - - ``m`` -- number of parts EXAMPLES:: @@ -1432,7 +1431,7 @@ def __iter__(self): n = 0 while True: for X in OrderedSetPartitions(n): - yield self.element_class(self, list(X)) + yield self.element_class(self, list(X), check=False) n += 1 def _element_constructor_(self, s): From 64c3482f88e43dd67d2c43b5eecb26843bc89ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 18 Oct 2022 16:30:57 +0200 Subject: [PATCH 334/350] re-using parent(self) --- src/sage/combinat/set_partition_ordered.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 2a75f41ba5f..6db0bdb1645 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -40,6 +40,7 @@ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.sets.set import Set, Set_generic from sage.structure.list_clone import ClonableArray +from sage.structure.element import parent from sage.structure.parent import Parent from sage.structure.richcmp import richcmp from sage.structure.unique_representation import UniqueRepresentation @@ -229,7 +230,8 @@ def check(self): sage: s = OS([[1, 3], [2, 4]]) sage: s.check() """ - assert self in self.parent(), "%s not in %s" % (self, self.parent()) + par = parent(self) + assert self in par, "%s not in %s" % (self, par) def _hash_(self): """ @@ -267,7 +269,7 @@ def base_set(self): frozenset({'a', 'b', 'c', 'd', 'e'}) """ try: - return self.parent()._set + return parent(self)._set except AttributeError: # in OrderedSetPartitions_all return frozenset(x for part in self for x in part) @@ -286,7 +288,7 @@ def base_set_cardinality(self): sage: OrderedSetPartition([[1,2,3,4]]).base_set_cardinality() 4 """ - return len(self.parent()._set) + return len(parent(self)._set) size = base_set_cardinality @@ -377,7 +379,7 @@ def reversed(self): sage: OrderedSetPartition([]).reversed() [] """ - par = self.parent() + par = parent(self) return par(list(reversed(self))) def complement(self): @@ -415,7 +417,7 @@ def complement(self): m = min(base_set) M = max(base_set) mM = m + M - par = self.parent() + par = parent(self) return par([[mM - i for i in part] for part in self]) def finer(self): @@ -448,7 +450,7 @@ def finer(self): [{4, 9}, {-1}, {2}], [{4, 9}, {-1, 2}]] """ - par = self.parent() + par = parent(self) if not self: return FiniteEnumeratedSet([self]) return FiniteEnumeratedSet([par(sum((list(i) for i in C), [])) @@ -550,7 +552,7 @@ def fatten(self, grouping): for i in range(len(grouping)): result[i] = sum(self[j:j+grouping[i]], Set()) j += grouping[i] - return self.parent()(result) + return parent(self)(result) def fatter(self): """ @@ -666,7 +668,7 @@ def strongly_finer(self): [{4, 9}, {-1}, {2}], [{4, 9}, {-1, 2}]] """ - par = self.parent() + par = parent(self) if not self: return FiniteEnumeratedSet([self]) buo = OrderedSetPartition.bottom_up_osp From e4815355b7eadfd5c7d7697bf08c1749cb4660bc Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 18 Oct 2022 16:50:52 +0100 Subject: [PATCH 335/350] reformat doctest --- src/sage/geometry/triangulation/point_configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 8d05c3bcb19..59d48cf82eb 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -708,7 +708,7 @@ def _TOPCOM_triangulations(self, verbose=True): # points2triangs # [[0,0,1],[0,1,1],[1,0,1],[1,1,1],[-1,-1,1]] #### TOPCOM output #### - # T[0]:=[0->5,3:{{0,1,2},{1,2,3},{0,2,4},{0,1,4}}]; + # T[0] := {{0,1,2},{0,1,4},{0,2,4},{1,2,3}}; (<0,1,2>, <0,1,4>, <0,2,4>, <1,2,3>) """ command = 'points2' From 023f37f0ae06ab31381eb627153e93fcce6662ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 18 Oct 2022 21:23:11 +0200 Subject: [PATCH 336/350] using set and frozenset --- src/sage/combinat/set_partition_ordered.py | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 6db0bdb1645..c7b05ac868e 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -202,7 +202,8 @@ def __init__(self, parent, s, check=True): sage: s = OS([[1, 3], [2, 4]]) sage: TestSuite(s).run() """ - ClonableArray.__init__(self, parent, [Set(part) for part in s], check=check) + ClonableArray.__init__(self, parent, + [frozenset(part) for part in s], check=check) def _repr_(self): """ @@ -340,7 +341,7 @@ def sum(osps): Any iterable can be provided as input:: - sage: Composition.sum([OrderedSetPartition([[2*i,2*i+1]]) for i in [4,1,3]]) + sage: OrderedSetPartition.sum([OrderedSetPartition([[2*i,2*i+1]]) for i in [4,1,3]]) [{8, 9}, {2, 3}, {6, 7}] Empty inputs are handled gracefully:: @@ -494,9 +495,9 @@ def is_finer(self, co2): i1 = 0 for j2 in co2: - sum1 = Set() + sum1 = set() while len(sum1) < len(j2): - sum1 += co1[i1] + sum1 = sum1.union(co1[i1]) i1 += 1 if not sum1.issubset(j2): return False @@ -550,7 +551,7 @@ def fatten(self, grouping): result = [None] * len(grouping) j = 0 for i in range(len(grouping)): - result[i] = sum(self[j:j+grouping[i]], Set()) + result[i] = set().union(*self[j:j+grouping[i]]) j += grouping[i] return parent(self)(result) @@ -638,7 +639,7 @@ def bottom_up_osp(X, comp): result = [None] * len(comp) j = 0 for i in range(len(comp)): - result[i] = Set(xs[j:j+comp[i]]) + result[i] = set(xs[j:j+comp[i]]) j += comp[i] return OrderedSetPartitions(X)(result) @@ -716,12 +717,12 @@ def is_strongly_finer(self, co2): i1 = 0 for j2 in co2: - sum1 = Set() + sum1 = set() while len(sum1) < len(j2): next = co1[i1] if sum1 and max(sum1) >= min(next): return False - sum1 += next + sum1 = sum1.union(next) i1 += 1 if not sum1.issubset(j2): return False @@ -996,9 +997,7 @@ def __contains__(self, x): sage: [Set([1,2]), Set([3,4])] in OS True sage: [set([1,2]), set([3,4])] in OS - Traceback (most recent call last): - ... - TypeError: X (=...1, 2...) must be a Set + True """ # x must be a list if not isinstance(x, (OrderedSetPartition, list, tuple)): @@ -1011,7 +1010,7 @@ def __contains__(self, x): # Check to make sure each element of the list # is a nonempty set - u = Set() + u = set() for s in x: if not s or not isinstance(s, (set, frozenset, Set_generic)): return False From 63ee91ee7314aec60c2d32d7d12a23b8813e7c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 19 Oct 2022 08:37:53 +0200 Subject: [PATCH 337/350] fixing the doctests --- src/sage/combinat/chas/wqsym.py | 14 ++++--- src/sage/combinat/set_partition_ordered.py | 45 +++++++++++----------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/sage/combinat/chas/wqsym.py b/src/sage/combinat/chas/wqsym.py index 238d0281030..945c3727fd3 100644 --- a/src/sage/combinat/chas/wqsym.py +++ b/src/sage/combinat/chas/wqsym.py @@ -574,7 +574,7 @@ class Monomial(WQSymBasis_abstract): sage: M = WQSym.M(); M Word Quasi-symmetric functions over Rational Field in the Monomial basis sage: sorted(M.basis(2)) - [M[{1, 2}], M[{2}, {1}], M[{1}, {2}]] + [M[{1}, {2}], M[{2}, {1}], M[{1, 2}]] """ _prefix = "M" _basis_name = "Monomial" @@ -625,6 +625,7 @@ def product_on_basis(self, x, y): def union(X, Y): return X.union(Y) + return self.sum_of_monomials(ShuffleProduct_overlapping(x, yshift, K, union)) @@ -975,12 +976,15 @@ def _C_to_X(self, P): temp = temp[:j] break + def union(X, Y): + return X.union(Y) + # Perform the quasi-shuffle product cur = {data[0]: 1} for B in data[1:]: ret = {} for A in cur: - for C in ShuffleProduct_overlapping(A, B, element_constructor=OSP): + for C in ShuffleProduct_overlapping(A, B, element_constructor=OSP, add=union): if C in ret: ret[C] += cur[A] else: @@ -2220,7 +2224,7 @@ def algebraic_complement(self): sage: M[[1,4],[2,5],[3,6]].algebraic_complement() M[{3, 6}, {2, 5}, {1, 4}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).algebraic_complement() - -4*M[] + 3*M[{1}] + 5*M[{2}, {1}] + 3*M[{1}] - 4*M[] + 5*M[{2}, {1}] sage: X = WQSym.X() sage: X[[1,3],[2]].algebraic_complement() X[{2}, {1, 3}] @@ -2385,7 +2389,7 @@ def coalgebraic_complement(self): sage: M[[1,4],[2,5],[3,6]].coalgebraic_complement() M[{3, 6}, {2, 5}, {1, 4}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).coalgebraic_complement() - -4*M[] + 3*M[{1}] + 5*M[{2}, {1}] + 3*M[{1}] - 4*M[] + 5*M[{2}, {1}] sage: X = WQSym.X() sage: X[[1,3],[2]].coalgebraic_complement() X[{1, 3}, {2}] @@ -2496,7 +2500,7 @@ def star_involution(self): sage: M[[1,4],[2,5],[3,6]].star_involution() M[{1, 4}, {2, 5}, {3, 6}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).star_involution() - -4*M[] + 3*M[{1}] + 5*M[{1}, {2}] + 3*M[{1}] - 4*M[] + 5*M[{1}, {2}] sage: X = WQSym.X() sage: X[[1,3],[2]].star_involution() X[{2}, {1, 3}] diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index c7b05ac868e..35f7327f84c 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -568,10 +568,10 @@ def fatter(self): sage: C.cardinality() 4 sage: sorted(C) - [[{1, 2, 3, 4, 5}], - [{1, 2, 5}, {3, 4}], + [[{2, 5}, {1}, {3, 4}], [{2, 5}, {1, 3, 4}], - [{2, 5}, {1}, {3, 4}]] + [{1, 2, 5}, {3, 4}], + [{1, 2, 3, 4, 5}]] sage: OrderedSetPartition([[4, 9], [-1, 2]]).fatter().list() [[{4, 9}, {-1, 2}], [{-1, 2, 4, 9}]] @@ -583,14 +583,14 @@ def fatter(self): sage: list(Composition([]).fatter()) [[]] sage: sorted(OrderedSetPartition([[1], [2], [3], [4]]).fatter()) - [[{1, 2, 3, 4}], - [{1, 2, 3}, {4}], - [{1, 2}, {3, 4}], - [{1, 2}, {3}, {4}], - [{1}, {2, 3, 4}], - [{1}, {2, 3}, {4}], + [[{1}, {2}, {3}, {4}], [{1}, {2}, {3, 4}], - [{1}, {2}, {3}, {4}]] + [{1}, {2, 3}, {4}], + [{1}, {2, 3, 4}], + [{1, 2}, {3}, {4}], + [{1, 2}, {3, 4}], + [{1, 2, 3}, {4}], + [{1, 2, 3, 4}]] """ return Compositions(len(self)).map(self.fatten) @@ -742,8 +742,7 @@ def strongly_fatter(self): sage: C.cardinality() 2 sage: sorted(C) - [[{2, 5}, {1, 3, 4}], - [{2, 5}, {1}, {3, 4}]] + [[{2, 5}, {1}, {3, 4}], [{2, 5}, {1, 3, 4}]] sage: OrderedSetPartition([[4, 9], [-1, 2]]).strongly_fatter().list() [[{4, 9}, {-1, 2}]] @@ -755,21 +754,21 @@ def strongly_fatter(self): sage: list(OrderedSetPartition([]).strongly_fatter()) [[]] sage: sorted(OrderedSetPartition([[1], [2], [3], [4]]).strongly_fatter()) - [[{1, 2, 3, 4}], - [{1, 2, 3}, {4}], - [{1, 2}, {3, 4}], - [{1, 2}, {3}, {4}], - [{1}, {2, 3, 4}], - [{1}, {2, 3}, {4}], + [[{1}, {2}, {3}, {4}], [{1}, {2}, {3, 4}], - [{1}, {2}, {3}, {4}]] + [{1}, {2, 3}, {4}], + [{1}, {2, 3, 4}], + [{1, 2}, {3}, {4}], + [{1, 2}, {3, 4}], + [{1, 2, 3}, {4}], + [{1, 2, 3, 4}]] sage: sorted(OrderedSetPartition([[1], [3], [2], [4]]).strongly_fatter()) - [[{1, 3}, {2, 4}], - [{1, 3}, {2}, {4}], + [[{1}, {3}, {2}, {4}], [{1}, {3}, {2, 4}], - [{1}, {3}, {2}, {4}]] + [{1, 3}, {2}, {4}], + [{1, 3}, {2, 4}]] sage: sorted(OrderedSetPartition([[4], [1], [5], [3]]).strongly_fatter()) - [[{4}, {1, 5}, {3}], [{4}, {1}, {5}, {3}]] + [[{4}, {1}, {5}, {3}], [{4}, {1, 5}, {3}]] """ c = [sorted(X) for X in self] l = len(c) - 1 From 64cae731f9ce71c2c945d70263fefe62481329e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 19 Oct 2022 15:39:08 +0200 Subject: [PATCH 338/350] little detail --- src/sage/combinat/set_partition_ordered.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 35f7327f84c..915af345269 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -250,8 +250,9 @@ def _hash_(self): def base_set(self): """ - Return the base set of ``self``, which is the union of all parts - of ``self``. + Return the base set of ``self``. + + This is the union of all parts of ``self``. EXAMPLES:: @@ -276,8 +277,9 @@ def base_set(self): def base_set_cardinality(self): """ - Return the cardinality of the base set of ``self``, which is the sum - of the sizes of the parts of ``self``. + Return the cardinality of the base set of ``self``. + + This is the sum of the sizes of the parts of ``self``. This is also known as the *size* (sometimes the *weight*) of an ordered set partition. @@ -288,8 +290,17 @@ def base_set_cardinality(self): 4 sage: OrderedSetPartition([[1,2,3,4]]).base_set_cardinality() 4 + + TESTS:: + + sage: S = OrderedSetPartitions() + sage: S([[1,4],[3],[2]]).base_set_cardinality() + 4 """ - return len(parent(self)._set) + try: + return len(parent(self)._set) + except AttributeError: # in OrderedSetPartitions_all + return sum(len(part) for part in self) size = base_set_cardinality From 362d8f14e7d214e79ec8d597c71ea2ad79f01a1d Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 20 Oct 2022 08:52:57 +0900 Subject: [PATCH 339/350] Being more careful with the parent in from_finite_word(). --- src/sage/combinat/chas/wqsym.py | 9 ++++++--- src/sage/combinat/set_partition_ordered.py | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/chas/wqsym.py b/src/sage/combinat/chas/wqsym.py index 945c3727fd3..99659ab154a 100644 --- a/src/sage/combinat/chas/wqsym.py +++ b/src/sage/combinat/chas/wqsym.py @@ -69,9 +69,12 @@ def __init__(self, alg, graded=True): sage: M = algebras.WQSym(QQ).M() sage: TestSuite(M).run() # long time """ + def sorting_key(X): + return (sum(map(len, X)), X) CombinatorialFreeModule.__init__(self, alg.base_ring(), OrderedSetPartitions(), category=WQSymBases(alg, graded), + sorting_key=sorting_key, bracket="", prefix=self._prefix) def _repr_term(self, osp): @@ -2224,7 +2227,7 @@ def algebraic_complement(self): sage: M[[1,4],[2,5],[3,6]].algebraic_complement() M[{3, 6}, {2, 5}, {1, 4}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).algebraic_complement() - 3*M[{1}] - 4*M[] + 5*M[{2}, {1}] + -4*M[] + 3*M[{1}] + 5*M[{2}, {1}] sage: X = WQSym.X() sage: X[[1,3],[2]].algebraic_complement() X[{2}, {1, 3}] @@ -2389,7 +2392,7 @@ def coalgebraic_complement(self): sage: M[[1,4],[2,5],[3,6]].coalgebraic_complement() M[{3, 6}, {2, 5}, {1, 4}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).coalgebraic_complement() - 3*M[{1}] - 4*M[] + 5*M[{2}, {1}] + -4*M[] + 3*M[{1}] + 5*M[{2}, {1}] sage: X = WQSym.X() sage: X[[1,3],[2]].coalgebraic_complement() X[{1, 3}, {2}] @@ -2500,7 +2503,7 @@ def star_involution(self): sage: M[[1,4],[2,5],[3,6]].star_involution() M[{1, 4}, {2, 5}, {3, 6}] sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).star_involution() - 3*M[{1}] - 4*M[] + 5*M[{1}, {2}] + -4*M[] + 3*M[{1}] + 5*M[{1}, {2}] sage: X = WQSym.X() sage: X[[1,3],[2]].star_involution() X[{2}, {1, 3}] diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 915af345269..3bb081310ea 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -1030,7 +1030,7 @@ def __contains__(self, x): # sets is the original set return len(u) == len(self._set) - def from_finite_word(self, w): + def from_finite_word(self, w, check=True): r""" Return the unique ordered set partition of `\{1, 2, \ldots, n\}` corresponding to a word `w` of length `n`. @@ -1051,14 +1051,24 @@ def from_finite_word(self, w): sage: A = OrderedSetPartitions().from_finite_word('abcabca') sage: A.parent() + Ordered set partitions + + sage: A = OrderedSetPartitions(7).from_finite_word('abcabca') + sage: A.parent() Ordered set partitions of {1, 2, 3, 4, 5, 6, 7} """ # TODO: fix this if statement. # In fact, what we need is for the underlying alphabet to be sortable. if isinstance(w, (list, tuple, str, FiniteWord_class)): W = Words(infinite=False) - s = frozenset(range(1, len(w) + 1)) - return self.element_class(self.subset(s), W(w).to_ordered_set_partition()) + if check: + try: + X = self._set + if len(X) != len(w) or X != frozenset(range(1, len(w) + 1)): + raise ValueError(f"result not in {self}") + except AttributeError: + pass + return self.element_class(self, W(w).to_ordered_set_partition()) raise TypeError(f"`from_finite_word` expects an object of type list/tuple/str/Word " f"representing a finite word, received {w}") From bd8adbcebd68ad12cbe65248a07c74a4c3574ca7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Sep 2022 08:26:13 -0700 Subject: [PATCH 340/350] build/pkgs/github_cli: New --- build/pkgs/github_cli/SPKG.rst | 19 +++++++++++++++++++ build/pkgs/github_cli/distros/alpine.txt | 1 + build/pkgs/github_cli/distros/arch.txt | 1 + build/pkgs/github_cli/distros/debian.txt | 1 + build/pkgs/github_cli/distros/fedora.txt | 1 + build/pkgs/github_cli/distros/freebsd.txt | 1 + build/pkgs/github_cli/distros/gentoo.txt | 1 + build/pkgs/github_cli/distros/homebrew.txt | 1 + build/pkgs/github_cli/distros/macports.txt | 1 + build/pkgs/github_cli/distros/nix.txt | 1 + build/pkgs/github_cli/distros/opensuse.txt | 1 + build/pkgs/github_cli/distros/void.txt | 1 + build/pkgs/github_cli/type | 1 + 13 files changed, 31 insertions(+) create mode 100644 build/pkgs/github_cli/SPKG.rst create mode 100644 build/pkgs/github_cli/distros/alpine.txt create mode 100644 build/pkgs/github_cli/distros/arch.txt create mode 100644 build/pkgs/github_cli/distros/debian.txt create mode 100644 build/pkgs/github_cli/distros/fedora.txt create mode 100644 build/pkgs/github_cli/distros/freebsd.txt create mode 100644 build/pkgs/github_cli/distros/gentoo.txt create mode 100644 build/pkgs/github_cli/distros/homebrew.txt create mode 100644 build/pkgs/github_cli/distros/macports.txt create mode 100644 build/pkgs/github_cli/distros/nix.txt create mode 100644 build/pkgs/github_cli/distros/opensuse.txt create mode 100644 build/pkgs/github_cli/distros/void.txt create mode 100644 build/pkgs/github_cli/type diff --git a/build/pkgs/github_cli/SPKG.rst b/build/pkgs/github_cli/SPKG.rst new file mode 100644 index 00000000000..5ab5b6bfbdc --- /dev/null +++ b/build/pkgs/github_cli/SPKG.rst @@ -0,0 +1,19 @@ +github_cli: Command-line interface for GitHub +============================================= + +Description +----------- + +``gh`` is GitHub on the command line. It brings pull requests, issues, and +other GitHub concepts to the terminal next to where you are already +working with ``git`` and your code. + +License +------- + +MIT + +Upstream Contact +---------------- + +https://github.com/cli/cli diff --git a/build/pkgs/github_cli/distros/alpine.txt b/build/pkgs/github_cli/distros/alpine.txt new file mode 100644 index 00000000000..5b249a1e859 --- /dev/null +++ b/build/pkgs/github_cli/distros/alpine.txt @@ -0,0 +1 @@ +github-cli diff --git a/build/pkgs/github_cli/distros/arch.txt b/build/pkgs/github_cli/distros/arch.txt new file mode 100644 index 00000000000..5b249a1e859 --- /dev/null +++ b/build/pkgs/github_cli/distros/arch.txt @@ -0,0 +1 @@ +github-cli diff --git a/build/pkgs/github_cli/distros/debian.txt b/build/pkgs/github_cli/distros/debian.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/debian.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/fedora.txt b/build/pkgs/github_cli/distros/fedora.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/fedora.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/freebsd.txt b/build/pkgs/github_cli/distros/freebsd.txt new file mode 100644 index 00000000000..7362ba57a11 --- /dev/null +++ b/build/pkgs/github_cli/distros/freebsd.txt @@ -0,0 +1 @@ +devel/gh diff --git a/build/pkgs/github_cli/distros/gentoo.txt b/build/pkgs/github_cli/distros/gentoo.txt new file mode 100644 index 00000000000..660aea3ced4 --- /dev/null +++ b/build/pkgs/github_cli/distros/gentoo.txt @@ -0,0 +1 @@ +dev-util/github-cli diff --git a/build/pkgs/github_cli/distros/homebrew.txt b/build/pkgs/github_cli/distros/homebrew.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/homebrew.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/macports.txt b/build/pkgs/github_cli/distros/macports.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/macports.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/nix.txt b/build/pkgs/github_cli/distros/nix.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/nix.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/opensuse.txt b/build/pkgs/github_cli/distros/opensuse.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/opensuse.txt @@ -0,0 +1 @@ +gh diff --git a/build/pkgs/github_cli/distros/void.txt b/build/pkgs/github_cli/distros/void.txt new file mode 100644 index 00000000000..5b249a1e859 --- /dev/null +++ b/build/pkgs/github_cli/distros/void.txt @@ -0,0 +1 @@ +github-cli diff --git a/build/pkgs/github_cli/type b/build/pkgs/github_cli/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/github_cli/type @@ -0,0 +1 @@ +optional From c0f7f6bccdc12373f768c3af599ac371972cea04 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Sep 2022 08:26:56 -0700 Subject: [PATCH 341/350] build/pkgs/_develop/dependencies: Add github_cli --- build/pkgs/_develop/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/_develop/dependencies b/build/pkgs/_develop/dependencies index f50a34b8495..f37c427ebcd 100644 --- a/build/pkgs/_develop/dependencies +++ b/build/pkgs/_develop/dependencies @@ -1 +1 @@ -_bootstrap git pytest pytest_xdist +_bootstrap git pytest pytest_xdist github_cli From dbc3b4eee61da009eff2f8a53e9a75d290b39975 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Sep 2022 09:10:36 -0700 Subject: [PATCH 342/350] build/pkgs/github_cli/distros/conda.txt: New --- build/pkgs/github_cli/distros/conda.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/github_cli/distros/conda.txt diff --git a/build/pkgs/github_cli/distros/conda.txt b/build/pkgs/github_cli/distros/conda.txt new file mode 100644 index 00000000000..7f8d49f4704 --- /dev/null +++ b/build/pkgs/github_cli/distros/conda.txt @@ -0,0 +1 @@ +gh From abb0f5f8bea4fb43a658b488cf426cd3bdb249aa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 23 Sep 2022 13:46:43 -0700 Subject: [PATCH 343/350] build/pkgs/github_cli/distros/repology.txt: New --- build/pkgs/github_cli/distros/repology.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/github_cli/distros/repology.txt diff --git a/build/pkgs/github_cli/distros/repology.txt b/build/pkgs/github_cli/distros/repology.txt new file mode 100644 index 00000000000..5b249a1e859 --- /dev/null +++ b/build/pkgs/github_cli/distros/repology.txt @@ -0,0 +1 @@ +github-cli From 5526199750a1320b5d10f14a82bd4f75a1139148 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 20 Oct 2022 09:53:21 -0700 Subject: [PATCH 344/350] build/pkgs/python_igraph: Update to 0.10.2 --- build/pkgs/python_igraph/checksums.ini | 6 +++--- build/pkgs/python_igraph/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/python_igraph/checksums.ini b/build/pkgs/python_igraph/checksums.ini index 9ddab211f0d..5f8bc59a4de 100644 --- a/build/pkgs/python_igraph/checksums.ini +++ b/build/pkgs/python_igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=python-igraph-VERSION.tar.gz -sha1=75eae8ca6de2daa8c5ca43f99487cf20b5cdf432 -md5=18a54cd2fe507f5602e6c10584f665ee -cksum=594785782 +sha1=6a6bca77737ff501e97f808aa18a9045e86b3e3e +md5=6951cc2e803118b74209ae21d54de38a +cksum=650236223 upstream_url=https://pypi.io/packages/source/i/igraph/igraph-VERSION.tar.gz diff --git a/build/pkgs/python_igraph/package-version.txt b/build/pkgs/python_igraph/package-version.txt index 571215736a6..5eef0f10e8c 100644 --- a/build/pkgs/python_igraph/package-version.txt +++ b/build/pkgs/python_igraph/package-version.txt @@ -1 +1 @@ -0.10.1 +0.10.2 From dd328e8d3b6f0707acf805bf37f2cf14c2875ef5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 20 Oct 2022 09:53:45 -0700 Subject: [PATCH 345/350] build/pkgs/igraph: Update to 0.10.2 --- build/pkgs/igraph/checksums.ini | 6 +++--- build/pkgs/igraph/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/igraph/checksums.ini b/build/pkgs/igraph/checksums.ini index 9da572238e5..f7d3336bda8 100644 --- a/build/pkgs/igraph/checksums.ini +++ b/build/pkgs/igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=igraph-VERSION.tar.gz -sha1=74abe82bdebdefc295a4f04b54170880dcb265e8 -md5=4e61e5e86ebe4fe478df415b7407e87e -cksum=2574937983 +sha1=20587332f0f36d6d7eb3cca248e2dab76e1e58ad +md5=af41eb9c614946c4a92a51834e9cab4a +cksum=4011381306 upstream_url=https://github.com/igraph/igraph/releases/download/VERSION/igraph-VERSION.tar.gz diff --git a/build/pkgs/igraph/package-version.txt b/build/pkgs/igraph/package-version.txt index 571215736a6..5eef0f10e8c 100644 --- a/build/pkgs/igraph/package-version.txt +++ b/build/pkgs/igraph/package-version.txt @@ -1 +1 @@ -0.10.1 +0.10.2 From 0c9d28aed04495569ff6761937f5c6bec226ad08 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 21 Oct 2022 09:30:49 +0100 Subject: [PATCH 346/350] Revert "build/pkgs/primesieve: Add patch to support ubuntu-trusty, linuxmint-17" This reverts commit b9b4eaf334c6dd5261ccd229ca825b01b600e6a6. --- build/pkgs/primesieve/patches/107.patch | 54 ------------------------- 1 file changed, 54 deletions(-) delete mode 100644 build/pkgs/primesieve/patches/107.patch diff --git a/build/pkgs/primesieve/patches/107.patch b/build/pkgs/primesieve/patches/107.patch deleted file mode 100644 index d8986d29337..00000000000 --- a/build/pkgs/primesieve/patches/107.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 1f8d0470b4e9d50393032b86d21a7a2fcc512355 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Sat, 27 Nov 2021 10:50:09 -0800 -Subject: [PATCH] src/MemoryPool.cpp: Work around missing std::align on GCC 4.x - ---- - src/MemoryPool.cpp | 27 ++++++++++++++++++++++++++- - 1 file changed, 26 insertions(+), 1 deletion(-) - -diff --git a/src/MemoryPool.cpp b/src/MemoryPool.cpp -index 7a4a4006..60f62101 100644 ---- a/src/MemoryPool.cpp -+++ b/src/MemoryPool.cpp -@@ -26,6 +26,31 @@ - - using std::size_t; - -+#if defined(__GNUC__) && __GNUC__ == 4 -+ -+// gcc 4.9 does not implement std::align. -+// Use the implementation from -+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350#c11 -+ -+using std::uintptr_t; -+ -+static inline void *align(size_t alignment, size_t size, -+ void *&ptr, size_t &space) -+{ -+ uintptr_t pn = reinterpret_cast(ptr); -+ uintptr_t aligned = (pn + alignment - 1) & -alignment; -+ size_t padding = aligned - pn; -+ if (space < size + padding) return nullptr; -+ space -= padding; -+ return ptr = reinterpret_cast(aligned); -+} -+ -+#else -+ -+using std::align; -+ -+#endif -+ - namespace primesieve { - - void MemoryPool::addBucket(SievingPrime*& sievingPrime) -@@ -70,7 +95,7 @@ void MemoryPool::allocateBuckets() - void* ptr = memory; - - // Align pointer address to sizeof(Bucket) -- if (!std::align(sizeof(Bucket), sizeof(Bucket), ptr, bytes)) -+ if (!align(sizeof(Bucket), sizeof(Bucket), ptr, bytes)) - throw primesieve_error("MemoryPool: failed to align memory!"); - - initBuckets(ptr, bytes); From fb783e02453ab76b41128bfd43787cca8d857003 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 21 Oct 2022 09:33:19 +0100 Subject: [PATCH 347/350] Revert "build/pkgs/flint/: Add patch for threads with GCC < 4.9" This reverts commit 8c6c9498e236cbc6a15b3ad80830db3e5adb55de. --- ...-On-GCC-4.9-do-not-use-_Thread_local.patch | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 build/pkgs/flint/patches/0001-flint.h-On-GCC-4.9-do-not-use-_Thread_local.patch diff --git a/build/pkgs/flint/patches/0001-flint.h-On-GCC-4.9-do-not-use-_Thread_local.patch b/build/pkgs/flint/patches/0001-flint.h-On-GCC-4.9-do-not-use-_Thread_local.patch deleted file mode 100644 index f37e9c73476..00000000000 --- a/build/pkgs/flint/patches/0001-flint.h-On-GCC-4.9-do-not-use-_Thread_local.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 54e5a36901bcbe5dedadcf3fc670eb00a7ab9193 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Sun, 21 Nov 2021 11:33:59 -0800 -Subject: [PATCH] flint.h: On GCC < 4.9, do not use _Thread_local - ---- - flint.h | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/flint.h b/flint.h -index 2cd15fb29..9d082f7f0 100644 ---- a/flint.h -+++ b/flint.h -@@ -157,7 +157,10 @@ FLINT_DLL void flint_set_abort(FLINT_NORETURN void (*func)(void)); - #define flint_bitcnt_t ulong - - #if FLINT_USES_TLS --#if __STDC_VERSION__ >= 201112L -+#if defined(__GNUC__) && __STDC_VERSION__ >= 201112L && __GNUC__ == 4 && __GNUC_MINOR__ < 9 -+/* GCC 4.7, 4.8 with -std=gnu11 purport to support C11 via __STDC_VERSION__ but lack _Thread_local */ -+#define FLINT_TLS_PREFIX __thread -+#elif __STDC_VERSION__ >= 201112L - #define FLINT_TLS_PREFIX _Thread_local - #elif defined(_MSC_VER) - #define FLINT_TLS_PREFIX __declspec(thread) --- -2.33.0 - From dd87547019684e21c1e23a640870231557aa5093 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 21 Oct 2022 22:49:45 +0100 Subject: [PATCH 348/350] update link to Fukuda's Polyhedral comp. FAQ --- src/sage/geometry/polyhedron/constructor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index eac816facb3..7f11ac13593 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -269,7 +269,7 @@ REFERENCES: Komei Fukuda's `FAQ in Polyhedral Computation - `_ + `_ AUTHORS: From 2d793075a03cd2808610e50afe784210674e5651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 23 Oct 2022 10:50:53 +0200 Subject: [PATCH 349/350] fix some details in graphs (found by lgtm) --- src/sage/graphs/graph_input.py | 4 ++-- src/sage/graphs/partial_cube.py | 7 +++---- src/sage/graphs/schnyder.py | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 34df7dd3c76..fe1de72dcc5 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -371,6 +371,8 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted - ``loops``, ``multiedges``, ``weighted`` -- booleans (default: ``False``); whether to consider the graph as having loops, multiple edges, or weights + .. NOTE:: ``weighted`` is currently ignored. + EXAMPLES:: sage: from sage.graphs.graph_input import from_oriented_incidence_matrix @@ -426,8 +428,6 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted positions.append(tuple(NZ)) else: positions.append((NZ[1], NZ[0])) - if weighted is None: - weighted = False if multiedges is None: total = len(positions) multiedges = len(set(positions)) < total diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index 0831df402e2..bce06dee677 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -166,7 +166,6 @@ def depth_first_traversal(G, start): sage: t = list(sage.graphs.partial_cube.depth_first_traversal(H, '00')) sage: len(t) 16 - """ neighbors = G.neighbor_out_iterator seen = set() @@ -286,7 +285,7 @@ def is_partial_cube(G, certificate=False): # Initial sanity check: are there few enough edges? # Needed so that we don't try to use union-find on a dense # graph and incur superquadratic runtimes. - if 1 << (2*G.size()//n) > n: + if 1 << (2 * G.size() // n) > n: return fail # Check for bipartiteness. @@ -399,13 +398,13 @@ def is_partial_cube(G, certificate=False): # Rest of data structure: point from states to list and list to states state_to_active_token = {v: -1 for v in g} - token_to_states = [[] for i in activeTokens] # (i.e. vertices on which each token acts) + token_to_states = [[] for _ in activeTokens] # (i.e. vertices on which each token acts) def scan(v): """ Find the next token that is effective for v. """ - a = next(i for i in range(state_to_active_token[v]+1, len(activeTokens)) + a = next(i for i in range(state_to_active_token[v] + 1, len(activeTokens)) if activeTokens[i] is not None and activeTokens[i] in action[v]) state_to_active_token[v] = a token_to_states[a].append(v) diff --git a/src/sage/graphs/schnyder.py b/src/sage/graphs/schnyder.py index 5816d1c7952..8a33cc8c70e 100644 --- a/src/sage/graphs/schnyder.py +++ b/src/sage/graphs/schnyder.py @@ -213,7 +213,6 @@ def _normal_label(g, comb_emb, external_face): except Exception: raise RuntimeError('Contractible list is empty but graph still has %d vertices. (Expected 3.)' % g.order()) - break # going to contract v v_neighbors = Set(g.neighbors(v)) contracted.append((v, v_neighbors, From c3028e74d80d7f8473b3e421ba6d54ab95f288f9 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 30 Oct 2022 11:43:30 +0100 Subject: [PATCH 350/350] Updated SageMath version to 9.8.beta3 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 25 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index bfc70cb35aa..81ea9dde6d0 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.8.beta2", - "version": "9.8.beta2", + "title": "sagemath/sage: 9.8.beta3", + "version": "9.8.beta3", "upload_type": "software", - "publication_date": "2022-10-16", + "publication_date": "2022-10-30", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.8.beta2", + "identifier": "https://github.com/sagemath/sage/tree/9.8.beta3", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index a62ad931e8c..ff069aea672 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.8.beta2, Release Date: 2022-10-16 +SageMath version 9.8.beta3, Release Date: 2022-10-30 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 7825699ede6..c69394ff5dc 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=56310dade6a501cd54dad562318f512784b46e20 -md5=7b9541629741c9b2ea6bae4eaf34bcc0 -cksum=1005659704 +sha1=103db8ec9f403e7d8c2a36fe7a9d03f8ace86667 +md5=67c1a87314dd1cd7eb9c426105f01c81 +cksum=878105096 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 9ddcd042195..d00f65abb0a 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -a0ccde283b91541cd304cbf5bdc23d53c52f5008 +412cc5c0045f1ae9f8f6d98d75754d5d443d58fd diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 1a0b2bc1457..e1ce4a85f34 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 9.8b2 +sage-conf ~= 9.8b3 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 93266bbb15b..3db13eeb1f7 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 9.8b2 +sage-docbuild ~= 9.8b3 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 2c6b94be041..d8a7c30eba0 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 9.8b2 +sage-setup ~= 9.8b3 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index fdcef24cdd4..95d6d392aa5 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 9.8b2 +sage-sws2rst ~= 9.8b3 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 7ecd279caab..3016d9eebcc 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 9.8b2 +sagelib ~= 9.8b3 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index cb1cb7106c8..d1bce6cf96e 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 9.8b2 +sagemath-categories ~= 9.8b3 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 8138a64abd8..99458e3a96c 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 9.8b2 +sagemath-environment ~= 9.8b3 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index ee5931a4236..e0b880eaac0 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 9.8b2 +sagemath-objects ~= 9.8b3 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 4445ac6e934..3cd52abc7d6 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 9.8b2 +sagemath-repl ~= 9.8b3 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/src/VERSION.txt b/src/VERSION.txt index 0d493e35378..b0789c4fde8 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.8.beta2 +9.8.beta3 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 7942e09574b..b4ab677a7f3 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.8.beta2' -SAGE_RELEASE_DATE='2022-10-16' -SAGE_VERSION_BANNER='SageMath version 9.8.beta2, Release Date: 2022-10-16' +SAGE_VERSION='9.8.beta3' +SAGE_RELEASE_DATE='2022-10-30' +SAGE_VERSION_BANNER='SageMath version 9.8.beta3, Release Date: 2022-10-30' diff --git a/src/sage/version.py b/src/sage/version.py index 7961b87efa6..a82d4578e10 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.8.beta2' -date = '2022-10-16' -banner = 'SageMath version 9.8.beta2, Release Date: 2022-10-16' +version = '9.8.beta3' +date = '2022-10-30' +banner = 'SageMath version 9.8.beta3, Release Date: 2022-10-30'