Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ModuleMorphismByLinearity doesn't coerce input arguments #13833

Open
cnassau opened this issue Dec 15, 2012 · 4 comments
Open

ModuleMorphismByLinearity doesn't coerce input arguments #13833

cnassau opened this issue Dec 15, 2012 · 4 comments

Comments

@cnassau
Copy link

cnassau commented Dec 15, 2012

A linear map really should know about f(0)==0:

   sage: C=CombinatorialFreeModule(ZZ,(1,2,3))
   sage: f = C.module_morphism(codomain=C,on_basis=lambda i:C.monomial(i))
   sage: f(0)
   ---------------------------------------------------------------------------
   AssertionError                            Traceback (most recent call last)
   ...
   /waste/cn/sage-5.5.rc0/local/lib/python2.7/site-packages/sage/categories/modules_with_basis.pyc in __call__(self, *args)
      1385         after = args[self._position+1:len(args)]
      1386         x = args[self._position]
   -> 1387         assert(x.parent() is self.domain())
      1388 
      1389         if self._is_module_with_basis_over_same_base_ring:

   AssertionError: 

Here ModuleMorphismByLinearity.__call__ should only complain if it cannot coerce its input into self.domain()

Component: categories

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

@nthiery
Copy link
Contributor

nthiery commented Dec 16, 2012

Hi Christian!

Replying to @cnassau:

A linear map really should know about f(0)==0:

   sage: C=CombinatorialFreeModule(ZZ,(1,2,3))
   sage: f = C.module_morphism(codomain=C,on_basis=lambda i:C.monomial(i))

Here ModuleMorphismByLinearity.__call__ should only complain if it cannot coerce its input into self.domain()

Well, a linear map from V to W should really know that f(V.zero()) ==
W.zero(), and it does! Whether that should extend by coercion to 0 is
quite questionable. I for myself would not want to depend on this
feature in my own code.

In any cases, the ``automatic coercion to self.domain()'' feature will
come for free once ModuleMorphism won't override anymore call. See
the comment in sage/categories/modules_with_basis.py, close to the
implementation of call. That's the right thing to work on, if any.
I personally deem the feature not worth the trouble temporarily
messing up with the implementation of _call_ in ModuleMorphism.

Cheers!
Nicolas

@cnassau
Copy link
Author

cnassau commented Dec 16, 2012

comment:2

Replying to @nthiery:

Well, a linear map from V to W should really know that f(V.zero()) ==
W.zero(), and it does! Whether that should extend by coercion to 0 is
quite questionable. I for myself would not want to depend on this
feature in my own code.

My background is this: I'm working on an optional package for Steenrod algebra cohomology, and I have just implemented kernels of maps between modules. Now I would like to have

f(kernel(f).an_element()) == 0

But this fails, because f cannot be evaluated on elements of kernel(f) - even though I have registered a canonical coercion map from kernel(f) into f.domain() (all of the modules are CombinatorialFreeModules).

Well, I can live with this deficiency in my code because I'm just patching Sage in my startup file. But it would be simple to fix this in Sage by changing the

assert(x.parent() is self.domain())

into a cast

x = self.domain()(x)

Whether it's worth doing this now depends on the timeframe of the other patch that you mentioned.

Cheers,

Christian

@nthiery
Copy link
Contributor

nthiery commented Dec 16, 2012

comment:3

Replying to @cnassau:

My background is this: I'm working on an optional package for Steenrod algebra cohomology, and I have just implemented kernels of maps between modules.

Nice! We will need such tools as well. Is the domain of f graded or finite dimensional?

Now I would like to have

f(kernel(f).an_element()) == 0

But this fails, because f cannot be evaluated on elements of kernel(f) - even though I have registered a canonical coercion map from kernel(f) into f.domain() (all of the modules are CombinatorialFreeModules).

I see. It would be natural to go from f.kernel() to f.codomain() using
a lift method (see S.Subquotients? for S=Sets()). So the above could
be written without coercion using:

f(kernel(f).an_element().lift()).is_zero()

Which is not so bad. Actually, the is_zero test is better since it
expresses more precisely the intention which opens the door for more
optimizations from the system (and indeed is_zero is faster than ==0).

Whether it's worth doing this now depends on the timeframe of the other patch that you mentioned.

Which, honestly, I have no idea about ... sorry. I have a patch for
multi-morphisms but it's been lying around for a while.

Cheers,
Nicolas

@cnassau
Copy link
Author

cnassau commented Dec 17, 2012

comment:4

Replying to @nthiery:

Replying to @cnassau:

My background is this: I'm working on an optional package for Steenrod algebra cohomology, and I have just implemented kernels of maps between modules.

Nice! We will need such tools as well. Is the domain of f graded or finite dimensional?

The modules are all tri-graded: they have two internal degrees (because the Steenrod algebra is bigraded) and one homological degree (because I'm really trying to implement differential graded modules).

The framework for multi-graded objects is of my own making and still quite experimental; I once had a look at some grading patches in the combinat queue [years ago] but decided that I probably needed something different. Of course, whether my own approach leads to something workable is not clear yet... I hope to arrive at something publishable at some point in the next year.

Now I would like to have

f(kernel(f).an_element()) == 0

But this fails, because f cannot be evaluated on elements of kernel(f) - even though I have registered a canonical coercion map from kernel(f) into f.domain() (all of the modules are CombinatorialFreeModules).

I see. It would be natural to go from f.kernel() to f.codomain() using
a lift method (see S.Subquotients? for S=Sets()). So the above could
be written without coercion using:

f(kernel(f).an_element().lift()).is_zero()

Which is not so bad. Actually, the is_zero test is better since it
expresses more precisely the intention which opens the door for more
optimizations from the system (and indeed is_zero is faster than ==0).

My kernels do follow the SubQuotients protocol, so this would indeed work. But I doubt that this syntax would be very appealing to users of the package.

Anyway, I can patch Sage in my package, so this is not an urgent problem for me.

Cheers,

Christian

@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@mkoeppe mkoeppe removed this from the sage-6.4 milestone Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants