Skip to content

Commit c43cd23

Browse files
author
Release Manager
committed
gh-38650: Add support for pseudomorphisms This PR implements pseudomorphisms. Let $M, M'$ be modules over a ring $R$, $\theta: R \to R$ be a ring homomorphism, and $\delta: R \to R$ be a $\theta$-derivation, which is a map such that $\delta(xy) = \theta(x)\delta(y) + \delta(x)y$. A *pseudomorphism* $f : M \to M$ is an additive map such that $f(\lambda x) = \theta(\lambda)f(x) + \delta(\lambda) x$ for all $\lambda$ and $x$. This PR is based on a former PR by @ymusleh (that I could not find, I don't know why). ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies URL: #38650 Reported by: Xavier Caruso Reviewer(s): Antoine Leudière, Kwankyu Lee, Xavier Caruso
2 parents 6e82ee5 + 76b71cf commit c43cd23

File tree

6 files changed

+1027
-10
lines changed

6 files changed

+1027
-10
lines changed

src/doc/en/reference/modules/index.rst

+9
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ Morphisms
9292

9393
sage/modules/matrix_morphism
9494

95+
Pseudomorphisms
96+
---------------
97+
98+
.. toctree::
99+
:maxdepth: 1
100+
101+
sage/modules/free_module_pseudohomspace
102+
sage/modules/free_module_pseudomorphism
103+
95104
Vectors
96105
-------
97106

src/sage/modules/free_module.py

+125
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,131 @@ def hom(self, im_gens, codomain=None, **kwds):
31133113
codomain = R**n
31143114
return super().hom(im_gens, codomain, **kwds)
31153115

3116+
def pseudoHom(self, twist, codomain=None):
3117+
r"""
3118+
Return the pseudo-Hom space corresponding to given data.
3119+
3120+
INPUT:
3121+
3122+
- ``twist`` -- the twisting morphism or the twisting derivation
3123+
3124+
- ``codomain`` -- (default: ``None``) the codomain of the pseudo
3125+
morphisms; if ``None``, the codomain is the same as the domain
3126+
3127+
EXAMPLES::
3128+
3129+
sage: F = GF(25)
3130+
sage: Frob = F.frobenius_endomorphism()
3131+
sage: M = F^2
3132+
sage: M.pseudoHom(Frob)
3133+
Set of Pseudoendomorphisms (twisted by z2 |--> z2^5) of Vector space of dimension 2 over Finite Field in z2 of size 5^2
3134+
3135+
.. SEEALSO::
3136+
3137+
:meth:`pseudohom`
3138+
"""
3139+
from sage.modules.free_module_pseudohomspace import FreeModulePseudoHomspace
3140+
if codomain is None:
3141+
codomain = self
3142+
return FreeModulePseudoHomspace(self, codomain, twist)
3143+
3144+
def pseudohom(self, f, twist, codomain=None, side="left"):
3145+
r"""
3146+
Return the pseudohomomorphism corresponding to the given data.
3147+
3148+
We recall that, given two `R`-modules `M` and `M'` together with
3149+
a ring homomorphism `\theta: R \to R` and a `\theta`-derivation,
3150+
`\delta: R \to R` (that is, a map such that
3151+
`\delta(xy) = \theta(x)\delta(y) + \delta(x)y`), a
3152+
pseudomorphism `f : M \to M'` is an additive map such that
3153+
3154+
.. MATH::
3155+
3156+
f(\lambda x) = \theta(\lambda) f(x) + \delta(\lambda) x
3157+
3158+
When `\delta` is nonzero, this requires that `M` coerces into `M'`.
3159+
3160+
.. NOTE::
3161+
3162+
Internally, pseudomorphisms are represented by matrices with
3163+
coefficient in the base ring `R`. See class
3164+
:class:`sage.modules.free_module_pseudomorphism.FreeModulePseudoMorphism`
3165+
for details.
3166+
3167+
INPUT:
3168+
3169+
- ``f`` -- a matrix (or any other data) defining the
3170+
pseudomorphism
3171+
3172+
- ``twist`` -- the twisting morphism or the twisting derivation
3173+
(if a derivation is given, the corresponding morphism `\theta`
3174+
is automatically infered;
3175+
see also :class:`sage.rings.polynomial.ore_polynomial_ring.OrePolynomialRing`)
3176+
3177+
- ``codomain`` -- (default: ``None``) the codomain of the pseudo
3178+
morphisms; if ``None``, the codomain is the same than the domain
3179+
3180+
- ``side`` -- (default: ``left``) side of the vectors acted on by
3181+
the matrix
3182+
3183+
EXAMPLES::
3184+
3185+
sage: K.<z> = GF(5^5)
3186+
sage: Frob = K.frobenius_endomorphism()
3187+
sage: V = K^2; W = K^3
3188+
sage: f = V.pseudohom([[1, z, z^2], [1, z^2, z^4]], Frob, codomain=W)
3189+
sage: f
3190+
Free module pseudomorphism (twisted by z |--> z^5) defined by the matrix
3191+
[ 1 z z^2]
3192+
[ 1 z^2 z^4]
3193+
Domain: Vector space of dimension 2 over Finite Field in z of size 5^5
3194+
Codomain: Vector space of dimension 3 over Finite Field in z of size 5^5
3195+
3196+
We check that `f` is indeed semi-linear::
3197+
3198+
sage: v = V([z+1, z+2])
3199+
sage: f(z*v)
3200+
(2*z^2 + z + 4, z^4 + 2*z^3 + 3*z^2 + z, 4*z^4 + 2*z^2 + 3*z + 2)
3201+
sage: z^5 * f(v)
3202+
(2*z^2 + z + 4, z^4 + 2*z^3 + 3*z^2 + z, 4*z^4 + 2*z^2 + 3*z + 2)
3203+
3204+
An example with a derivation::
3205+
3206+
sage: R.<t> = ZZ[]
3207+
sage: d = R.derivation()
3208+
sage: M = R^2
3209+
sage: Nabla = M.pseudohom([[1, t], [t^2, t^3]], d, side='right')
3210+
sage: Nabla
3211+
Free module pseudomorphism (twisted by d/dt) defined as left-multiplication by the matrix
3212+
[ 1 t]
3213+
[t^2 t^3]
3214+
Domain: Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in t over Integer Ring
3215+
Codomain: Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in t over Integer Ring
3216+
3217+
sage: v = M([1,1])
3218+
sage: Nabla(v)
3219+
(t + 1, t^3 + t^2)
3220+
sage: Nabla(t*v)
3221+
(t^2 + t + 1, t^4 + t^3 + 1)
3222+
sage: Nabla(t*v) == t * Nabla(v) + v
3223+
True
3224+
3225+
If the twisting derivation is not zero, the domain must
3226+
coerce into the codomain::
3227+
3228+
sage: N = R^3
3229+
sage: M.pseudohom([[1, t, t^2], [1, t^2, t^4]], d, codomain=N)
3230+
Traceback (most recent call last):
3231+
...
3232+
ValueError: the domain does not coerce into the codomain
3233+
3234+
.. SEEALSO::
3235+
3236+
:meth:`pseudoHom`
3237+
"""
3238+
H = self.pseudoHom(twist, codomain)
3239+
return H(f, side)
3240+
31163241
def inner_product_matrix(self):
31173242
"""
31183243
Return the default identity inner product matrix associated to this

0 commit comments

Comments
 (0)