I suppose it depends how you define the free module over S
-- I think the recommended way is using CombinatorialFreeModule
, although while trying to do what you want, I did get a number of errors saying that it is "still using old coercion framework", whatever that means . . .
In any case, I think I was able to do something like what you want, as long as your basis set is finite. Let me know if it works for you:
sage: a = (1,1,1)
sage: b = (1,3,2)
sage: c = (2,1,2)
sage: F = CombinatorialFreeModule(ZZ,[a,b,c])
sage: f = lambda x: sum(x)*F.basis()[x]
sage: f(a)
3*B[(1, 1, 1)]
sage: f(b)
6*B[(1, 3, 2)]
sage: f(c)
5*B[(2, 1, 2)]
sage: phi = F.hom([f(x) for x in [a,b,c]], F)
sage: phi.on_basis()
[3*B[(1, 1, 1)], 6*B[(1, 3, 2)], 5*B[(2, 1, 2)]]
Note, in particular, that it's a little tricky to get the elements a, b, c
as elements of F
. The method F.basis()
gives the basis as a sage finite family, and you recover the element corresponding to a
, for example, as if it were the key in a python dictionary: F.basis()[a]
. Such a convoluted approach would not be necessary if coercion was working correctly.
Some further examples of .hom()
are given (for rings) at the Homomorphisms of rings manual page.