Coercion question

47 views
Skip to first unread message

Andrew

unread,
Jul 30, 2024, 1:13:27 AM7/30/24
to sage-support
[Not sure if this belongs here or in sage-dev...]

I am trying to implement coercions between algebras that are related by base change. For example,consider

A=CombinatorialFreeModule(ZZ['x'], ['1','2'])
B=CombinatorialFreeModule(ZZ, ['1','2'])
A.module_morphism(
    lambda a: B._from_dict({b: c.subtitute(x=1) for (b,c) in a}), 
    codomain=B, category=A.category()
).register_as_coercion()

This fails with a category mismatch error because A is defined over Z[x] and B over Z:

ValueError: Free module generated by {'1', '2'} over Univariate Polynomial Ring in x over Integer Ring is not in Category of finite dimensional modules with basis over Integer Ring

This is entirely reasonable because I have not specified how Z is a Z[x]-module, but when I try to define this it seems I need slightly different syntax:

Rx = ZZ['x]
R = ZZ
Rx.module_morphism(function=lambda f: f.substitute(x=1), codomain=R)

This also fails with a category mismatch:

ValueError: Integer Ring is not in Category of modules over Integer Ring

My actual use case is slightly more complicated in that I have an algebra defined as a combinatorial free module with multiple realisations and the rings could be different, but this is the essence of my problem. I could just fudge this but I'd like to do this "properly".

Andrew

Nils Bruin

unread,
Jul 30, 2024, 12:49:16 PM7/30/24
to sage-support
On Monday 29 July 2024 at 22:13:27 UTC-7 Andrew wrote:
[Not sure if this belongs here or in sage-dev...]

I am trying to implement coercions between algebras that are related by base change. For example,consider

A=CombinatorialFreeModule(ZZ['x'], ['1','2'])
B=CombinatorialFreeModule(ZZ, ['1','2'])
A.module_morphism(
    lambda a: B._from_dict({b: c.subtitute(x=1) for (b,c) in a}), 
    codomain=B, category=A.category()
).register_as_coercion()

Are you sure you want to register that as a *coercion*? Those are to be used in other coercion discoveries as well and can be used implicitly to resolve things like a+b, where a in A and b in B (and extensions of these!)
 
This is entirely reasonable because I have not specified how Z is a Z[x]-module, but when I try to define this it seems I need slightly different syntax:

Rx = ZZ['x]
R = ZZ
Rx.module_morphism(function=lambda f: f.substitute(x=1), codomain=R)

These are bases, so I think you should define a ring homomorphism between them (I think a CombinatorialFreeModule has a ring as its base). And then you see how you'd get a problem if you insert a coercion from ZZ['x'] to ZZ: there's already one in the oppositie direction and sage really prefers its coercion graph to not have directed cycles.
 
So I expect that your original map A -> B should really be one from a ZZ['x']-module to a ZZ-module, where ZZ is really ZZ['x']/(x-1).

In fact, with

P.<x>=ZZ[]
R=P.quo(x-1)
A=CombinatorialFreeModule(P, ['1','2'])
B=CombinatorialFreeModule(R, ['1','2'])

I get:

sage: x*A('1')+B('2')
B['1'] + B['2']

so it seems to discover the coercion correctly. (I do get that A('1') prints as B['1'] so there is something fishy there. Are combinatorial modules always printing as `B`? or is that the default name for its "basis"?)

Andrew

unread,
Jul 31, 2024, 9:47:18 AM7/31/24
to sage-support
Thanks Nils. Actually, I think that what I need is a conversion rather than a coercion as `register_as_conversion()` lets me change the category.
Reply all
Reply to author
Forward
0 new messages