Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-08-03 Thread Robert Miller
On Sun, Jul 25, 2010 at 6:50 PM, Robert Miller r...@rlmiller.org wrote:
 On Sun, Jul 25, 2010 at 8:10 PM, Carl Witty carl.wi...@gmail.com wrote:
 You seem to want to make the vertex dictionary respect the equivalence
 relation defined by Sage equality.  If so, you're going to be in
 trouble, since Sage equality actually is not an equivalence relation:

It gets worse:

sage: a = Set([1,2,3])
sage: b = Set([2,3,4])
sage: a  b
True
sage: b  a
False

sage: b  a
True
sage: a  b
False

Let's take a look at Sage's implementation of comparison:

sage: a.__cmp__??
...
if isinstance(other, Set_object_enumerated):
if self.set() == other.set():
return 0
return -1
else:
return Set_object.__cmp__(self, other)

Aduu! If it is not true that a == b, then a  b. Not good.

I would like to ask, since obviously nobody cares about doing
comparisons with Sage sets at the moment... We obviously need to
define what it means for a  b and a  b for Sage Sets. Does anyone
mind if we do this so that instead of  meaning subset, and getting a
bad ordering with respect to sorting lists, can we make  give a
lexicographic ordering? I will gladly do all the work, including
implementing an is_subset method.

That way, if you like working with sets themselves and you want  to
mean subset, simply use Python sets. Or if you are Chris Godsil, e.g.,
and like to be able to consistently sort sets because you use them as
vertices for graphs, use Sage Sets.

I think this is the best solution we can get to this problem...




-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-08-03 Thread William Stein
On Tue, Aug 3, 2010 at 10:33 AM, Robert Miller r...@rlmiller.org wrote:
 On Sun, Jul 25, 2010 at 6:50 PM, Robert Miller r...@rlmiller.org wrote:
 On Sun, Jul 25, 2010 at 8:10 PM, Carl Witty carl.wi...@gmail.com wrote:
 You seem to want to make the vertex dictionary respect the equivalence
 relation defined by Sage equality.  If so, you're going to be in
 trouble, since Sage equality actually is not an equivalence relation:

 It gets worse:

 sage: a = Set([1,2,3])
 sage: b = Set([2,3,4])
 sage: a  b
 True
 sage: b  a
 False

 sage: b  a
 True
 sage: a  b
 False

 Let's take a look at Sage's implementation of comparison:

 sage: a.__cmp__??
 ...
        if isinstance(other, Set_object_enumerated):
            if self.set() == other.set():
                return 0
            return -1
        else:
            return Set_object.__cmp__(self, other)

 Aduu! If it is not true that a == b, then a  b. Not good.

 I would like to ask, since obviously nobody cares about doing
 comparisons with Sage sets at the moment... We obviously need to
 define what it means for a  b and a  b for Sage Sets. Does anyone
 mind if we do this so that instead of  meaning subset, and getting a
 bad ordering with respect to sorting lists, can we make  give a
 lexicographic ordering? I will gladly do all the work, including
 implementing an is_subset method.

+1It makes no sense for  to mean subset because  should be a
total order.

If you want to check for subsets we should use a method like in python:

sage: a = set([1,2,3])
sage: b = set([2,3,4])
sage: a.issubset(b)
False
sage: b.issubset(a)
False
sage: a.issubset(b.union(a))
True

I don't like issubset as the method name, and would prefer
is_subset, personally.


 That way, if you like working with sets themselves and you want  to
 mean subset, simply use Python sets.

Yep.

  Or if you are Chris Godsil, e.g.,
 and like to be able to consistently sort sets because you use them as
 vertices for graphs, use Sage Sets.

 I think this is the best solution we can get to this problem...

William

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-08-03 Thread Robert Miller
On Tue, Aug 3, 2010 at 2:29 PM, William Stein wst...@gmail.com wrote:
 +1    It makes no sense for  to mean subset because  should be a
 total order.

 If you want to check for subsets we should use a method like in python:

 sage: a = set([1,2,3])
 sage: b = set([2,3,4])
 sage: a.issubset(b)
 False
 sage: b.issubset(a)
 False
 sage: a.issubset(b.union(a))
 True

 I don't like issubset as the method name, and would prefer
 is_subset, personally.

http://trac.sagemath.org/sage_trac/ticket/9677

needs a review...

-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-27 Thread Robert Miller
See trac #9610 for a patch which fixes this issue.



-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Robert Miller
Nathann,

Using the following instead fixes the problem:

g.add_edges( (Mod(i,n),Mod(i+j,n)) for i in range(n) for j in range(1,k+1) )

This is more consistent, since we are actually using the same vertex
objects. However, that should just work, right? Why doesn't it?

This is coming from the code around line 1000 of c_graph, which goes
from vertex labels to ints and back. The IntegerMod case was not in
mind when this code was written. The real problem is that when the
Python int 0 gets passed to get_vertex, it does not add the entry to
the translation dictionary. The idea being that it would be more
efficient for the majority of graphs, which only use [0, 1, ..., n-1]
as labels, going through dictionaries a bunch would be a waste.
However, when the IntegerMod 0 gets passed in, it does not find an
equal object in the dict, and since it is not one of {int, long,
Integer}, it assigns a new int in the translation dictionary for it.

So that's what's happening, what do people think about what we should
do about this? Technically the input is a bit fuzzy, but this raises
the question of how many other objects are there which will pass the
test int(0) == IntegerMod(0, 20)... I am very reluctant to support
adding all the labels to the dicts, unless someone can show that there
really isn't any overhead there...



-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Nathann Cohen
Hello !!!

 This is coming from the code around line 1000 of c_graph, which goes
 from vertex labels to ints and back. The IntegerMod case was not in
 mind when this code was written. The real problem is that when the
 Python int 0 gets passed to get_vertex, it does not add the entry to
 the translation dictionary. The idea being that it would be more
 efficient for the majority of graphs, which only use [0, 1, ..., n-1]
 as labels, going through dictionaries a bunch would be a waste.
 However, when the IntegerMod 0 gets passed in, it does not find an
 equal object in the dict, and since it is not one of {int, long,
 Integer}, it assigns a new int in the translation dictionary for it.

 So that's what's happening, what do people think about what we should
 do about this? Technically the input is a bit fuzzy, but this raises
 the question of how many other objects are there which will pass the
 test int(0) == IntegerMod(0, 20)... I am very reluctant to support
 adding all the labels to the dicts, unless someone can show that there
 really isn't any overhead there...

H.. I would not want to see any loss of performance because of
such matters either, I think we quite agree on this point..

I understood from your explanation why Mod(1,n) is considered
different from 0, and it is to me the correct behaviour... But what
about this

g has 21 vertices
len(g.vertices) == 20 ?

Sorry if you answered already ! :-)

Nathann

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Robert Miller
Nathann,

 I understood from your explanation why Mod(1,n) is considered
 different from 0, and it is to me the correct behaviour... But what
 about this

 g has 21 vertices
 len(g.vertices) == 20 ?

 Sorry if you answered already ! :-)

I think the information was there, but I was not very clear. It is
better if you just look at the code:

{{{
cdef int get_vertex(object u, dict vertex_ints, dict vertex_labels,
CGraph G) except ? -2:
if u in vertex_ints:
return vertex_ints[u]
if (not isinstance(u, (int, long, Integer)) or
u  0 or u = G.active_vertices.size or
u in vertex_labels):
return -1
return u
}}}

When int(0) is input, it returns 0. When Mod(0, 20) is input, however,
it returns -1, meaning that the object is not yet in the translation
dictionaries (since the second block only tests for three types of
integer). So when int(0) is input to check_vertex(), nothing gets
added to the dictionaries. However, when Mod(0, 20) is input, it does
add an entry to the dicts, and since 0 is already taken up (as defined
in a bitset of which ones are used), it gets a different int. This is
how we get two zeros in the vertex dicts.

It is not clear to me how to solve this problem. One could add
IntegerMod to the list of types to check, but that's a slippery
slope... One very silly option is to simply make the behavior of
adding Python ints and IntegerMods at the same time undefined, but
there *must* be a better fix...



-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Nathann Cohen
Nononon, I understood why there are two copies of what appears to
be a zero, and I think it's fine like that !
My question was about the number of vertices as remembered by the graph :

in one case, it says 21, but g.vertices() is only long of 20 elements.
Why aren't there two zeroes in g.vertices() ? I would expect to see
one 0, which is the integer, and one zero which is actually the member
of Z/20Z !

Sorry for this misunderstanding :-)

Nathann

On 25 July 2010 20:49, Robert Miller r...@rlmiller.org wrote:
 Nathann,

 I understood from your explanation why Mod(1,n) is considered
 different from 0, and it is to me the correct behaviour... But what
 about this

 g has 21 vertices
 len(g.vertices) == 20 ?

 Sorry if you answered already ! :-)

 I think the information was there, but I was not very clear. It is
 better if you just look at the code:

 {{{
 cdef int get_vertex(object u, dict vertex_ints, dict vertex_labels,
                    CGraph G) except ? -2:
    if u in vertex_ints:
        return vertex_ints[u]
    if (not isinstance(u, (int, long, Integer)) or
        u  0 or u = G.active_vertices.size or
        u in vertex_labels):
        return -1
    return u
 }}}

 When int(0) is input, it returns 0. When Mod(0, 20) is input, however,
 it returns -1, meaning that the object is not yet in the translation
 dictionaries (since the second block only tests for three types of
 integer). So when int(0) is input to check_vertex(), nothing gets
 added to the dictionaries. However, when Mod(0, 20) is input, it does
 add an entry to the dicts, and since 0 is already taken up (as defined
 in a bitset of which ones are used), it gets a different int. This is
 how we get two zeros in the vertex dicts.

 It is not clear to me how to solve this problem. One could add
 IntegerMod to the list of types to check, but that's a slippery
 slope... One very silly option is to simply make the behavior of
 adding Python ints and IntegerMods at the same time undefined, but
 there *must* be a better fix...



 --
 Robert L. Miller
 http://www.rlmiller.org/

 --
 To post to this group, send an email to sage-devel@googlegroups.com
 To unsubscribe from this group, send an email to 
 sage-devel+unsubscr...@googlegroups.com
 For more options, visit this group at 
 http://groups.google.com/group/sage-devel
 URL: http://www.sagemath.org


-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Robert Miller
On Sun, Jul 25, 2010 at 2:01 PM, Nathann Cohen nathann.co...@gmail.com wrote:
 Nononon, I understood why there are two copies of what appears to
 be a zero, and I think it's fine like that !

This is definitely *not* fine, since we have

sage: int(0) == Mod(0, 20)
True

As input, the underlying C graph ends up corrupted (see below for
details). Since they are equal, Sage's graphs should treat them as
equal and they do not. Bug.

To belabor the point for clarity:

When you call g.vertices(), it calls iterator_verts in c_graph.pyx:

{{{

cdef int i
cdef object v
if verts is None:
S = set(self.vertex_ints.iterkeys())
for i from 0 = i  (CGraphself._cg).active_vertices.size:
if (i not in self.vertex_labels and
bitset_in((CGraphself._cg).active_vertices, i)):
S.add(i)
return iter(S)

}}}

At this point we have:

{{{

active_vertices == 1000

vertex_ints == {0: 20, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8,
9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17,
18: 18, 19: 19}

vertex_labels == {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9:
9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18:
18, 19: 19, 20: 0}

}}}

Note that there are 21 bits in active_vertices, so C int 0 and C int
20 are both vertices according to that. That first zero in vertex_ints
is an IntegerMod, and the 20 it points to is a C int. Vice versa for
the 20: 0 entry in vertex_labels.

At first, the line {{{ S = set(self.vertex_ints.iterkeys()) }}}
creates a set of size twenty, containing twenty IntegerMod's, the set
{0, ..., 19}.

When i == 0 in the loop {{{ for i from 0 = i 
(CGraphself._cg).active_vertices.size }}}, the inner branch
discovers that 0 should be added to S, but since S is a set, and
Mod(0, 20) is already in there, adding int(0) to it does nothing.

So as I said before, the problem is created by line 1084 (in
sage-4.5/4.5.1) of c_graph.pyx, namely:

{{{ if (not isinstance(u, (int, long, Integer)) or }}}

In fact this should check for any Sage object X for which {{{
Integer(Y) == X }}} is true for any Y.

I hope this better illustrates the problem, and I hope I've convinced
you that int(0) and Mod(0, 20) should *not* be considered distinct by
Sage graphs.


 Sorry for this misunderstanding :-)

 Nathann


A: Stop apologizing!
B: I'm sorry!

-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Carl Witty
On Sun, Jul 25, 2010 at 10:27 AM, Robert Miller r...@rlmiller.org wrote:
 On Sun, Jul 25, 2010 at 2:01 PM, Nathann Cohen nathann.co...@gmail.com 
 wrote:
 Nononon, I understood why there are two copies of what appears to
 be a zero, and I think it's fine like that !

 This is definitely *not* fine, since we have

 sage: int(0) == Mod(0, 20)
 True

You seem to want to make the vertex dictionary respect the equivalence
relation defined by Sage equality.  If so, you're going to be in
trouble, since Sage equality actually is not an equivalence relation:

sage: 3 == Mod(7, 4)
True
sage: 3 == Mod(8, 5)
True
sage: Mod(7, 4) == Mod(8, 5)
False

This means that mixing Sage objects of different parents as elements
of a single set or keys of a single dictionary is asking for trouble;
in general, it cannot work (or at least we haven't figured out a way
to make it work).  (As long as you stick to a single parent you should
be fine.)

 So as I said before, the problem is created by line 1084 (in
 sage-4.5/4.5.1) of c_graph.pyx, namely:

 {{{ if (not isinstance(u, (int, long, Integer)) or }}}

 In fact this should check for any Sage object X for which {{{
 Integer(Y) == X }}} is true for any Y.

Sounds like what you want is u in ZZ, which is equivalent to u ==
ZZ(u) except that it returns False if ZZ(u) fails.

Carl

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org


Re: [sage-devel] Re: Scary things in Sage's Digraphs

2010-07-25 Thread Robert Miller
On Sun, Jul 25, 2010 at 8:10 PM, Carl Witty carl.wi...@gmail.com wrote:
 You seem to want to make the vertex dictionary respect the equivalence
 relation defined by Sage equality.  If so, you're going to be in
 trouble, since Sage equality actually is not an equivalence relation:

Is it really too much to ask?

It sounds like the proper thing to do here, then, is to adjust the
circulant graph constructor to use Mod(i) instead of i in the edge
additions, and then profusely document this issue -- perhaps a whole
chapter in the reference manual about graph gotchas... This is just
really unsatisfying. I like the idea of having graphs be free enough
that you can make anything you want a vertex.

A mathematician would not usually say that the integer is equal to the
coset. I can see why we might want

 sage: 3 == Mod(7, 4)
 True

But this highlights yet another place where mathematics and computer
science are less than perfect bedfellows. Just a day or two ago this
sort of thing was discovered in another thread. In short, Python sets
do not implement a total ordering (since  means inclusion), and so
are not sortable...

What to do, what to do?

Definition: Mod(n, m, parent=None)
Docstring:

   Return the equivalence class of n modulo m as an element of
   ZZ/mZZ.

According to this definition, I would expect

sage: Integer(7) == Mod(7,12)
False

Following the Python set notation, which I think is equally silly but
much harder to change, we would have

sage: Integer(7)  Mod(7,12)
True

..

-- 
Robert L. Miller
http://www.rlmiller.org/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org