How to see (1,1,1,1) as an element of Z/3Z x Z/2Z x Z/2Z x Z/2Z ?

70 views
Skip to first unread message

Nathann Cohen

unread,
Apr 26, 2014, 11:16:58 AM4/26/14
to Sage Support
Hello everybody !

I  am back again with my group problems. I need to see 4-uples as elements of the additive group Z/3Z x Z/2Z x Z/2Z x Z/2Z, how can I do that ? My problem is that Sage converts the group  I  want into Z/2Z x Z/2Z x Z/6Z and I don't want that ....

sage: g=groups.misc.AdditiveAbelian([2,2,2,3]); g
Additive abelian group isomorphic to Z/2 + Z/2 + Z/6
sage: g([1,1,1,1])
...
TypeError: length of v must be at most the number of rows of self

Thanks for your help !

Nathann

Nathann Cohen

unread,
Apr 26, 2014, 11:22:35 AM4/26/14
to sage-s...@googlegroups.com
P.S. : I need to add some of those tuples  together...

Nathann

Nathann Cohen

unread,
Apr 26, 2014, 11:33:18 AM4/26/14
to sage-s...@googlegroups.com
REALLY ????....

The group is internally 4-tuples, but it only accepts 3-uples as input. 

sage: g=groups.misc.AdditiveAbelian([2,2,2,3]); g
Additive abelian group isomorphic to Z/2 + Z/2 + Z/6
sage: print list(g)
[(0, 0, 0, 0), (0, 0, 1, 2), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 0, 2), (0, 0, 1, 1), (1, 0, 0, 0), (1, 0, 1, 2), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 0, 2), (1, 0, 1, 1), (0, 1, 0, 0), (0, 1, 1, 2), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 0, 2), (0, 1, 1, 1), (1, 1, 0, 0), (1, 1, 1, 2), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 0, 2), (1, 1, 1, 1)]
sage: g([1,1,1,1])
...
TypeError: length of v must be at most the number of rows of self
sage: g([1,1,1])  
(1, 1, 1, 2)

Does not make any sense ....

Nathann 

John H Palmieri

unread,
Apr 26, 2014, 11:47:14 AM4/26/14
to sage-s...@googlegroups.com



Note:

sage: g.V() # the group of which you're taking a quotient
Ambient free module of rank 4 over the principal ideal domain Integer Ring

So this is roundabout, but seems to work: turn (1,1,1,1) into an element of "V", then convert to an element of g:

sage: x = g(g.V()([1,1,1,1])); x
(1, 1, 1, 1)
sage: 3*x
(1, 1, 1, 0)
sage: 2*x
(0, 0, 0, 2)

(I agree that additive abelian groups in Sage have some frustrating aspects; I ran across some others, recently, but I can't remember them right now...)

 

Nathann

--
John
 

John Cremona

unread,
Apr 26, 2014, 12:14:22 PM4/26/14
to SAGE support
sage: A = AdditiveAbelianGroup([2,2,2,3], remember_generators=True)
sage: A.gens()
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
sage: A(vector([1,1,1,1]))
(1, 1, 1, 1)
sage: A(vector([1,1,1,1])).order()
6

Read AdditiveAbelianGroup? for more.

John



--
You received this message because you are subscribed to the Google Groups "sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sage-support...@googlegroups.com.
To post to this group, send email to sage-s...@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.

Nathann Cohen

unread,
Apr 26, 2014, 12:18:35 PM4/26/14
to Sage Support
I don't know what this option actually does, but both seem to work.

sage: groups.misc.AdditiveAbelian([2,2,2,3],remember_generators=False)(vector([1,1,1,1]))
(1, 1, 1, 1)
sage: groups.misc.AdditiveAbelian([2,2,2,3],remember_generators=True)(vector([1,1,1,1])) 
(1, 1, 1, 1)

Also, why should vector([1,1,1,1]) be recognised and not [1,1,1,1] ?

Nathann


--
You received this message because you are subscribed to a topic in the Google Groups "sage-support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sage-support/yexpjig9BSg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sage-support...@googlegroups.com.

Nathann Cohen

unread,
Apr 28, 2014, 4:48:28 AM4/28/14
to sage-s...@googlegroups.com
Okay, thanks to this "vector" trick I was able to do what I wanted. Do you believe that the syntax should be changed so that A(vector(whatever)) has the same result as A(whatever) ? "vector" does not add a very meaningful information here ...

Nathann

John Cremona

unread,
Apr 28, 2014, 5:45:25 AM4/28/14
to SAGE support
On 28 April 2014 09:48, Nathann Cohen <nathan...@gmail.com> wrote:
Okay, thanks to this "vector" trick I was able to do what I wanted. Do you believe that the syntax should be changed so that A(vector(whatever)) has the same result as A(whatever) ? "vector" does not add a very meaningful information here ...

I think that the point is to allow creation of elements either with respect to the input generators (using vector) or with respect to the simplified generators (without vector).  Since both sort of input look the same (tuples / lists) I am guessing that the trick of using "vector" is just that -- a trick to be able to distinguish these.   Other ways are possible, for sure.

John

Nathann Cohen

unread,
Apr 28, 2014, 6:11:45 AM4/28/14
to Sage Support
> I think that the point is to allow creation of elements either with respect to the input generators (using vector) or with respect to the simplified generators (without vector). Since both sort of input look the same (tuples / lists) I am guessing that the trick of using "vector" is just that -- a trick to be able to distinguish these. Other ways are possible, for sure.

Hmmm... Is there any point to handle both at the same time ? Why
shouldn't this decision be made when the group is built, in order to
be able to use either
1) The tuple corresponding to how the user built the group (much more natural)
2) The tuples corresponding to the reduced form if the user asked for
it during the construction ?

My problem is that I have no idea of how to make those changes... I
looked at the code but these things are inherited from
God-knows-where...

Nathann

Volker Braun

unread,
Apr 28, 2014, 6:13:59 AM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 11:11:45 AM UTC+1, Nathann Cohen wrote:
> I think that the point is to allow creation of elements either with respect to the input generators (using vector) or with respect to the simplified generators (without vector).  Since both sort of input look the same (tuples / lists) I am guessing that the trick of using "vector" is just that -- a trick to be able to distinguish these.   Other ways are possible, for sure.

Thats it.
 
Hmmm... Is there any point to handle both at the same time ? Why
shouldn't this decision be made when the group is built

-1, some method returns an abelian group and you don't know how it was constructed without having to dig around.

Nathann Cohen

unread,
Apr 28, 2014, 6:18:09 AM4/28/14
to Sage Support
> Thats it.

The syntax is awful, do we agree on that ?

> -1, some method returns an abelian group and you don't know how it was
> constructed without having to dig around.

?

But when I create a group by myself which I want to be equal to Z/2Z *
Z/3Z I end up with something different, isn't that a more important
problem ?

Right now, when I create MY group by writing is as I want as a
product, I have to call __repr__ to see what it accepts as input. If a
function built the group I can do the same, can't I ?

Come on guys... Don't tell me that creating a group as a product and
not even knowing how to convert a tuple to an element of my group is
not a problem ! This vector trick is nice, but you can't expect
anybody to figure it out immediately, and clearly the default
behaviour is not the right one !

Nathann

John Cremona

unread,
Apr 28, 2014, 7:13:01 AM4/28/14
to SAGE support
I agree there.   The fact that Z/2 x Z/3 is isomorphic ot Z/6 does not make them the same group.  We should allow construction of such a group (f.g. abelian) without standardising  anything, at least as far as the input/output interface with the user who has constructed the group is concerned.  (There can be an internal standardised model of the group, for sure).  The user can ask for the standard model, which would return a new group together with morphisms both ways.

The situation is surely the same as this:  If I define a number fields with the polynomial x^2-8 I would be unhappy if Sage decided that Q(sqrt(8))=Q(sqrt(2)) and hence gave a field whose generator satisfied x^2-2 instead, even if that is more standard.  Here we have the same abstract field but different generators for it as a Q-algebra, and we can do this sort of thing:

sage: K1.<a> = NumberField(x^2-2)
sage: K2.<b> = NumberField(x^2-8)
sage: K1==K2
False
sage: K1.is_isomorphic(K2)
True
sage: Hom(K1,K2)
Set of field embeddings from Number Field in a with defining polynomial x^2 - 2 to Number Field in b with defining polynomial x^2 - 8
sage: len(Hom(K1,K2))
2
sage: f = Hom(K1,K2)[0]
sage: f
Ring morphism:
  From: Number Field in a with defining polynomial x^2 - 2
  To:   Number Field in b with defining polynomial x^2 - 8
  Defn: a |--> 1/2*b
sage:

Volker Braun

unread,
Apr 28, 2014, 8:24:10 AM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 11:18:09 AM UTC+1, Nathann Cohen wrote:> Thats it. 
The syntax is awful, do we agree on that ?

Its always going to be somewhat confusing to have both the original definition and a canonical form around. Feel free to add more descriptive construction methods for elements. The ctor argument convention is because that was chosen originally and I didn't want to break code when refactoring it for libgap.

Nathann Cohen

unread,
Apr 28, 2014, 9:09:55 AM4/28/14
to Sage Support
> Its always going to be somewhat confusing to have both the original
> definition and a canonical form around. Feel free to add more descriptive
> construction methods for elements. The ctor argument convention is because
> that was chosen originally and I didn't want to break code when refactoring
> it for libgap.

What do you think the implications of the following changes would be ?

- if isinstance(x, (list,tuple)):
- try:
- x = self.optimized()[0].V().linear_combination_of_basis(x)
- except ValueError as msg:
- raise TypeError(msg)
- elif isinstance(x, FGP_Element):
+ if isinstance(x, FGP_Element):
x = x.lift()
return self.element_class(self, self._V(x))

This changes the codes that appears in :

sage: g=groups.misc.AdditiveAbelian([4,3,3,5])
sage: g._element_constructor??

The thing is that I really know nothing about groups, nothing about
their implementation in Sage, and that I have no idea what the impact
of such changes can be .... :-/

Nathann

John Cremona

unread,
Apr 28, 2014, 9:23:01 AM4/28/14
to SAGE support
I don't think that will work if you are relying on the error message to indicate the wrong length of input.  For example:

sage: AdditiveAbelianGroup([6,2])
Additive abelian group isomorphic to Z/2 + Z/6

Now you will expect the element (1,0) to have order 6 but it has order 2.

John


Nathann Cohen

unread,
Apr 28, 2014, 9:25:20 AM4/28/14
to Sage Support
> I don't think that will work if you are relying on the error message to
> indicate the wrong length of input. For example:
>
> sage: AdditiveAbelianGroup([6,2])
> Additive abelian group isomorphic to Z/2 + Z/6
>
> Now you will expect the element (1,0) to have order 6 but it has order 2.

No, this looks good !

sage: G=AdditiveAbelianGroup([6,2])
sage: G(vector([2,2]))
(2, 0)
sage: G(vector([1,0]))+G(vector([1,0]))
(2, 0)

Nathann

Volker Braun

unread,
Apr 28, 2014, 9:56:01 AM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 2:09:55 PM UTC+1, Nathann Cohen wrote:
What do you think the implications of the following changes would be ?
[...]

I would think that this is incompatible with the current syntax. If anything, we should add a G.linear_combination_of_gens in addition to the existing G.linear_combination_of_smith_form_gens and in doubt you should use these over just calling G().


Nathann Cohen

unread,
Apr 28, 2014, 9:59:05 AM4/28/14
to Sage Support
> I would think that this is incompatible with the current syntax.

Yes of course, that changes the default ! But I am not so sure that it
would break many things, as the current implementation is so
unreliable that you cannot "guess" what G accepts as input, unless you
made sure to define it with a reduced form already. So I am not sure
it will break a lot of things.

> If
> anything, we should add a G.linear_combination_of_gens in addition to the
> existing G.linear_combination_of_smith_form_gens and in doubt you should use
> these over just calling G().

I was more worried about performance issues. Really, I am not so sure
that it would break so much. Of course it means changing the default
behaviour, but who can use the default behaviour as it is ? I mean :
if you define the group from a reduced form already, then there will
be no change. And if you did not, well, you were in trouble already
because you had to first make sure that you gave the right things as
input.

Nathann

Volker Braun

unread,
Apr 28, 2014, 10:59:38 AM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 2:59:05 PM UTC+1, Nathann Cohen wrote:
> I would think that this is incompatible with the current syntax.
Yes of course, that changes the default

Hence it can break code that people have written privately.

Nathann Cohen

unread,
Apr 28, 2014, 11:06:36 AM4/28/14
to Sage Support
> Hence it can break code that people have written privately.

I believe that not so many have written such code, for the very same
reason. But indeed if we change that we will need a deprecation step.

Don't you agree that this change would make sense ?

I just did the change I mentionned above, and run the long tests on
all files. The only doctests which broke are documentation on why you
do not get what you expect when you feed a group with a tuple.

You can see which doctests break in u/ncohen/tmp (which removes them).
Of course the documentation would have to be updated, but this
behaviour is much more natural ....

Nathann

Volker Braun

unread,
Apr 28, 2014, 11:16:29 AM4/28/14
to sage-s...@googlegroups.com
The default repr is in terms of smith form gens, so IMHO it makes more sense to default to a linear combination of smith form gens. Imagine some method returns an abelian group, how are you going to construct elements?


Nathann Cohen

unread,
Apr 28, 2014, 11:19:55 AM4/28/14
to Sage Support
> The default repr is in terms of smith form gens, so IMHO it makes more sense
> to default to a linear combination of smith form gens. Imagine some method
> returns an abelian group, how are you going to construct elements?

Well, obviously by changing repr, no ? O_o

Nathann

Nathann Cohen

unread,
Apr 28, 2014, 11:20:48 AM4/28/14
to Sage Support
I mean ... Really, nobody cares what the smith form generators are.
It's a technical problem, the user does not even have to be aware of
that !

Nathann

Simon King

unread,
Apr 28, 2014, 11:23:39 AM4/28/14
to sage-s...@googlegroups.com
Hi!
+1.

There should of course be a command to "normalise" a product of abelian groups.
But applying this normalisation by default violates the principle of
least surprise, IMHO.

Cheers,
Simon

Volker Braun

unread,
Apr 28, 2014, 11:25:35 AM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 4:06:36 PM UTC+1, Nathann Cohen wrote:
I believe that not so many have written such code, for the very same
reason. But indeed if we change that we will need a deprecation step.

Moreover, how are you going to deprecate it? When is a deprecation warning shown?

Nathann Cohen

unread,
Apr 28, 2014, 11:27:45 AM4/28/14
to Sage Support
> Moreover, how are you going to deprecate it? When is a deprecation warning
> shown?

Ahahahah. That's an interesting question, but the current way being
bad, there is absolutely no way that it will stay like that forever
just because we don't know how to tell the users :-D

I had something a bit unpleasant in mind... Just showing a deprecation
warning in this __call__ function saying that the standard WILL
change, and doing nothing... And removing the lines we need to remove
one year from now.

Nathann

Nathann Cohen

unread,
Apr 28, 2014, 11:29:39 AM4/28/14
to Sage Support
To be honest, I would prefer to do the opposite. Changing it now while
printing a message saying that the format changed, and removing the
message one year from now.

Nathann

John H Palmieri

unread,
Apr 28, 2014, 11:36:51 AM4/28/14
to sage-s...@googlegroups.com
Here's something I find really confusing about additive abelian groups:

sage: H = AdditiveAbelianGroup([0,2])
sage: H((2,0))
(0, 0)
sage: H(vector((2,0)))
(2, 0)

sage: H((1,0)).order()
2
sage: H(vector((1,0))).order()
+Infinity

This is terrible, and a symptom of what Nathann wants to fix. It should be fixed.

  John

Volker Braun

unread,
Apr 28, 2014, 12:14:17 PM4/28/14
to sage-s...@googlegroups.com
Showing a deprecation warning for valid input isn't ideal ;-)

How about we deprecate all list/tuple input and force the user to use G.linear_combination_of_smith_form_gens / G.linear_combination_of_gens.

Nathann Cohen

unread,
Apr 28, 2014, 12:14:41 PM4/28/14
to Sage Support
Hello guys !

I just created ticket #16261 about this and uploaded my branch. It's
funny that to make all tests pass I only had to add four
"linear_combination_of_smith_form_gens"...

Now the problem is that I have no idea how to change .short_name()
(which is called by __repr__), as I have no idea how to get back the
signature of the abelian group. The one which is used by the elements
^^;

If anybody can help me there, or take a technical look at this patch.
I am afraid that I really know next to nothing about all the
math/programming involved there.

Nathann
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "sage-support" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/sage-support/yexpjig9BSg/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to

Nathann Cohen

unread,
Apr 28, 2014, 12:16:16 PM4/28/14
to Sage Support
> Showing a deprecation warning for valid input isn't ideal ;-)

Indeed, indeed. Right now it prints the following input, which I hope
will be taken seriously by those who should, and be ignored by those
who should :

sage: x = A([5]); x
doctest:1: DeprecationWarning: The default behaviour changed ! If you
*really* want a linear combination of smith generators, use
.linear_combination_of_smith_form_gens.
See http://trac.sagemath.org/16261 for details.

> How about we deprecate all list/tuple input and force the user to use
> G.linear_combination_of_smith_form_gens / G.linear_combination_of_gens.

Well... It's more proper, but it does look a bit too extreme... :-/

Nathann

Nathann Cohen

unread,
Apr 28, 2014, 12:29:04 PM4/28/14
to Sage Support
Ahahaah. While writing that code, I met an infinite loop. Apparently
testing if an element of a group is equal to +infinity calls
__repr__... :-P

Nathann

Nathann Cohen

unread,
Apr 28, 2014, 12:42:22 PM4/28/14
to Sage Support
The current branch passes all tests in groups/ and modules/fg_pid/ :-)

Needs review !

Nathann

Nils Bruin

unread,
Apr 28, 2014, 12:58:46 PM4/28/14
to sage-s...@googlegroups.com
On Monday, April 28, 2014 9:14:17 AM UTC-7, Volker Braun wrote:
Showing a deprecation warning for valid input isn't ideal ;-)

How about we deprecate all list/tuple input and force the user to use G.linear_combination_of_smith_form_gens / G.linear_combination_of_gens.

list input is actually an inverse to list output:

sage: G=AdditiveAbelianGroup([2,3])
sage: list(G.0)
[3]
sage: list(G.1)
[2]
sage: g.lift()
(1, 0)
sage: G.0.lift()
(1, 0)
sage: G.1.lift()
(0, 1)

Nathann Cohen

unread,
Apr 28, 2014, 2:38:03 PM4/28/14
to Sage Support
Hellooooo again !

This time the branch passes all long tests in src/ except one, and I need your advice. Here is the problem :

**********************************************************************
File "chain_complex.py", line 738, in sage.homology.chain_complex.ChainComplex_class.grading_group
Failed example:
    C = ChainComplex(grading_group=G, degree=G([1,2]))
Expected nothing
Got:

    doctest:1: DeprecationWarning: The default behaviour changed ! If you *really* want a linear combination of smith generators, use .linear_combination_of_smith_form_gens.
    See http://trac.sagemath.org/16261 for details.
**********************************************************************

1) The warning is not very meaningful as the user never called G.__call__ explicitly, and has no idea what the problem could  be
2) I cannot change the code of ChainComplex to call G(vector(x)) instead of G(x) as AdditiveAbelianGroup is not the only group that ChainComplex works on (and wrapping does not work for all groups)

Soooo, well... My way of doing things would be "let's consider that this G(x) has been broken all along, and because we are fixing a bug there is no need to display a warning at all".

On the other hand, Volker would prefer to have a ".linear_combination_of_gens()" function to  go with the current ".linear_combination_of_smith_form_gens()" so that we could say to all users "Don't use G(x), call one of the two .linear_combination* functions instead".

I do not like  this, because it feels like shooting at one's foot to stop using G(x) for one year just because it had a weird syntax before.

Aaaaaaaaand besides, having a new function like that would not solve the problem above with ChainComplex.

Well, what do you think guys ?

I pushed the branch in #16261 if you want to give it a try.

Nathann

Nathann Cohen

unread,
Apr 28, 2014, 2:44:47 PM4/28/14
to Sage Support
Turns out that I am an idiot, and that the warning is triggered by the "degree=G([1,2])" part of the expression I had overlooked. The branch now passes all tests, and is in needs_review.

The only thing that  needs to be discussed is this warning problem, and whether we should create a new function (or just add in the warning that the users should use G(vector(x)) instead of G(x), which removes the warning too).

Nathann
Reply all
Reply to author
Forward
0 new messages