Derivations¶
Let A be a ring and B be an bimodule over A. A derivation d:A→B is an additive map that satisfies the Leibniz rule
If B is an algebra over A and if we are given in addition a ring homomorphism θ:A→B, a twisted derivation with respect to θ (or a θ-derivation) is an additive map d:A→B such that
When θ is the morphism defining the structure of A-algebra on B, a θ-derivation is nothing but a derivation. In general, if ι:A→B denotes the defining morphism above, one easily checks that θ−ι is a θ-derivation.
This file provides support for derivations and twisted derivations over commutative rings with values in algebras (i.e. we require that B is a commutative A-algebra). In this case, the set of derivations (resp. θ-derivations) is a module over B.
Given a ring A, the module of derivations over A can be created as follows:
sage: A.<x,y,z> = QQ[]
sage: M = A.derivation_module()
sage: M
Module of derivations over Multivariate Polynomial Ring in x, y, z over Rational Field
The method gens()
returns the generators of this module:
sage: A.<x,y,z> = QQ[]
sage: M = A.derivation_module()
sage: M.gens()
(d/dx, d/dy, d/dz)
We can combine them in order to create all derivations:
sage: d = 2*M.gen(0) + z*M.gen(1) + (x^2 + y^2)*M.gen(2)
sage: d
2*d/dx + z*d/dy + (x^2 + y^2)*d/dz
and now play with them:
sage: d(x + y + z)
x^2 + y^2 + z + 2
sage: P = A.random_element()
sage: Q = A.random_element()
sage: d(P*Q) == P*d(Q) + d(P)*Q
True
Alternatively we can use the method
derivation()
of the ring A to create derivations:
sage: Dx = A.derivation(x); Dx
d/dx
sage: Dy = A.derivation(y); Dy
d/dy
sage: Dz = A.derivation(z); Dz
d/dz
sage: A.derivation([2, z, x^2+y^2])
2*d/dx + z*d/dy + (x^2 + y^2)*d/dz
Sage knows moreover that M is a Lie algebra:
sage: M.category()
Join of Category of lie algebras with basis over Rational Field
and Category of modules with basis over Multivariate Polynomial Ring in x, y, z over Rational Field
Computations of Lie brackets are implemented as well:
sage: Dx.bracket(Dy)
0
sage: d.bracket(Dx)
-2*x*d/dz
At the creation of a module of derivations, a codomain can be specified:
sage: B = A.fraction_field()
sage: A.derivation_module(B)
Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field
to Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field
Alternatively, one can specify a morphism f with domain A. In this case, the codomain of the derivations is the codomain of f but the latter is viewed as an algebra over A through the homomorphism f. This construction is useful, for example, if we want to work with derivations on A at a certain point, e.g. (0,1,2). Indeed, in order to achieve this, we first define the evaluation map at this point:
sage: ev = A.hom([QQ(0), QQ(1), QQ(2)])
sage: ev
Ring morphism:
From: Multivariate Polynomial Ring in x, y, z over Rational Field
To: Rational Field
Defn: x |--> 0
y |--> 1
z |--> 2
Now we use this ring homomorphism to define a structure of A-algebra on Q and then build the following module of derivations:
sage: M = A.derivation_module(ev)
sage: M
Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Rational Field
sage: M.gens()
(d/dx, d/dy, d/dz)
Elements in M then acts as derivations at (0,1,2):
sage: Dx = M.gen(0)
sage: Dy = M.gen(1)
sage: Dz = M.gen(2)
sage: f = x^2 + y^2 + z^2
sage: Dx(f) # = 2*x evaluated at (0,1,2)
0
sage: Dy(f) # = 2*y evaluated at (0,1,2)
2
sage: Dz(f) # = 2*z evaluated at (0,1,2)
4
Twisted derivations are handled similarly:
sage: theta = B.hom([B(y),B(z),B(x)])
sage: theta
Ring endomorphism of Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field
Defn: x |--> y
y |--> z
z |--> x
sage: M = B.derivation_module(twist=theta)
sage: M
Module of twisted derivations over Fraction Field of Multivariate Polynomial Ring
in x, y, z over Rational Field (twisting morphism: x |--> y, y |--> z, z |--> x)
Over a field, one proves that every θ-derivation is a multiple of θ−id, so that:
sage: d = M.gen(); d
[x |--> y, y |--> z, z |--> x] - id
and then:
sage: d(x)
-x + y
sage: d(y)
-y + z
sage: d(z)
x - z
sage: d(x + y + z)
0
AUTHOR:
- Xavier Caruso (2018-09)
-
class
sage.rings.derivation.
RingDerivation
¶ Bases:
sage.structure.element.ModuleElement
An abstract class for twisted and untwisted derivations over commutative rings.
-
codomain
()¶ Return the codomain of this derivation.
EXAMPLES:
sage: R.<x> = QQ[] sage: f = R.derivation(); f d/dx sage: f.codomain() Univariate Polynomial Ring in x over Rational Field sage: f.codomain() is R True
sage: S.<y> = R[] sage: M = R.derivation_module(S) sage: M.random_element().codomain() Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: M.random_element().codomain() is S True
-
domain
()¶ Return the domain of this derivation.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: f = R.derivation(y); f d/dy sage: f.domain() Multivariate Polynomial Ring in x, y over Rational Field sage: f.domain() is R True
-
-
class
sage.rings.derivation.
RingDerivationModule
(domain, codomain, twist=None)¶ Bases:
sage.modules.module.Module
,sage.structure.unique_representation.UniqueRepresentation
A class for modules of derivations over a commutative ring.
-
basis
()¶ Return a basis of this module of derivations.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy)
-
codomain
()¶ Return the codomain of the derivations in this module.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module(); M Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.codomain() Multivariate Polynomial Ring in x, y over Integer Ring
-
defining_morphism
()¶ Return the morphism defining the structure of algebra of the codomain over the domain.
EXAMPLES:
sage: R.<x> = QQ[] sage: M = R.derivation_module() sage: M.defining_morphism() Identity endomorphism of Univariate Polynomial Ring in x over Rational Field sage: S.<y> = R[] sage: M = R.derivation_module(S) sage: M.defining_morphism() Polynomial base injection morphism: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: ev = R.hom([QQ(0)]) sage: M = R.derivation_module(ev) sage: M.defining_morphism() Ring morphism: From: Univariate Polynomial Ring in x over Rational Field To: Rational Field Defn: x |--> 0
-
domain
()¶ Return the domain of the derivations in this module.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module(); M Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.domain() Multivariate Polynomial Ring in x, y over Integer Ring
-
dual_basis
()¶ Return the dual basis of the canonical basis of this module of derivations (which is that returned by the method
basis()
).Note
The dual basis of (d1,…,dn) is a family (x1,…,xn) of elements in the domain such that di(xi)=1 and di(xj)=0 if i≠j.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: M.dual_basis() Family (x, y)
-
gen
(n=0)¶ Return the
n
-th generator of this module of derivations.INPUT:
n
– an integer (default:0
)
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module(); M Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.gen() d/dx sage: M.gen(1) d/dy
-
gens
()¶ Return the generators of this module of derivations.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module(); M Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.gens() (d/dx, d/dy)
We check that, for a nontrivial twist over a field, the module of twisted derivation is a vector space of dimension 1 generated by
twist - id
:sage: K = R.fraction_field() sage: theta = K.hom([K(y),K(x)]) sage: M = K.derivation_module(twist=theta); M Module of twisted derivations over Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x) sage: M.gens() ([x |--> y, y |--> x] - id,)
-
ngens
()¶ Return the number of generators of this module of derivations.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module(); M Module of derivations over Multivariate Polynomial Ring in x, y over Integer Ring sage: M.ngens() 2
Indeed, generators are:
sage: M.gens() (d/dx, d/dy)
We check that, for a nontrivial twist over a field, the module of twisted derivation is a vector space of dimension 1 generated by
twist - id
:sage: K = R.fraction_field() sage: theta = K.hom([K(y),K(x)]) sage: M = K.derivation_module(twist=theta); M Module of twisted derivations over Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x) sage: M.ngens() 1 sage: M.gen() [x |--> y, y |--> x] - id
-
random_element
(*args, **kwds)¶ Return a random derivation in this module.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module() sage: M.random_element() # random (x^2 + x*y - 3*y^2 + x + 1)*d/dx + (-2*x^2 + 3*x*y + 10*y^2 + 2*x + 8)*d/dy
-
ring_of_constants
()¶ Return the subring of the domain consisting of elements x such that d(x)=0 for all derivation d in this module.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: M.ring_of_constants() Rational Field
-
some_elements
()¶ Return a list of elements of this module.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: M = R.derivation_module() sage: M.some_elements() [d/dx, d/dy, x*d/dx, x*d/dy, y*d/dx, y*d/dy]
-
twisting_morphism
()¶ Return the twisting homomorphism of the derivations in this module.
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: theta = R.hom([y,x]) sage: M = R.derivation_module(twist=theta); M Module of twisted derivations over Multivariate Polynomial Ring in x, y over Integer Ring (twisting morphism: x |--> y, y |--> x) sage: M.twisting_morphism() Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> y y |--> x
When the derivations are untwisted, this method returns nothing:
sage: M = R.derivation_module() sage: M.twisting_morphism()
-
-
class
sage.rings.derivation.
RingDerivationWithTwist_generic
(parent, scalar=0)¶ Bases:
sage.rings.derivation.RingDerivation
The class handles θ-derivations of the form λ(θ−ι) (where ι is the defining morphism of the codomain over the domain) for a scalar λ varying in the codomain.
-
list
()¶ Return the list of coefficient of this twisted derivation on the canonical basis.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: K = R.fraction_field() sage: theta = K.hom([y,x]) sage: M = K.derivation_module(twist=theta) sage: M.basis() Family (twisting_morphism - id,) sage: f = (x+y) * M.gen() sage: f (x + y)*(twisting_morphism - id) sage: f.list() [x + y]
-
postcompose
(morphism)¶ Return the twisted derivation obtained by applying first this twisted derivation and then
morphism
.INPUT:
morphism
– a homomorphism of rings whose domain is the codomain of this derivation or a ring into which the codomain of this derivation
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: theta = R.hom([y,x]) sage: D = R.derivation(x, twist=theta); D x*([x |--> y, y |--> x] - id) sage: f = R.hom([x^2, y^3]) sage: g = D.precompose(f); g x*([x |--> y^2, y |--> x^3] - [x |--> x^2, y |--> y^3])
Observe that the g is no longer a θ-derivation but a (θ∘f)-derivation:
sage: g.parent().twisting_morphism() Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> y^2 y |--> x^3
-
precompose
(morphism)¶ Return the twisted derivation obtained by applying first
morphism
and then this twisted derivation.INPUT:
morphism
– a homomorphism of rings whose codomain is the domain of this derivation or a ring that coerces to the domain of this derivation
EXAMPLES:
sage: R.<x,y> = ZZ[] sage: theta = R.hom([y,x]) sage: D = R.derivation(x, twist=theta); D x*([x |--> y, y |--> x] - id) sage: f = R.hom([x^2, y^3]) sage: g = D.postcompose(f); g x^2*([x |--> y^3, y |--> x^2] - [x |--> x^2, y |--> y^3])
Observe that the g is no longer a θ-derivation but a (f∘θ)-derivation:
sage: g.parent().twisting_morphism() Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> y^3 y |--> x^2
-
-
class
sage.rings.derivation.
RingDerivationWithoutTwist
¶ Bases:
sage.rings.derivation.RingDerivation
An abstract class for untwisted derivations.
-
is_zero
()¶ Return
True
if this derivation is zero.EXAMPLES:
sage: R.<x,y> = ZZ[] sage: f = R.derivation(); f d/dx sage: f.is_zero() False sage: (f-f).is_zero() True
-
list
()¶ Return the list of coefficient of this derivation on the canonical basis.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: R.derivation(x).list() [1, 0] sage: R.derivation(y).list() [0, 1] sage: f = x*R.derivation(x) + y*R.derivation(y); f x*d/dx + y*d/dy sage: f.list() [x, y]
-
monomial_coefficients
()¶ Return dictionary of nonzero coordinates (on the canonical basis) of this derivation.
More precisely, this returns a dictionary whose keys are indices of basis elements and whose values are the corresponding coefficients.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: R.derivation(x).monomial_coefficients() {0: 1} sage: R.derivation(y).monomial_coefficients() {1: 1} sage: f = x*R.derivation(x) + y*R.derivation(y); f x*d/dx + y*d/dy sage: f.monomial_coefficients() {0: x, 1: y}
-
postcompose
(morphism)¶ Return the derivation obtained by applying first this derivation and then
morphism
.INPUT:
morphism
– a homomorphism of rings whose domain is the codomain of this derivation or a ring into which the codomain of this derivation coerces
EXAMPLES:
sage: A.<x,y>= QQ[] sage: ev = A.hom([QQ(0), QQ(1)]) sage: Dx = A.derivation(x) sage: Dy = A.derivation(y)
We can define the derivation at (0,1) just by postcomposing with
ev
:sage: dx = Dx.postcompose(ev) sage: dy = Dy.postcompose(ev) sage: f = x^2 + y^2 sage: dx(f) 0 sage: dy(f) 2
Note that we cannot avoid the creation of the evaluation morphism: if we pass in
QQ
instead, an error is raised since there is no coercion morphism fromA
toQQ
:sage: Dx.postcompose(QQ) Traceback (most recent call last): ... TypeError: the codomain of the derivation does not coerce to the given ring
Note that this method cannot be used to compose derivations:
sage: Dx.precompose(Dy) Traceback (most recent call last): ... TypeError: you must give an homomorphism of rings
-
precompose
(morphism)¶ Return the derivation obtained by applying first
morphism
and then this derivation.INPUT:
morphism
– a homomorphism of rings whose codomain is the domain of this derivation or a ring that coerces to the domain of this derivation
EXAMPLES:
sage: A.<x> = QQ[] sage: B.<x,y> = QQ[] sage: D = B.derivation(x) - 2*x*B.derivation(y); D d/dx - 2*x*d/dy
When restricting to
A
, the termd/dy
disappears (since it vanishes onA
):sage: D.precompose(A) d/dx
If we restrict to another well chosen subring, the derivation vanishes:
sage: C.<t> = QQ[] sage: f = C.hom([x^2 + y]); f Ring morphism: From: Univariate Polynomial Ring in t over Rational Field To: Multivariate Polynomial Ring in x, y over Rational Field Defn: t |--> x^2 + y sage: D.precompose(f) 0
Note that this method cannot be used to compose derivations:
sage: D.precompose(D) Traceback (most recent call last): ... TypeError: you must give an homomorphism of rings
-
pth_power
()¶ Return the p-th power of this derivation where p is the characteristic of the domain.
Note
Leibniz rule implies that this is again a derivation.
EXAMPLES:
sage: R.<x,y> = GF(5)[] sage: Dx = R.derivation(x) sage: Dx.pth_power() 0 sage: (x*Dx).pth_power() x*d/dx sage: (x^6*Dx).pth_power() x^26*d/dx sage: Dy = R.derivation(y) sage: (x*Dx + y*Dy).pth_power() x*d/dx + y*d/dy
An error is raised if the domain has characteristic zero:
sage: R.<x,y> = QQ[] sage: Dx = R.derivation(x) sage: Dx.pth_power() Traceback (most recent call last): ... TypeError: the domain of the derivation must have positive and prime characteristic
or if the characteristic is not a prime number:
sage: R.<x,y> = Integers(10)[] sage: Dx = R.derivation(x) sage: Dx.pth_power() Traceback (most recent call last): ... TypeError: the domain of the derivation must have positive and prime characteristic
-
-
class
sage.rings.derivation.
RingDerivationWithoutTwist_fraction_field
(parent, arg=None)¶ Bases:
sage.rings.derivation.RingDerivationWithoutTwist_wrapper
This class handles derivations over fraction fields.
-
class
sage.rings.derivation.
RingDerivationWithoutTwist_function
(parent, arg=None)¶ Bases:
sage.rings.derivation.RingDerivationWithoutTwist
A class for untwisted derivations over rings whose elements are either polynomials, rational fractions, power series or Laurent series.
-
is_zero
()¶ Return
True
if this derivation is zero.EXAMPLES:
sage: R.<x,y> = ZZ[] sage: f = R.derivation(); f d/dx sage: f.is_zero() False sage: (f-f).is_zero() True
-
list
()¶ Return the list of coefficient of this derivation on the canonical basis.
EXAMPLES:
sage: R.<x,y> = GF(5)[[]] sage: M = R.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: R.derivation(x).list() [1, 0] sage: R.derivation(y).list() [0, 1] sage: f = x*R.derivation(x) + y*R.derivation(y); f x*d/dx + y*d/dy sage: f.list() [x, y]
-
-
class
sage.rings.derivation.
RingDerivationWithoutTwist_quotient
(parent, arg=None)¶ Bases:
sage.rings.derivation.RingDerivationWithoutTwist_wrapper
This class handles derivations over quotient rings.
-
class
sage.rings.derivation.
RingDerivationWithoutTwist_wrapper
(parent, arg=None)¶ Bases:
sage.rings.derivation.RingDerivationWithoutTwist
This class is a wrapper for derivation.
It is useful for changing the parent without changing the computation rules for derivations. It is used for derivations over fraction fields and quotient rings.
-
list
()¶ Return the list of coefficient of this derivation on the canonical basis.
EXAMPLES:
sage: R.<X,Y> = GF(5)[] sage: S.<x,y> = R.quo([X^5, Y^5]) sage: M = S.derivation_module() sage: M.basis() Family (d/dx, d/dy) sage: S.derivation(x).list() [1, 0] sage: S.derivation(y).list() [0, 1] sage: f = x*S.derivation(x) + y*S.derivation(y); f x*d/dx + y*d/dy sage: f.list() [x, y]
-
-
class
sage.rings.derivation.
RingDerivationWithoutTwist_zero
(parent, arg=None)¶ Bases:
sage.rings.derivation.RingDerivationWithoutTwist
This class can only represent the zero derivation.
It is used when the parent is the zero derivation module (e.g., when its domain is
ZZ
,QQ
, a finite field, etc.)-
is_zero
()¶ Return
True
if this derivation vanishes.EXAMPLES:
sage: M = QQ.derivation_module() sage: M().is_zero() True
-
list
()¶ Return the list of coefficient of this derivation on the canonical basis.
EXAMPLES:
sage: M = QQ.derivation_module() sage: M().list() []
-