sagemath/sage

FreeModule.hom stores its matrix over the wrong ring

koffie opened this issue · 14 comments

This is ok:

sage: (ZZ^2).hom([[2,3],[3,6]],QQ^2) 
Free module morphism defined by the matrix
[2 3]
[3 6]
Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
Codomain: Vector space of dimension 2 over Rational Field

This should not be possible:

sage: (QQ^2).hom([[1/3,1/4],[1/3,1/6]],ZZ^2)
Free module morphism defined by the matrix
[1/3 1/4]
[1/3 1/6]
Domain: Vector space of dimension 2 over Rational Field
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring

This should work

sage: (ZZ^2).hom([[1/3,1/4],[1/3,1/6]],QQ^2) #goes boom with an error you might have excpected in the previous example
Traceback (most recent call last):
...
TypeError: no conversion of this rational to integer

This should defenitly also not work:

sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2)
Free module morphism defined by the matrix
[6 0]
[0 0]
Domain: Vector space of dimension 2 over Finite Field of size 7
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring

The following should give a clue what is going wrong:


sage: (GF(7)^2).hom([[1/3,1/4],[1/3,1/6]],QQ^2)
Vector space morphism represented by the matrix:
[5 2]
[5 6]
Domain: Vector space of dimension 2 over Finite Field of size 7
Codomain: Vector space of dimension 2 over Rational Field
sage: _.matrix().parent()
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
sage: (QQ^2).hom([[1/3,1/4],[1/3,1/6]],ZZ^2)
Free module morphism defined by the matrix
[1/3 1/4]
[1/3 1/6]
Domain: Vector space of dimension 2 over Rational Field
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
sage: _.matrix().parent()
Full MatrixSpace of 2 by 2 dense matrices over Rational Field

Seems that somewhere the domain and codomain are messed up.

CC: @novoselt @sagetrac-jakobkroeker

Component: linear algebra

Author: Frédéric Chapoton

Branch/Commit: caae8a7

Reviewer: Matthias Koeppe

Issue created by migration from https://trac.sagemath.org/ticket/13321

comment:7

why should the following example not work?

   sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2)

all other mentioned ticket issues are fixed

comment:8

It is not mathematically well-defined. See:

sage: ZZ.has_coerce_map_from(GF(7))
False

Stopgaps: wrongBehaviourMarker

comment:10

Replying to @tscrim:

It is not mathematically well-defined. See:

sage: ZZ.has_coerce_map_from(GF(7))
False

D'oh!
Indeed.

Hopefully nobody reads my question.
It is still incorrect in recent sage 7.6, beta 4.

comment:11

As an update to this ticket as of Sage 8.9, this appears to be almost fixed by now. The incorrect example:

(QQ^2).hom([[1/3,1/4],[1/3,1/6]],ZZ^2)

Now gives an error (no conversion of this rational to integer), and the example which is correct:

(ZZ^2).hom([[1/3,1/4],[1/3,1/6]],QQ^2)

Does work. The part of this ticket that seems to be still relevant is the fact that the following does not give an error:

sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2)
Free module morphism defined by the matrix
[20  0]
[ 0 21]
Domain: Vector space of dimension 2 over Finite Field of size 7
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring

as mentioned above, since it doesn't make sense to coerce from GF(7) to ZZ. This is still something to fix

comment:12

The final example in this issue seems to be solved. I.e. the following raises an error as expected:

sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2)                                       
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-f279e7ac9774> in <module>
----> 1 (GF(Integer(7))**Integer(2)).hom([[Integer(20),Integer(0)],[Integer(0),Integer(21)]],ZZ**Integer(2))

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/structure/parent.pyx in sage.structure.parent.Parent.hom (build/cythonized/sage/structure/parent.c:12200)()
   1421             kwds['base_map'] = base_map
   1422         Hom_kwds = {} if category is None else {'category': category}
-> 1423         return self.Hom(codomain, **Hom_kwds)(im_gens, **kwds)
   1424 
   1425     #################################################################################

/var/tmp/sage-9.4-current/local/lib/python3.9/site-packages/sage/modules/free_module_homspace.py in __call__(self, A, check)
    209                 pass
    210         if not self.codomain().base_ring().has_coerce_map_from(self.domain().base_ring()) and not A.is_zero():
--> 211             raise TypeError("nontrivial morphisms require a coercion map from the base ring of the domain to the base ring of the codomain")
    212         return free_module_morphism.FreeModuleMorphism(self, A)
    213 

TypeError: nontrivial morphisms require a coercion map from the base ring of the domain to the base ring of the codomain

Additionally the only morphism that does exist is still valid:

sage: (GF(7)^2).hom([[0,0],[0,0]],ZZ^2)                                         
Free module morphism defined by the matrix
[0 0]
[0 0]
Domain: Vector space of dimension 2 over Finite Field of size 7
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
comment:14

Should we add a doctest to guard against changes to the current behavior?

Author: Frédéric Chapoton

comment:15

I have added a doctest and refreshed the file.


New commits:

caae8a7add one doctest for free module morphism

Commit: caae8a7

Reviewer: Matthias Koeppe

Changed stopgaps from wrongBehaviourMarker to none

Changed branch from u/chapoton/13321 to caae8a7