From 20d30f1936ab36297469fcf3e5dfc35a06d42600 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 4 May 2023 17:03:51 +0100 Subject: [PATCH 01/32] accounted for moved MatrixGroupElement_gap class --- .../groups/matrix_gps/group_element_gap.pyx | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index 7aba88e9b88..031791f6c34 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -116,6 +116,33 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): '[1 1]\n[0 1]' """ return str(self.matrix()) + + def __call__(self, other): + r""" + + EXAMPLES:: + + sage: G=groups.matrix.Sp(4,GF(2)) + sage: R.=GF(2)[] + sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 + sage: g=G.1 + sage: g + [0 0 1 0] + [1 0 0 0] + [0 0 0 1] + [0 1 0 0] + sage: g(p) + w*x*z*y + w*x^2 + + """ + if type(other)==MPolynomial_libsingular: + assert self.base_ring()==other.base_ring() + mRingPoly=other + polynomial_vars=mRingPoly.variables() + varsToSubstituteModuleContext=self*MatrixConstructor(polynomial_vars).transpose() + varsToSubstituteRingContext=map(PolynomialRing(self.base_ring(), other.variables()), varsToSubstituteModuleContext) + substitutionDict={v:s for v,s in zip(polynomial_vars, varsToSubstituteRingContext)} + return mRingPoly.subs(substitutionDict) def _latex_(self): r""" From 3f5603096d2d06cadbb5bd2aaa08f2437ac2a104 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 4 May 2023 17:28:17 +0100 Subject: [PATCH 02/32] changed explicit type matching to isInstance --- src/sage/groups/matrix_gps/group_element_gap.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index 031791f6c34..e287b59894a 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -23,6 +23,9 @@ from sage.misc.cachefunc import cached_method from sage.structure.element import is_Matrix from sage.structure.factorization import Factorization from sage.structure.richcmp cimport richcmp +from sage.rings.polynomial.multi_polynomial import MPolynomial +from sage.matrix.constructor import matrix as MatrixConstructor +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing cdef class MatrixGroupElement_gap(ElementLibGAP): @@ -135,7 +138,7 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): w*x*z*y + w*x^2 """ - if type(other)==MPolynomial_libsingular: + if isinstance(other, MPolynomial): assert self.base_ring()==other.base_ring() mRingPoly=other polynomial_vars=mRingPoly.variables() From 61c0aa94940434083ae61cae041fca040360421d Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 4 May 2023 17:53:53 +0100 Subject: [PATCH 03/32] improved testing + correct polynomial var access --- .../groups/matrix_gps/group_element_gap.pyx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index e287b59894a..4de23c84ee9 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -126,7 +126,7 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): EXAMPLES:: sage: G=groups.matrix.Sp(4,GF(2)) - sage: R.=GF(2)[] + sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 sage: g @@ -135,15 +135,25 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): [0 0 0 1] [0 1 0 0] sage: g(p) - w*x*z*y + w*x^2 + w*x*y*z + w*z^2 + sage: p2=x+y^2 + sage: g2=G.0 + sage: g2 + [1 0 1 1] + [1 0 0 1] + [0 1 0 1] + [1 1 1 1] + sage: g2(p2) + x^2 + z^2 + w + z + """ if isinstance(other, MPolynomial): assert self.base_ring()==other.base_ring() mRingPoly=other - polynomial_vars=mRingPoly.variables() + polynomial_vars=mRingPoly.parent().gens() varsToSubstituteModuleContext=self*MatrixConstructor(polynomial_vars).transpose() - varsToSubstituteRingContext=map(PolynomialRing(self.base_ring(), other.variables()), varsToSubstituteModuleContext) + varsToSubstituteRingContext=map(PolynomialRing(self.base_ring(), polynomial_vars), varsToSubstituteModuleContext) substitutionDict={v:s for v,s in zip(polynomial_vars, varsToSubstituteRingContext)} return mRingPoly.subs(substitutionDict) From bfd6f4a6a603db15a7da32eec4ed3979aaf56832 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 4 May 2023 17:56:41 +0100 Subject: [PATCH 04/32] variable naming conventions --- src/sage/groups/matrix_gps/group_element_gap.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index 4de23c84ee9..b80e8618b13 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -150,12 +150,12 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): """ if isinstance(other, MPolynomial): assert self.base_ring()==other.base_ring() - mRingPoly=other - polynomial_vars=mRingPoly.parent().gens() - varsToSubstituteModuleContext=self*MatrixConstructor(polynomial_vars).transpose() - varsToSubstituteRingContext=map(PolynomialRing(self.base_ring(), polynomial_vars), varsToSubstituteModuleContext) - substitutionDict={v:s for v,s in zip(polynomial_vars, varsToSubstituteRingContext)} - return mRingPoly.subs(substitutionDict) + polynomial=other + polynomial_vars=polynomial.parent().gens() + vars_to_sub_module_context=self*MatrixConstructor(polynomial_vars).transpose() + vars_to_sub_ring_context=map(PolynomialRing(self.base_ring(), polynomial_vars), vars_to_sub_module_context) + substitution_dict={v:s for v,s in zip(polynomial_vars, vars_to_sub_ring_context)} + return polynomial.subs(substitution_dict) def _latex_(self): r""" From 0e210d845a496e4f1be37f72c8580dda03be295f Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Sat, 6 May 2023 17:14:41 +0100 Subject: [PATCH 05/32] pycodestyle fix --- src/sage/groups/matrix_gps/group_element_gap.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index b80e8618b13..2a7c0d5611d 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -119,10 +119,10 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): '[1 1]\n[0 1]' """ return str(self.matrix()) - + def __call__(self, other): - r""" - + r""" + EXAMPLES:: sage: G=groups.matrix.Sp(4,GF(2)) From bd83e578f9daf8eb05b2a2a026288d2eca480d03 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Fri, 30 Jun 2023 17:51:44 +0100 Subject: [PATCH 06/32] start of @ coersion implementation --- .../multi_polynomial_libsingular.pyx | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 64f01724081..e1612abd903 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -234,6 +234,14 @@ from sage.rings.number_field.number_field_base cimport NumberField from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields +from sage.categories.action import Action +from sage.matrix.matrix_space import MatrixSpace +from sage.groups.matrix_gps.finitely_generated import MatrixGroup +from sage.rings.polynomial.multi_polynomial import MPolynomial +from sage.matrix.constructor import matrix as MatrixConstructor +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from _operator import matmul + from sage.structure.element import coerce_binop from sage.structure.parent cimport Parent @@ -2110,6 +2118,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if sage_res._parent is not res_parent: sage_res = res_parent(sage_res) return sage_res + + def _get_action_(self, G): + if isinstance(G, (MatrixSpace, MatrixGroup)) and self.base_ring().has_coerce_map_from(G.base_ring()): + return MatrixPolynomialAction(G, self) + return super() def __hash__(self): """ @@ -5833,3 +5846,14 @@ cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, p cdef poly *MPolynomial_libsingular_get_element(object self): return (self)._poly + +class MatrixPolynomialAction(Action): + def __init__(self, MS, PR): + self._poly_vars = PR.gens() + self._vars_vector = MatrixConstructor(self._poly_vars).transpose() + super().__init__(MS, PR, op=matmul) + + def _act_(self, mat, poly): + vars_to_sub = MatrixConstructor(poly.base_ring(), mat) * self._vars_vector + substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub)} + return poly.subs(substitution_dict) \ No newline at end of file From 96b84461e3a7d218e5361fbf02bbc07ecd4376e9 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Tue, 4 Jul 2023 18:02:34 +0100 Subject: [PATCH 07/32] adjusted _get_action_ signature --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index e1612abd903..4973d8d0df7 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -240,7 +240,8 @@ from sage.groups.matrix_gps.finitely_generated import MatrixGroup from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.matrix.constructor import matrix as MatrixConstructor from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from _operator import matmul +from operator import matmul +from sage.groups.matrix_gps.group_element_gap import MatrixGroupElement_gap from sage.structure.element import coerce_binop @@ -2118,9 +2119,10 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if sage_res._parent is not res_parent: sage_res = res_parent(sage_res) return sage_res - - def _get_action_(self, G): - if isinstance(G, (MatrixSpace, MatrixGroup)) and self.base_ring().has_coerce_map_from(G.base_ring()): + + cpdef _get_action_(self, G, op, bint self_on_left): + print("_get_action_ called!") + if isinstance(G, (MatrixSpace, MatrixGroupElement_gap)) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul: return MatrixPolynomialAction(G, self) return super() From e88c35fbcd0d801db5bcac1500744962cd0fd626 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Tue, 4 Jul 2023 18:05:51 +0100 Subject: [PATCH 08/32] pxd changes --- src/sage/rings/polynomial/multi_polynomial_libsingular.pxd | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd index c9cec10e2bc..d7e740a1881 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd @@ -15,6 +15,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cpdef is_constant(self) cpdef _homogenize(self, int var) cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P) + cpdef _get_action_(self, G, op, bint self_on_left) cpdef long number_of_terms(self) cdef class MPolynomialRing_libsingular(MPolynomialRing_base): From 7d0a2401b9f30c065e874b128e13afa202ccc8ee Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 6 Jul 2023 18:06:18 +0100 Subject: [PATCH 09/32] got coersion working --- .../groups/matrix_gps/group_element_gap.pyx | 40 --------------- .../multi_polynomial_libsingular.pxd | 1 - .../multi_polynomial_libsingular.pyx | 23 ++++----- .../polynomial/multi_polynomial_ring_base.pxd | 1 + .../polynomial/multi_polynomial_ring_base.pyx | 49 +++++++++++++++++++ 5 files changed, 59 insertions(+), 55 deletions(-) diff --git a/src/sage/groups/matrix_gps/group_element_gap.pyx b/src/sage/groups/matrix_gps/group_element_gap.pyx index 2a7c0d5611d..7aba88e9b88 100644 --- a/src/sage/groups/matrix_gps/group_element_gap.pyx +++ b/src/sage/groups/matrix_gps/group_element_gap.pyx @@ -23,9 +23,6 @@ from sage.misc.cachefunc import cached_method from sage.structure.element import is_Matrix from sage.structure.factorization import Factorization from sage.structure.richcmp cimport richcmp -from sage.rings.polynomial.multi_polynomial import MPolynomial -from sage.matrix.constructor import matrix as MatrixConstructor -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing cdef class MatrixGroupElement_gap(ElementLibGAP): @@ -120,43 +117,6 @@ cdef class MatrixGroupElement_gap(ElementLibGAP): """ return str(self.matrix()) - def __call__(self, other): - r""" - - EXAMPLES:: - - sage: G=groups.matrix.Sp(4,GF(2)) - sage: R.=GF(2)[] - sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 - sage: g=G.1 - sage: g - [0 0 1 0] - [1 0 0 0] - [0 0 0 1] - [0 1 0 0] - sage: g(p) - w*x*y*z + w*z^2 - sage: p2=x+y^2 - sage: g2=G.0 - sage: g2 - [1 0 1 1] - [1 0 0 1] - [0 1 0 1] - [1 1 1 1] - sage: g2(p2) - x^2 + z^2 + w + z - - - """ - if isinstance(other, MPolynomial): - assert self.base_ring()==other.base_ring() - polynomial=other - polynomial_vars=polynomial.parent().gens() - vars_to_sub_module_context=self*MatrixConstructor(polynomial_vars).transpose() - vars_to_sub_ring_context=map(PolynomialRing(self.base_ring(), polynomial_vars), vars_to_sub_module_context) - substitution_dict={v:s for v,s in zip(polynomial_vars, vars_to_sub_ring_context)} - return polynomial.subs(substitution_dict) - def _latex_(self): r""" EXAMPLES:: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd index d7e740a1881..c9cec10e2bc 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd @@ -15,7 +15,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cpdef is_constant(self) cpdef _homogenize(self, int var) cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P) - cpdef _get_action_(self, G, op, bint self_on_left) cpdef long number_of_terms(self) cdef class MPolynomialRing_libsingular(MPolynomialRing_base): diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 4973d8d0df7..939a3082a51 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2120,11 +2120,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage_res = res_parent(sage_res) return sage_res - cpdef _get_action_(self, G, op, bint self_on_left): - print("_get_action_ called!") - if isinstance(G, (MatrixSpace, MatrixGroupElement_gap)) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul: - return MatrixPolynomialAction(G, self) - return super() def __hash__(self): """ @@ -5849,13 +5844,13 @@ cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, p cdef poly *MPolynomial_libsingular_get_element(object self): return (self)._poly -class MatrixPolynomialAction(Action): - def __init__(self, MS, PR): - self._poly_vars = PR.gens() - self._vars_vector = MatrixConstructor(self._poly_vars).transpose() - super().__init__(MS, PR, op=matmul) +# class MatrixPolynomialAction(Action): +# def __init__(self, MS, PR): +# self._poly_vars = PR.gens() +# self._vars_vector = MatrixConstructor(self._poly_vars).transpose() +# super().__init__(MS, PR, op=matmul) - def _act_(self, mat, poly): - vars_to_sub = MatrixConstructor(poly.base_ring(), mat) * self._vars_vector - substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub)} - return poly.subs(substitution_dict) \ No newline at end of file +# def _act_(self, mat, poly): +# vars_to_sub = MatrixConstructor(poly.base_ring(), mat) * self._vars_vector +# substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub)} +# return poly.subs(substitution_dict) \ No newline at end of file diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd index fc81cf6d298..b361273c568 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd @@ -7,6 +7,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): cdef public object _has_singular cdef public object _magma_gens cdef public dict _magma_cache + cpdef _get_action_(self, G, op, bint self_on_left) cdef _coerce_c_impl(self, x) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 70e1e7c861b..96b6336e3dc 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -27,6 +27,11 @@ from sage.combinat.integer_vector import IntegerVectors from sage.rings.integer_ring import ZZ +from sage.categories.action import Action +from sage.matrix.matrix_space import MatrixSpace +from sage.matrix.constructor import matrix as MatrixConstructor +from operator import matmul + from .polydict import PolyDict from . import (multi_polynomial_ideal, polynomial_ring, @@ -112,6 +117,36 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): False """ return self.base_ring().is_integral_domain(proof) + + cpdef _get_action_(self, G, op, bint self_on_left): + """ + EXAMPLES:: + sage: G=groups.matrix.Sp(4,GF(2)) + sage: R.=GF(2)[] + sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 + sage: g=G.1 + sage: g + [0 0 1 0] + [1 0 0 0] + [0 0 0 1] + [0 1 0 0] + sage: g@p + w*x*y*z + w*z^2 + sage: p2=x+y^2 + sage: g2=G.0 + sage: g2 + [1 0 1 1] + [1 0 0 1] + [0 1 0 1] + [1 1 1 1] + sage: g2@p2 + x^2 + z^2 + w + z + """ + + from sage.groups.matrix_gps.matrix_group import MatrixGroup_generic + if isinstance(G, MatrixGroup_generic) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul and not self_on_left: + return MatrixPolynomialAction(G, self) + return super(MPolynomialRing_base, self)._get_action_(G, op, self_on_left) def is_noetherian(self): """ @@ -1797,3 +1832,17 @@ def unpickle_MPolynomialRing_generic(base_ring, n, names, order): from .polynomial_ring_constructor import PolynomialRing return PolynomialRing(base_ring, n, names=names, order=order) + +class MatrixPolynomialAction(Action): + def __init__(self, MS, PR): + self._poly_vars = PR.gens() + self._vars_vector = MatrixConstructor(self._poly_vars).transpose() + super().__init__(MS, PR, op=matmul) + + def _act_(self, mat, polynomial): + assert mat.base_ring()==polynomial.base_ring() + polynomial_vars=polynomial.parent().gens() + vars_to_sub_module_context=mat*MatrixConstructor(polynomial_vars).transpose() + vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), polynomial_vars), vars_to_sub_module_context) + substitution_dict={v:s for v,s in zip(polynomial_vars, vars_to_sub_ring_context)} + return polynomial.subs(substitution_dict) \ No newline at end of file From 65ba9fd2f411fd598a4cd5108215b4f9d316c197 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Sat, 8 Jul 2023 18:33:05 +0100 Subject: [PATCH 10/32] linter fixes --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 11 ----------- .../rings/polynomial/multi_polynomial_ring_base.pyx | 10 +++++----- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index abf238d7dc6..16a052e3ee1 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -5845,14 +5845,3 @@ cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, p cdef poly *MPolynomial_libsingular_get_element(object self): return (self)._poly - -# class MatrixPolynomialAction(Action): -# def __init__(self, MS, PR): -# self._poly_vars = PR.gens() -# self._vars_vector = MatrixConstructor(self._poly_vars).transpose() -# super().__init__(MS, PR, op=matmul) - -# def _act_(self, mat, poly): -# vars_to_sub = MatrixConstructor(poly.base_ring(), mat) * self._vars_vector -# substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub)} -# return poly.subs(substitution_dict) \ No newline at end of file diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 3dfe9963007..c17152e9db8 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -114,7 +114,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): False """ return self.base_ring().is_integral_domain(proof) - + cpdef _get_action_(self, G, op, bint self_on_left): """ EXAMPLES:: @@ -141,7 +141,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): """ from sage.groups.matrix_gps.matrix_group import MatrixGroup_generic - if isinstance(G, MatrixGroup_generic) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul and not self_on_left: + if isinstance(G, MatrixGroup_generic) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul and not self_on_left: return MatrixPolynomialAction(G, self) return super(MPolynomialRing_base, self)._get_action_(G, op, self_on_left) @@ -1828,11 +1828,11 @@ class MatrixPolynomialAction(Action): self._poly_vars = PR.gens() self._vars_vector = MatrixConstructor(self._poly_vars).transpose() super().__init__(MS, PR, op=matmul) - + def _act_(self, mat, polynomial): assert mat.base_ring()==polynomial.base_ring() polynomial_vars=polynomial.parent().gens() vars_to_sub_module_context=mat*MatrixConstructor(polynomial_vars).transpose() - vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), polynomial_vars), vars_to_sub_module_context) + vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), polynomial_vars), vars_to_sub_module_context) substitution_dict={v:s for v,s in zip(polynomial_vars, vars_to_sub_ring_context)} - return polynomial.subs(substitution_dict) \ No newline at end of file + return polynomial.subs(substitution_dict) From aa0d722226275e283f68c17d9bbec75672384e6b Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 24 Aug 2023 16:59:35 +0100 Subject: [PATCH 11/32] remove space --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 5d91b9620e5..7c18cbb1606 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2122,7 +2122,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage_res = res_parent(sage_res) return sage_res - def __hash__(self): """ This hash incorporates the variable name in an effort to From c746e0e6187185ffb51982a6e16b8fd72dca162e Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 24 Aug 2023 17:00:55 +0100 Subject: [PATCH 12/32] remove inherited pxd declaration --- src/sage/rings/polynomial/multi_polynomial_ring_base.pxd | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd index b361273c568..fc81cf6d298 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd @@ -7,7 +7,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): cdef public object _has_singular cdef public object _magma_gens cdef public dict _magma_cache - cpdef _get_action_(self, G, op, bint self_on_left) cdef _coerce_c_impl(self, x) From cc2fea58513a35f34eccb0bdd09b5d47cb8ef159 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Thu, 24 Aug 2023 17:08:49 +0100 Subject: [PATCH 13/32] remove unneeded imports --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 7c18cbb1606..4392ae438be 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -230,15 +230,6 @@ from sage.rings.number_field.number_field_base cimport NumberField from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields -from sage.categories.action import Action -from sage.matrix.matrix_space import MatrixSpace -from sage.groups.matrix_gps.finitely_generated import MatrixGroup -from sage.rings.polynomial.multi_polynomial import MPolynomial -from sage.matrix.constructor import matrix as MatrixConstructor -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from operator import matmul -from sage.groups.matrix_gps.group_element_gap import MatrixGroupElement_gap - from sage.structure.element import coerce_binop from sage.structure.parent cimport Parent From 9d301307c6cd9a440edf9e3c8a368522590b06e4 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Fri, 25 Aug 2023 19:01:56 +0100 Subject: [PATCH 14/32] avoid recomputing values --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 2eae4b28385..4ac56a44d3b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1839,8 +1839,7 @@ class MatrixPolynomialAction(Action): def _act_(self, mat, polynomial): assert mat.base_ring()==polynomial.base_ring() - polynomial_vars=polynomial.parent().gens() - vars_to_sub_module_context=mat*MatrixConstructor(polynomial_vars).transpose() - vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), polynomial_vars), vars_to_sub_module_context) - substitution_dict={v:s for v,s in zip(polynomial_vars, vars_to_sub_ring_context)} + vars_to_sub_module_context=mat*self._vars_vector + vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), self._poly_vars), vars_to_sub_module_context) + substitution_dict={v:s for v,s in zip(self._poly_vars, vars_to_sub_ring_context)} return polynomial.subs(substitution_dict) From 162e2484272a943794fdf2f0195ef1224b4bfa50 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:56:06 +0100 Subject: [PATCH 15/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 4ac56a44d3b..cee43e2c6c0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -135,9 +135,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: g2@p2 x^2 + z^2 + w + z """ - from sage.groups.matrix_gps.matrix_group import MatrixGroup_generic - if isinstance(G, MatrixGroup_generic) and self.base_ring().has_coerce_map_from(G.base_ring()) and op==matmul and not self_on_left: + if isinstance(G, MatrixGroup_generic) and self.base_ring().has_coerce_map_from(G.base_ring()) and op == matmul and not self_on_left: return MatrixPolynomialAction(G, self) return super(MPolynomialRing_base, self)._get_action_(G, op, self_on_left) From bc91221e7b0d82283e7a9d5eadecb8467c4ac73d Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:56:37 +0100 Subject: [PATCH 16/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index cee43e2c6c0..003e5a389ac 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -112,9 +112,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): return self.base_ring().is_integral_domain(proof) cpdef _get_action_(self, G, op, bint self_on_left): - """ + r""" + Return the action of ``G`` by ``op`` on ``self``. + EXAMPLES:: - sage: G=groups.matrix.Sp(4,GF(2)) + + sage: G = groups.matrix.Sp(4,GF(2)) sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 From 01e9de32076f1b4e57f3223389f70164d805011e Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:56:55 +0100 Subject: [PATCH 17/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 003e5a389ac..a4400e593b0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -27,8 +27,7 @@ from sage.matrix.matrix_space import MatrixSpace from sage.matrix.constructor import matrix as MatrixConstructor from operator import matmul -from . import (multi_polynomial_ideal, - polynomial_ring) +from . import multi_polynomial_ideal, polynomial_ring from .term_order import TermOrder from .polynomial_ring_constructor import (PolynomialRing, polynomial_default_category) From 1ca6a20db2184294069ca00ac474cb4c2dc816ec Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:00:52 +0100 Subject: [PATCH 18/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index a4400e593b0..e7ef3986b91 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1839,8 +1839,8 @@ class MatrixPolynomialAction(Action): super().__init__(MS, PR, op=matmul) def _act_(self, mat, polynomial): - assert mat.base_ring()==polynomial.base_ring() - vars_to_sub_module_context=mat*self._vars_vector - vars_to_sub_ring_context=map(PolynomialRing(mat.base_ring(), self._poly_vars), vars_to_sub_module_context) - substitution_dict={v:s for v,s in zip(self._poly_vars, vars_to_sub_ring_context)} + assert mat.base_ring() == polynomial.base_ring() + vars_to_sub_module_context = mat * self._vars_vector + vars_to_sub_ring_context = map(PolynomialRing(mat.base_ring(), self._poly_vars), vars_to_sub_module_context) + substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub_ring_context)} return polynomial.subs(substitution_dict) From e3d1801f8331cab8962dd749779a7c84c0abdf81 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Sat, 2 Sep 2023 19:36:40 +0100 Subject: [PATCH 19/32] action object TestSuite implementation start --- .../rings/polynomial/multi_polynomial_ring_base.pyx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index e7ef3986b91..bc77316b93b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1834,6 +1834,16 @@ def unpickle_MPolynomialRing_generic(base_ring, n, names, order): class MatrixPolynomialAction(Action): def __init__(self, MS, PR): + """ + EXAMPLES :: + sage: G = groups.matrix.Sp(4,GF(2)) + sage: R.=GF(2)[] + sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 + sage: g=G.1 + sage: from operator import matmul + sage: A = p.parent()._get_action_(g.parent(), matmul, False) + sage: TestSuite(A).run() + """ self._poly_vars = PR.gens() self._vars_vector = MatrixConstructor(self._poly_vars).transpose() super().__init__(MS, PR, op=matmul) From 8e858c5ef5f23619604dc0267fdb522009fb1cdd Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:50:50 +0100 Subject: [PATCH 20/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index bc77316b93b..e0edf4ef120 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1835,8 +1835,11 @@ def unpickle_MPolynomialRing_generic(base_ring, n, names, order): class MatrixPolynomialAction(Action): def __init__(self, MS, PR): """ + Initialize ``self``. + EXAMPLES :: - sage: G = groups.matrix.Sp(4,GF(2)) + + sage: G = groups.matrix.Sp(4,GF(2)) sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 From a2c1a8ae9dbe6e3e40c642fb7880a5a6d0668398 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Wed, 25 Oct 2023 18:39:30 +0100 Subject: [PATCH 21/32] (broken) matpolyaction reduce method --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index e0edf4ef120..d3456df3f0c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1849,6 +1849,8 @@ class MatrixPolynomialAction(Action): """ self._poly_vars = PR.gens() self._vars_vector = MatrixConstructor(self._poly_vars).transpose() + self.MS=MS + self.PR=PR super().__init__(MS, PR, op=matmul) def _act_(self, mat, polynomial): @@ -1857,3 +1859,6 @@ class MatrixPolynomialAction(Action): vars_to_sub_ring_context = map(PolynomialRing(mat.base_ring(), self._poly_vars), vars_to_sub_module_context) substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub_ring_context)} return polynomial.subs(substitution_dict) + + def __reduce__(self): + return (type(self), (self.MS, self.PR)) From 7892e726494b35e239fad6644de03a7e056021ec Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Sun, 12 Nov 2023 20:10:22 +0000 Subject: [PATCH 22/32] test suite fixes (equality and hashing) --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 3691274289a..c41e5d938bb 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1860,5 +1860,13 @@ class MatrixPolynomialAction(Action): substitution_dict = {v: s for v, s in zip(self._poly_vars, vars_to_sub_ring_context)} return polynomial.subs(substitution_dict) + def __eq__(self, other): + if isinstance(other, MatrixPolynomialAction): + return self.MS == other.MS and self.PR == other.PR + return False + + def __hash__(self): + return hash((self.MS, self.PR)) + def __reduce__(self): return (type(self), (self.MS, self.PR)) From 6a5779f0fac53b178c9d84f2d3f03128ab58fbaf Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Sun, 12 Nov 2023 21:32:21 +0000 Subject: [PATCH 23/32] doctest indentation fix --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index c41e5d938bb..991b401828f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1838,8 +1838,7 @@ class MatrixPolynomialAction(Action): Initialize ``self``. EXAMPLES :: - - sage: G = groups.matrix.Sp(4,GF(2)) + sage: G = groups.matrix.Sp(4,GF(2)) sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 From 59401d7148bdb5a0a2c535fc24bc476c4736226b Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:34:43 +0000 Subject: [PATCH 24/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 991b401828f..183be05f8ec 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1838,8 +1838,9 @@ class MatrixPolynomialAction(Action): Initialize ``self``. EXAMPLES :: - sage: G = groups.matrix.Sp(4,GF(2)) - sage: R.=GF(2)[] + + sage: G = groups.matrix.Sp(4,GF(2)) + sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 sage: from operator import matmul From a30b0bc2093c1ca7ae5199bf82be204d2b9110dc Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:35:40 +0000 Subject: [PATCH 25/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 183be05f8ec..64632da2175 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1849,8 +1849,8 @@ class MatrixPolynomialAction(Action): """ self._poly_vars = PR.gens() self._vars_vector = MatrixConstructor(self._poly_vars).transpose() - self.MS=MS - self.PR=PR + self.MS = MS + self.PR = PR super().__init__(MS, PR, op=matmul) def _act_(self, mat, polynomial): From 864ede7c9fac59ff908b204a178cb398171112d5 Mon Sep 17 00:00:00 2001 From: Bruno Edwards Date: Mon, 13 Nov 2023 13:26:53 +0000 Subject: [PATCH 26/32] improve docstrings and doctests --- .../polynomial/multi_polynomial_ring_base.pyx | 79 ++++++++++++++++++- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 64632da2175..d94310fce70 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1835,12 +1835,15 @@ def unpickle_MPolynomialRing_generic(base_ring, n, names, order): class MatrixPolynomialAction(Action): def __init__(self, MS, PR): """ - Initialize ``self``. + Initialize a MatrixPolynomialAction object. - EXAMPLES :: + Parameters: + MS: The matrix space for the action. + PR: The polynomial ring where the action takes place. - sage: G = groups.matrix.Sp(4,GF(2)) - sage: R.=GF(2)[] + Examples: + sage: G = groups.matrix.Sp(4,GF(2)) + sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 sage: from operator import matmul @@ -1854,6 +1857,25 @@ class MatrixPolynomialAction(Action): super().__init__(MS, PR, op=matmul) def _act_(self, mat, polynomial): + """ + Perform the action of a matrix on a polynomial. + + Parameters: + mat: The matrix to act on the polynomial. + polynomial: The polynomial to be acted upon. + + Returns: + Polynomial: The result of the action. + + Examples: + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: R. = PolynomialRing(GF(2), 3) + sage: M = Matrix(GF(2), [[1, 1, 0], [0, 1, 1], [1, 0, 1]]) + sage: p = x*y + y*z + z^2 + sage: A = MatrixPolynomialAction(M.parent(), R) # using M.parent() to get the matrix space + sage: A._act_(M, p) + x^2 + y^2 + """ assert mat.base_ring() == polynomial.base_ring() vars_to_sub_module_context = mat * self._vars_vector vars_to_sub_ring_context = map(PolynomialRing(mat.base_ring(), self._poly_vars), vars_to_sub_module_context) @@ -1861,12 +1883,61 @@ class MatrixPolynomialAction(Action): return polynomial.subs(substitution_dict) def __eq__(self, other): + """ + Check if another object is equal to this MatrixPolynomialAction. + + Parameters: + other: The object to compare with. + + Returns: + bool: True if equal, False otherwise. + + Examples: + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: M = MatrixSpace(GF(2), 2) + sage: R = PolynomialRing(GF(2), 2, 'x') + sage: A1 = MatrixPolynomialAction(M, R) + sage: A2 = MatrixPolynomialAction(M, R) + sage: A1 == A2 + True + """ if isinstance(other, MatrixPolynomialAction): return self.MS == other.MS and self.PR == other.PR return False def __hash__(self): + """ + Generate a hash for the MatrixPolynomialAction. + + Returns: + int: The hash value. + + Examples: + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: M = MatrixSpace(GF(2), 2) + sage: R = PolynomialRing(GF(2), 2, 'x') + sage: A1 = MatrixPolynomialAction(M, R) + sage: A2 = MatrixPolynomialAction(M, R) + sage: hash(A1)==hash(A2) + True + """ return hash((self.MS, self.PR)) def __reduce__(self): + """ + Reduce the object for serialization. + + Returns: + tuple: The callable and its arguments to recreate the object. + + Examples: + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: M = MatrixSpace(GF(2), 2) + sage: R = PolynomialRing(GF(2), 2, 'x') + sage: A = MatrixPolynomialAction(M, R) + sage: A.__reduce__() + (, + (Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2, + Multivariate Polynomial Ring in x0, x1 over Finite Field of size 2)) + """ return (type(self), (self.MS, self.PR)) From 5e88a54a02f8dc4c33b88a1744e1aeafa4c66016 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:07:54 +0000 Subject: [PATCH 27/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- .../polynomial/multi_polynomial_ring_base.pyx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index d94310fce70..49fd6fa1954 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1835,14 +1835,16 @@ def unpickle_MPolynomialRing_generic(base_ring, n, names, order): class MatrixPolynomialAction(Action): def __init__(self, MS, PR): """ - Initialize a MatrixPolynomialAction object. + Initialize ``self``. - Parameters: - MS: The matrix space for the action. - PR: The polynomial ring where the action takes place. + INPUT: - Examples: - sage: G = groups.matrix.Sp(4,GF(2)) + - ``MS`` -- the matrix space for the action + - ``PR`` -- the polynomial ring where the action takes place + + EXAMPLES:: + + sage: G = groups.matrix.Sp(4,GF(2)) sage: R.=GF(2)[] sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 sage: g=G.1 From b1ccf18a95ce8ed4f1fbb6b1db962a68adcd86b1 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:08:04 +0000 Subject: [PATCH 28/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- .../rings/polynomial/multi_polynomial_ring_base.pyx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 49fd6fa1954..b696c63ff94 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1886,16 +1886,11 @@ class MatrixPolynomialAction(Action): def __eq__(self, other): """ - Check if another object is equal to this MatrixPolynomialAction. + Check if ``self`` equals ``other``. - Parameters: - other: The object to compare with. - - Returns: - bool: True if equal, False otherwise. + EXAMPLES:: - Examples: - sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction sage: M = MatrixSpace(GF(2), 2) sage: R = PolynomialRing(GF(2), 2, 'x') sage: A1 = MatrixPolynomialAction(M, R) From 95cfadc6cea842e703c248aee795feb2e8a95a82 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:08:18 +0000 Subject: [PATCH 29/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index b696c63ff94..8b10ff39aba 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1904,13 +1904,11 @@ class MatrixPolynomialAction(Action): def __hash__(self): """ - Generate a hash for the MatrixPolynomialAction. + Return the hash of ``self``. - Returns: - int: The hash value. + EXAMPLES:: - Examples: - sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction sage: M = MatrixSpace(GF(2), 2) sage: R = PolynomialRing(GF(2), 2, 'x') sage: A1 = MatrixPolynomialAction(M, R) From 4ea353359d99c5dfd5fe5d572629e269ac39ae96 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:08:32 +0000 Subject: [PATCH 30/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 8b10ff39aba..b8d336a6e29 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1920,13 +1920,11 @@ class MatrixPolynomialAction(Action): def __reduce__(self): """ - Reduce the object for serialization. + Return data for creating a pickle of ``self``. - Returns: - tuple: The callable and its arguments to recreate the object. + EXAMPLES:: - Examples: - sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction sage: M = MatrixSpace(GF(2), 2) sage: R = PolynomialRing(GF(2), 2, 'x') sage: A = MatrixPolynomialAction(M, R) From cfd7b2024165734594fa2a2febbb73a859dae478 Mon Sep 17 00:00:00 2001 From: Bruno-TT <33663538+Bruno-TT@users.noreply.github.com> Date: Sun, 19 Nov 2023 14:08:46 +0000 Subject: [PATCH 31/32] Update src/sage/rings/polynomial/multi_polynomial_ring_base.pyx Co-authored-by: Travis Scrimshaw --- .../rings/polynomial/multi_polynomial_ring_base.pyx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index b8d336a6e29..461823b7eef 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1860,17 +1860,11 @@ class MatrixPolynomialAction(Action): def _act_(self, mat, polynomial): """ - Perform the action of a matrix on a polynomial. + Return the action of the matrix ``mat`` on ``polynomial``. - Parameters: - mat: The matrix to act on the polynomial. - polynomial: The polynomial to be acted upon. - - Returns: - Polynomial: The result of the action. + EXAMPLES:: - Examples: - sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction + sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction sage: R. = PolynomialRing(GF(2), 3) sage: M = Matrix(GF(2), [[1, 1, 0], [0, 1, 1], [1, 0, 1]]) sage: p = x*y + y*z + z^2 From 468bb600658801b7b564d40829792e081273cc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 18 Jan 2024 16:40:12 +0100 Subject: [PATCH 32/32] align the doc correctly --- .../polynomial/multi_polynomial_ring_base.pyx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index c84163210cb..e1740393410 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1843,12 +1843,12 @@ class MatrixPolynomialAction(Action): EXAMPLES:: sage: G = groups.matrix.Sp(4,GF(2)) - sage: R.=GF(2)[] - sage: p=x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 - sage: g=G.1 - sage: from operator import matmul - sage: A = p.parent()._get_action_(g.parent(), matmul, False) - sage: TestSuite(A).run() + sage: R.=GF(2)[] + sage: p = x*y^2 + w*x*y*z + 4*w^2*z+2*y*w^2 + sage: g = G.1 + sage: from operator import matmul + sage: A = p.parent()._get_action_(g.parent(), matmul, False) + sage: TestSuite(A).run() """ self._poly_vars = PR.gens() self._vars_vector = MatrixConstructor(self._poly_vars).transpose() @@ -1863,12 +1863,12 @@ class MatrixPolynomialAction(Action): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction - sage: R. = PolynomialRing(GF(2), 3) - sage: M = Matrix(GF(2), [[1, 1, 0], [0, 1, 1], [1, 0, 1]]) - sage: p = x*y + y*z + z^2 - sage: A = MatrixPolynomialAction(M.parent(), R) # using M.parent() to get the matrix space - sage: A._act_(M, p) - x^2 + y^2 + sage: R. = PolynomialRing(GF(2), 3) + sage: M = Matrix(GF(2), [[1, 1, 0], [0, 1, 1], [1, 0, 1]]) + sage: p = x*y + y*z + z^2 + sage: A = MatrixPolynomialAction(M.parent(), R) # using M.parent() to get the matrix space + sage: A._act_(M, p) + x^2 + y^2 """ assert mat.base_ring() == polynomial.base_ring() vars_to_sub_module_context = mat * self._vars_vector @@ -1883,12 +1883,12 @@ class MatrixPolynomialAction(Action): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction - sage: M = MatrixSpace(GF(2), 2) - sage: R = PolynomialRing(GF(2), 2, 'x') - sage: A1 = MatrixPolynomialAction(M, R) - sage: A2 = MatrixPolynomialAction(M, R) - sage: A1 == A2 - True + sage: M = MatrixSpace(GF(2), 2) + sage: R = PolynomialRing(GF(2), 2, 'x') + sage: A1 = MatrixPolynomialAction(M, R) + sage: A2 = MatrixPolynomialAction(M, R) + sage: A1 == A2 + True """ if isinstance(other, MatrixPolynomialAction): return self.MS == other.MS and self.PR == other.PR @@ -1901,12 +1901,12 @@ class MatrixPolynomialAction(Action): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring_base import MatrixPolynomialAction - sage: M = MatrixSpace(GF(2), 2) - sage: R = PolynomialRing(GF(2), 2, 'x') - sage: A1 = MatrixPolynomialAction(M, R) - sage: A2 = MatrixPolynomialAction(M, R) - sage: hash(A1)==hash(A2) - True + sage: M = MatrixSpace(GF(2), 2) + sage: R = PolynomialRing(GF(2), 2, 'x') + sage: A1 = MatrixPolynomialAction(M, R) + sage: A2 = MatrixPolynomialAction(M, R) + sage: hash(A1)==hash(A2) + True """ return hash((self.MS, self.PR))