Open StevellM opened 9 months ago
I guess the problem in this case is that the 'optional' third argument of hom
for polynomial rings is a map for the coefficient rings and there is no real meaningful type constraint for this (it could be an OSCAR homomorphism type, a julia function, possibly a dictionary (?), ???).
But I agree that the different hom
constructors should be consistent. Maybe things like coeff_map
should be a keyword argument? Looking at ?hom
, it seems difficult though to find a common set of input arguments every hom should support. Even codomain and domain as first arguments seems not to be necessary/consistent:
hom(A::Vector{GrpAbFinGenElem}, B::Vector{GrpAbFinGenElem}) -> Map
That there is no type restriction on the coefficient map as the third argument was a decision (If I recall correctly; @thofma ?). Whether we want to have it as a keyword argument might be debatable. I have no strong opinion on that. But specifying two sets of generators in a constructor also seems awkward to me. Why would you specify generators in the domain?
I do not think about a general solution, and at the stage where we are it is going to be difficult to revert everything to a clean and universal pattern. Though I am concerned that the constructor allows me to create something which does not work. After further investigation, it is not only the printing which is affected but also the use of the function itself.
I specify generators because there are constructors for group homomorphisms where it is possible, namely when you know the images of certain elements which do not correspond to gens
for instance. In that case, you specify which are those elements and what are their image. Naively I thought it would work the same, and the constructor did not complain.
I think that there are different things to consider here:
We are at a stage, where we can change everything, so we should strive for some consistency. Things we could do:
hom(R, S, coefficient_map, imgs_of_gens)
we do as @HechtiDerLachs suggested:
hom(R, S, imgs_of_gens [, coefficient_map = g]) # what we have now for affine algebras, but with keyword argument
hom(A::Vector{GrpAbFinGenElem}, B::Vector{GrpAbFinGenElem})
into
hom(D, C, [a => b for (a, b) in zip(A, B)])
so that this is invoked for example as hom(D, C, [g1 => h1, g2 => h2])
. (I also added domain/codomain here.)
I am in favour of 1), no matter what we decide else.
On Thu, Dec 07, 2023 at 12:55:53AM -0800, Tommy Hofmann wrote:
I think that there are different things to consider here:
- I agree with Stevell, that in the context of groups it is a very useful feature. Assume $G, H$ are two groups and $f \colon G \to H$ a morphism that one would like to construct. Often one knows $f$ on some generating set of $G$, which might be different from the generating set of $G$. Not sure how useful it is for polynomial rings/affine algebras. Is there a situation where you know $f \colon \mathbf{Q}[x, y] \to R$ for only $f(x + 1)$ and $f(y - 1)$? There aren't that many other algebra generators.
- We cannot properly type the coefficient map, because there is not proper type for callable things.
We are at a stage, where we can change everything, so we should strive for some consistency. Things we could do:
- Instead
hom(R, S, coefficient_map, imgs_of_gens)
we do as @HechtiDerLachs suggested:hom(R, S, imgs_of_gens [, coefficient_map = g]) # what we have now for affine algebras, but with keyword argument
I can live with both, the 1st is more concise, the 2nd readable. Is the coeff map from coeff(R) -> S or to coeff(S)? or undecided? The latter is much more efficient, but restrictive
- Turn
hom(A::Vector{GrpAbFinGenElem}, B::Vector{GrpAbFinGenElem})
intohom(D, C, [a => b for (a, b) in zip(A, B)])
so that this is invoked for example as
hom(D, C, [g1 => h1, g2 => h2])
. (I also added domain/codomain here.) Happy with pairs. Code should probably be rewritten to directly get pairs and not the individual lists first I am in favour of 1), no matter what we decide else.-- Reply to this email directly or view it on GitHub: https://github.com/oscar-system/Oscar.jl/issues/3072#issuecomment-1844935952 You are receiving this because you are subscribed to this thread.
Message ID: @.***>
Looking at ?hom
I have the impression that we could enforce the following general policy to make hom
more consistent without too much trouble.
Every hom
that returns a map between two objects (apparently there are others) should have one of the following signatures:
hom(domain, codomain, images, ...)
defining the map by images of canonical generatorshom(domain, codomain, mapping, ...)
defining the map by a julia function or a matrix or ???hom(domain, codomain, generators, images, ...)
defining the map by mapping generators
to images
, potentially changed to @thofma's suggestion 2, ...
can then be any other arguments that are necessary or useful to construct the map, preferably by keyword arguments.
Is the coeff map from coeff(R) -> S or to coeff(S)? or undecided?
Undecided. The code for the mappings checks which one is the case and performs the mapping accordingly.
Describe the bug While constructing a homomorphism between two multivariate polynomial rings, the function do not check the entry which leads to a bug when trying to print.
I was used to create group homomorphism by feeding a domain, a codomain, a set of generators and their images. I thought that it was similar for
hom
between rings but apparently not and the constructor did not complain (I then checked the source code and found out my mistake. The problem is that there are many functionshom
and they are not consistent through Oscar.To Reproduce That was my particular example, where I just wanted to map a polynomial ring to its reduction modulo a prime ideal.
Expected behavior I did not expect much but while trying to print
KtoKp
, I end up with an error which is not super explicit. Indeed, it does not tell me I did something wrong with the constructor, but just fallback on trying to use a vector as a function:So my expectation would have been that Oscar complained that my input were not correct: it should check that the user follows the documentation and put a function on the base rings as third argument. At least now I know, but young users this is not helpful if you use
hom
with different structures within Oscar.System (please complete the following information): Please paste the output of
Oscar.versioninfo(full=true)
below. If this does not work, please paste the output of Julia'sversioninfo()
and your Oscar version.Additional context I know how to solve this issue for myself, I thought though it would be good to tell about this issue (hopefully there were no other open issues on the same subject)