I'm having several problems with module/vector spaces-morphisms in Sage. I'm
not sure exactly what we want to fix.
The starting point was that in the category Modules() the zero of the Hom set
is defined as:
class HomCategory(HomCategory):
class ParentMethods:
@cached_method
def zero(self):
return self(lambda x: self.codomain().zero())
This create a pickling problem with morphisms for CombinatorialFreeModule()::
sage: M = CombinatorialFreeModule(QQ, [1,2])
sage: H = Hom(M, M)
sage: dumps(H)
'x\x9c...\xe9\x7f'
But after a::
sage: H.zero()
Generic endomorphism of Free module generated by {1, 2} over Rational Field
H is no more picklable::
sage: dumps(H)
[...]
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Note that this doesn't cause problems with (finite dimensional) FreeModule
because the matrix is expanded::
sage: M = FreeModule(QQ, 2)
sage: H = Hom(M, M)
sage: H.zero()
Vector space morphism represented by the matrix:
[0 0]
[0 0]
Domain: Vector space of dimension 2 over Rational Field
Codomain: Vector space of dimension 2 over Rational Field
So I tried to replace::
def zero(self):
return self(lambda x: self.codomain().zero())
by::
def zero(self):
return self(ConstantFunction(self.codomain().zero()))
Now CombinatorialFreeModules are happy::
sage: M = CombinatorialFreeModule(QQ, [1,2])
sage: H = Hom(M, M)
sage: f = H(ConstantFunction(M.zero())); f
Generic endomorphism of Free module generated by {1, 2} over Rational Field
sage: dumps(f)
'x\x9c...\xe9\x7f'
However::
sage: M = FreeModule(QQ, 2)
sage: H = Hom(M, M)
sage: H(lambda x: M.zero())
Vector space morphism represented by the matrix:
[0 0]
[0 0]
Domain: Vector space of dimension 2 over Rational Field
Codomain: Vector space of dimension 2 over Rational Field
sage: H(ConstantFunction(M.zero()))
[...]
TypeError: vector space homspace can only coerce matrices, vector space morphisms, functions or lists, not The constant function (...) -> (0, 0)
As you can see there are several more or less unrelated problems and things
seems to go a little out of control. Since I know that there is some cleanup
planned here, I'd like some advice on what short term fix may be acceptable
(The original goal was to add a generic test checking that for any element x
x.__nonzero__() is consistent with x != x.parent().zero())
Thanks for any suggestion.
Cheers,
Florent
===========================
By the way::
sage: TestSuite(H).run()
Failure in _test_additive_associativity:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/commutative_additive_semigroups.py", line 77, in _test_additive_associativity
for x in tester.some_elements():
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 460, in some_elements
return self._instance.some_elements()
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 612, in some_elements
return [ self.an_element() ]
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
Failure in _test_an_element:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 402, in _test_an_element
an_element = self.an_element()
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
Failure in _test_elements:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 465, in _test_elements
an_element = self.an_element()
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
Failure in _test_elements_eq:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 552, in _test_elements_eq
elements = list(self.some_elements())+[None, 0]
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 612, in some_elements
return [ self.an_element() ]
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
Failure in _test_some_elements:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 640, in _test_some_elements
elements = self.some_elements()
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 612, in some_elements
return [ self.an_element() ]
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
Failure in _test_zero:
Traceback (most recent call last):
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 275, in run
test_method(tester = tester)
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/commutative_additive_monoids.py", line 77, in _test_zero
for x in tester.some_elements():
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py", line 460, in some_elements
return self._instance.some_elements()
File "/home/data/Sage-Install/sage-5.0.beta2/local/lib/python2.7/site-packages/sage/categories/sets_cat.py", line 612, in some_elements
return [ self.an_element() ]
File "parent.pyx", line 2518, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17566)
File "parent.pyx", line 2544, in sage.structure.parent.Parent.an_element (sage/structure/parent.c:17510)
File "parent.pyx", line 2612, in sage.structure.parent.Parent._an_element_ (sage/structure/parent.c:18101)
NotImplementedError: please implement _an_element_ for Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 2 over Rational Field
------------------------------------------------------------
The following tests failed: _test_additive_associativity, _test_an_element, _test_elements, _test_elements_eq, _test_some_elements, _test_zero
As a temporary workaround, use SetMorphism to construct the
morphism. The __call__ method of Homsets do not yet accept uniformly a
Python function (or function object) as input as they should.
Cheers,
Nicolas
--
Nicolas M. Thi�ry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/
I'm not sure how I can do that. I've now a seemingly working workaround by
defining zero by ConstantFunction in the category Modules and overloading it
using lambda in FreeModuleHomspace. Now you tell me that there is a third kind
of morphisms ?
Cheers,
Florent
There is a single class for morphisms implemented by a Python function
(or function object), namely SetMorphism. The current issue is that,
for H an homset, what H(f) does is hardcoded in each homset class. In
particular, when f is a function, it does not systematically construct
a SetMorphism as it should. So you have to do it by hand:
sage: from sage.categories.morphism import SetMorphism
sage: M = FreeModule(QQ, 2)
sage: H = Hom(M, M)
sage: phi = SetMorphism(H, ConstantFunction(M.zero()))
sage: phi
Generic endomorphism of Vector space of dimension 2 over Rational Field
sage: phi(M.an_element())
(0, 0)
sage: M = CombinatorialFreeModule(QQ, 2)
sage: M = CombinatorialFreeModule(QQ, [1,2,3])
sage: H =Hom(M,M)
sage: phi = SetMorphism(H, ConstantFunction(M.zero()))
sage: phi(M.an_element())
0
Of course, we might want to have instead a ConstantMorphism class for
ultimate speed.
Unforunately this is not quite satisfactory:
sage: M = FreeModule(QQ, 2)
sage: H = Hom(M, M)
sage: phi = SetMorphism(H, ConstantFunction(M.zero()))
sage: phi
Generic endomorphism of Vector space of dimension 2 over Rational Field
sage: phi+phi
TypeError: unsupported operand type(s) for +: 'sage.categories.morphism.SetMorphism' and 'sage.categories.morphism.SetMorphism'
What the point of having a zero if you can't add it with the other object of
the same set... Maybe, I'm asking too much with the current status...
Cheers,
Florent
+1
> Maybe, I'm asking too much with the current status...
Indeed, you are :-)
Arithmetic between objects of the same parent but belonging to
different classes is only supported in very few places in Sage, and
when it is, it's completely ad-hoc.