# support() and coefficients() in combinatorial free modules

I was surprised that in the code below I could not count on the lists returned by support() and coefficients() to correspond. Is there a proper way to use these methods in conjunction with each other, or should I adopt a different approach? If I sort the list returned by support() will I be able to count on the coefficients corresponding with generators?

k3.<w3> = CyclotomicField(3)
F3 = CombinatorialFreeModule(k3,NN,prefix='v3')
v3 = F3.basis()
v3

>  Lazy family (Term map from Non negative integer semiring to Free module generated by Non negative integer semiring over Cyclotomic Field of order 3 and degree 2(i))_{i in Non negative integer semiring}

expr = -2*v3[34] - (-2*w3)*v3[42] - 2*v3[58] - (2*w3+2)*v3[66]
[expr.support(),expr.coefficients()]

> [[34, 42, 66, 58], [-2, 2*w3, -2, -2*w3 - 2]]


Perhaps I should ask my real question, while I'm here. I have a list of module elements (actually vectors) and would like to find the kernel of the matrix with these vectors as rows. The matrix is likely to be sparse. I encountered the issue described above while trying to set up the matrix by hand from the list of vectors.

Added: The suggestion of John Palmieri in a comment and of tmonteil in an answer to use expr.monomial_coefficients() solves my problem, but I think it still worth trying to pin down the answer to the original question.

The documentation for support() says

Return a list of the objects indexing the basis of "self.parent()" whose corresponding coefficients of "self" are non-zero.

This method returns these objects in an arbitrary order.

The documentation for coefficients() says

Return a list of the (non-zero) coefficients appearing on the basis elements in "self" (in an arbitrary order).

INPUT:

• "sort" -- (default: "True") to sort the coefficients based upon the default ordering of the indexing set

Both mention that elements are returned "in an arbitrary order". Since it is not specified that the arbitrary order returned by the two functions is the same, one must assume the orders could be different. I wonder, however, whether they are intended to be the same since it is difficult to imagine many uses for a function that returns coefficients without making it possible to determine what they are coefficients of.

The other striking thing is that coefficients() actually doesn't default to the behavior described in the first line of the documentation: it defaults to "sort=True" which causes the coefficients to be returned in an order corresponding to the sorted order of the elements of the support, and not an arbitrary order. Since support() has no "sort" option, the only option is the "arbitrary" order. I strongly suspect that if one turns off the default option in coefficients() by setting "sort=False", one will get an arbitrary order that corresponds to that of support(), but, if true, it would be nice to have that documented somewhere.

edit retag close merge delete

1

expr.monomial_coefficients() might give you what you want, as far as the first question goes, or you could use expr.coefficients(sort=True).

( 2021-08-29 06:20:58 +0200 )edit

expr.monomial_coefficients() looks like the right approach; I've managed to use it to set up a sparse matrix and solve my problem For future reference, are you saying that expr.coefficients(sort=True) will return the coefficients in the order corresponding to the sorted list of support elements? I'm sure this is documented somewhere, but I'm not sufficiently familiar with how the documentation is structured to search effectively.

( 2021-08-29 22:20:58 +0200 )edit

I should have tried expr.coefficients()? first, to see what help was available. This provides me with "'sort' -- (default: 'True') to sort the coefficients based upon the default ordering of the indexing set." It appears, therefore, that I could have used my original code with "sort=False" to suppress the default sorting of coefficients(), and it would have worked. Or I could sort the list returned by support() and use that in conjunction with "coefficients(sort=True)" or simply "coefficients()", which seems in line with your suggestion.

( 2021-08-29 22:57:16 +0200 )edit
1

The relevant documentation is in the reference manual here: https://doc.sagemath.org/html/en/refe...

( 2021-08-30 04:34:56 +0200 )edit

Sort by » oldest newest most voted

On my machine, running Sage 9.4, i see no problem in the relative ordering:

sage: expr.support()
[34, 42, 58, 66]
sage: expr.coefficients()
[-2, 2*w3, -2, -2*w3 - 2]
sage: expr.monomials()
[v3[34], v3[42], v3[58], v3[66]]


However, the documentation of those methods are clear that the list is returned in an arbitrary order, so that we can not rely on that.

According to git blame + git trac find, you should find more details on trac ticket 18066

The sage: monomial_coefficients method suggested by @john-palmieri is the way to go as it returns a dict which links the elements of the support with the corresponding coefficients:

sage: expr.monomial_coefficients()
{34: -2, 42: 2*w3, 58: -2, 66: -2*w3 - 2}


or simply:

sage: dict(expr)
{34: -2, 42: 2*w3, 58: -2, 66: -2*w3 - 2}

more

Interesting that the behavior may be version or platform dependent. The dictionary method does seem to be the better way. I left some comments on my original post about what I think is going on with the ordering, and there may be a way to get the original idea to work too.

( 2021-08-29 23:01:17 +0200 )edit