[sage-devel] Re: coercing of sqrt(2)
On Jun 6, 2008, at 10:00 AM, John Cremona wrote: 2008/6/6 Nick Alexander [EMAIL PROTECTED]: This thread got slightly off topic to the original question though: where should sqrt(2) belong? Z[sqrt(2)], SR, or somewhere else? I always want my data to start as close to the initial object as possible. In this case, Z[sqrt(2)] \into SR and not vice versa -- so sqrt(2) should be in Z[sqrt(2)]. Nick I agree: for exactly the same reason that I expect 2 to be in ZZ and not in SR! What about sqrt(8)? Would you put that in the maximal order Z[sqrt(2)] or in its own order Z[sqrt(8)]? I would recommenfd the former, otherwise every time you type sqrt(n) for some integer n then you would be forcing the factorization of n (on the grounds that there is no known algorithm for finding the square-free part of an integer which is faster than factorization). Similarly for other algebraic integers alpha (at least those which have a symbolic definition like sqrt(n)). What about sqrt(1/2)? (or anyother non-integral algebraic number)? This does not belong to any finitely-generated ring (I mean f.g. as Z-module of course) so I would put it straight into the field Q(sqrt(2)). Yes, this is what I was thinking to--I think I've mentioned it before, but I think there should be a coercion parent(a) - parent (sqrt(a)). - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 5, 2008, at 3:39 PM, Carl Witty wrote: On Jun 5, 12:37 pm, Bill Page [EMAIL PROTECTED] wrote: The point I am making is that Python already has everything you need to implement the concept of the parent of an element as a type, i.e. directly as an instance of the class that creates it. This could result in considerable simplification compared to the current situation. Right now a Sage user has to deal with three separate type-related concepts: type (Python class), parent (an object in some category) and category. Metaclasses are a good match for Categories. Thus you can have everything in one package and remain closer to conventional Python programming in spirit. OK, I'm convinced that unifying parents and types is elegant and works very well in Aldor, and that it's possible in Python. However, I don't think it's a good idea for Sage, because of pragmatic limitations due to Python/Cython. These points were all made by other people in this thread, but I'm combining them into one convenient list here for debating purposes. 1. Creating classes at run-time in Python is slow and memory-hungry; the more methods you add to the class, the slower and more memory- hungry it gets. 2. Creating classes at run-time in Cython is impossible. If Cython was extended to support creating classes at run-time (which it may be, at some point, since there are Cython developers who want it to compile the entire Python language) there would need to be significant language extensions (and corresponding compiler extensions) to let these run-time be classes be as fast as the former compile-time classes. 3. While it is possible in Python to add methods to types, these methods are inherited by values of that type. Currently, we have methods on parents that are not inherited by methods on the values; we don't want to lose that. Here are some other points that were made, but seem to me less important than the above: 4. Currently, if P is a parent and T is a type, P(...) and T(...) both have meanings which are not the same. If we merged parents and types, we would have to leave the function-call syntax for constructors, and come up with a new syntax for conversion (coercion). This would be annoying and non-backward-compatible, but is not a fatal flaw. 5. People have mentioned that we have cases where values of the same type can have different parents, like IntegerMod_int which is the implementation for both GF(7) and Integers(7). This particular case is not a problem at all... we could just have GF(7) inherit from Integers(7). 6. People have mentioned that we have cases where values of different types share the same parent, such as symbolic constants and symbolic expressions both being in the symbolic ring. This may sometimes not be a problem; for instance, parent(x)==SR could be replaced by isinstance(x, SR), even though type(x)==SR would not work. In summary, I think we could unify parents and types with a large amount of work and a significant performance loss; or with a very large amount of work (including a lot of work on Cython) and a minor performance loss. In either case, we would have a functionality loss (the ability to put methods on parents that are not inherited by values). I don't think it's worth it. I think that sums it up well (though personally I think types and parents are distinct enough concepts that keeping them separate is a good idea anyways). On (2), creating classes at runtime will certainly be supported, that's how normal classes are done now, but creating cdef classes at runtime without invoking gcc (or some other sort of compiler) at runtime is perhaps not even possible. For (6) we do a lot of parent(x) is SR, especially in the fast paths of the coercion model (due to caching, parents are usually unique, and if not we follow it up by the (relatively expensive) ==, so even with a very large amount of work, that would still slow things down. This thread got slightly off topic to the original question though: where should sqrt(2) belong? Z[sqrt(2)], SR, or somewhere else? - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
This thread got slightly off topic to the original question though: where should sqrt(2) belong? Z[sqrt(2)], SR, or somewhere else? I always want my data to start as close to the initial object as possible. In this case, Z[sqrt(2)] \into SR and not vice versa -- so sqrt(2) should be in Z[sqrt(2)]. Nick --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 6:39 PM, Carl Witty wrote: OK, I'm convinced that unifying parents and types is elegant and works very well in Aldor, and that it's possible in Python. However, I don't think it's a good idea for Sage, because of pragmatic limitations due to Python/Cython. These points were all made by other people in this thread, but I'm combining them into one convenient list here for debating purposes. Thanks for summarizing the arguments against unifying parents and types in Sage. As I stated near the start of this thread, it was not my intention to recommend that Sage actually take this approach. Sage is 3.0 and the current approach is established and working well for the end user. My regret however is that it seems to make new development in Sage more complicated, with a steeper learning curve for new developers than it really needs to be. On Thu, Jun 5, 2008 at 9:09 PM, Gonzalo Tornaria [EMAIL PROTECTED] wrote: On Thu, Jun 5, 2008 at 1:18 PM, William Stein wrote: OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. On 6/5/08, Bill Page [EMAIL PROTECTED] wrote: Do you still consider the example code like that given above by Gonzalo unnatural and ugly? It seems like pretty standard Python to me. There of course various ways of packaging the metaclass machinery to provide an even cleaner user interface. I do think my code (as posted) is unnatural and ugly. Just an example, not even a class. I'd really love to figure out a proper model of parent-element relationship using metaclasses, etc. It seems to me that the parent-element relationship is already there. It is inherent in the Python concept of an instance of a class. In this model classes *are* parents. Instances are elements. Your example code presents a function that generates classes based on a parameter - a standard class factory. As you say, what might be more interesting is a class that behaves like a category, i.e. whose instances themselves are classes. Python's type module is an example of such a metaclass. I think this is all very well and concisely described here: http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html A Primer on Python Metaclass Programming by David Mertz I tried very hard (several times) to find such a model, or at least a cleaner user interface, and I played with some interesting ideas but cooked no cake. Maybe you have some cool ideas on how one can make this work (and appealing to others). Have you looked at the 'type' class? I think that is pretty cool. category) and category. Metaclasses are a good match for Categories. Also cool. I remember I was hit by the python version of a few of the paradoxes in early days set theory. YMMV. I don't think you should let apparent paradoxes in set theory worry you. OpenAxiom for example has a domain called Domain. Domain is an instance of Domain so we can write: x:Domain:=Domain and the world does not end.. And would I really would like to get as much mileage as possible from native Python constructions. In the Axiom world we have a bit of a problem: Unlike Axiom itself, the new generation Axiom library compiler - Aldor - is not free (although just last year it finally became at least semi-open). In my opinion, to progress rapidly and as intended when Axiom was still a commercial product Axiom badly needs Aldor. The existing compiler in Axiom - SPAD - is significantly harder to use and to extend (although Gabriel Dos Reis has started to do some wonderful new things with it in the OpenAxiom fork of the original open source Axiom project.). I think this is one of the main reasons why Axiom has had a relatively difficult time attracting new uses and developers. Even Aldor however is already a rather old language. There has been a lot of progress in programming language design since the mid 1990's. Python is one result. It seems to me that Python has many of the attributes of the kind of language that the Axiom developers were trying to achieve. This is one of the primary reasons why I was interested in the Sage project in the first place. Sage is not Axiom, but it is (more or less) based on Magma and Magma has at least some of the features that I think make Axiom rather special as a computer algebra system. So like several other people before me, e.g. the developers of Sage and the developers of SymPy, I am now thinking quite seriously about how much of the Axiom design could actually be accommodated in Python. Implementing domains and categories as Python classes is an essential part of that strategy. Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at
[sage-devel] Re: coercing of sqrt(2)
2008/6/6 Nick Alexander [EMAIL PROTECTED]: This thread got slightly off topic to the original question though: where should sqrt(2) belong? Z[sqrt(2)], SR, or somewhere else? I always want my data to start as close to the initial object as possible. In this case, Z[sqrt(2)] \into SR and not vice versa -- so sqrt(2) should be in Z[sqrt(2)]. Nick I agree: for exactly the same reason that I expect 2 to be in ZZ and not in SR! What about sqrt(8)? Would you put that in the maximal order Z[sqrt(2)] or in its own order Z[sqrt(8)]? I would recommenfd the former, otherwise every time you type sqrt(n) for some integer n then you would be forcing the factorization of n (on the grounds that there is no known algorithm for finding the square-free part of an integer which is faster than factorization). Similarly for other algebraic integers alpha (at least those which have a symbolic definition like sqrt(n)). What about sqrt(1/2)? (or anyother non-integral algebraic number)? This does not belong to any finitely-generated ring (I mean f.g. as Z-module of course) so I would put it straight into the field Q(sqrt(2)). John --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 4, 2008, at 7:35 PM, Bill Page wrote: On Wed, Jun 4, 2008 at 1:54 PM, Robert Bradshaw wrote: On Jun 4, 2008, at 4:07 AM, Bill Page wrote: ... These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. So is this essentially an admission that the concept of 'parent' is superfluous and could have in fact been implemented just at Python 'type'? Not at all. It is the realization that not all Python objects will have a Parent (e.g. the builtin objects, objects from other libraries, Sage Parents, etc.) but they will have a type, which is a much weaker notion but can be reasoned with a bit (e.g. the builtin Python 'int' type coerces nicely into the IntegerRing). I am not sure that I would actually advocate this now, but for argument's sake: Why not do it this way all of the time? Python classes all end up as (potential) parents. Types are all about the implementations of things, they synonymous with the classes of Object Oriented programming, and are insufficient (and the wrong vehicle) to carry deeper mathematical structure. For example, an element of Z/5Z and an element of Z/7Z have the same type (i.e. they're instances of the same class, with the same methods, internal representation, etc), but not the same parent (which is data). I think that this more or less is what at least some Magma developers had in mind. E.g. We read in the preface to the Magma HTML Help Document: http://magma.maths.usyd.edu.au/magma/htmlhelp/preface.htm Every object created during the course of a computation is associated with a unique parent algebraic structure. The type of an object is then simply its parent structure. William Stein adequately addressed this point. ... One should think of the type of an object as what specifies its implementation (including its internal representation). In this sense it is like a class in Java, C++, or any other programming language. (In Python there is a subtle (and mostly historical) difference between types and classes depending on whether or not it's written in C, but for the most part they can be used interchangeably). Python has multiple inheritance, but Cython does not (the C format of a compiled Python class is a C struct, so this is not so much a Cython limitation as a Python/C API limitation.) The lack of multiple inheritance in Cython seems to be a major design obstacle. Although a C struct is not a real class, it is not clear to me why this is not adequate in compiled code. Wouldn't it be sufficient to merge (flatten) the components of the multiple ancesters into one struct? If not (e.g. if it is necessary to retain some knowledge of their origins), why not provide nested structs? But I suppose that this is quite off-topic... The exact details of why this isn't as easy as it seems are quite technical, and off-topic. The short answer is that with a major re- design of Cython multiple inheritance could be supported at the cost of an extra indirection (even on non-multiply inherited types) on ever C member/method lookup. (This is done in C++, but it would be even more complicated to deal with the way Python handles extension types). One of the primary reasons for Cython is speed, which is not worth sacrificing for this feature. Most of the time there is a 1-to-1 correspondence between Parents and the types of its Elements. For example, and element of the Parent RR (= RealField(53) is represented by sage.rings.real_mpfr.RealNumber. If I do RR(3) I get back an object of type sage.rings.real_mpfr.RealNumber representing the floating point number 3 to 53 bits of precision, and it's Parent is RR. RealField (100) is a new Parent, whose elements are again of type sage.rings.real_mpfr.RealNumber but to 100 bits of precision. Sometimes, however, the same type is used for multiple parents. There are several integer mod types (depending on whether or not the modulus fits in a single word) and they are used for both generic Z/nZ and prime-order finite fields. Thus we have sage: [type(mod(-1, 100^k)) for k in [2..5]] [type 'sage.rings.integer_mod.IntegerMod_int', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_gmp'] sage: [parent(mod(-1, 100^k)) for k in [2..5]] [Ring of integers modulo 1, Ring of integers modulo 100, Ring of integers modulo
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 1:47 AM, William Stein wrote: On Wed, Jun 4, 2008 at 10:16 PM, Bill Page wrote: ... Python classes can also take parameters. I didn't know that. I thought the only way to create a Python class is for the Python interpreter to execute Python code that looks like this: class Foo(...): ... That makes a new class called Foo. How are you going to make, at runtime, new classes for each of Z/nZ say, for 1 = n 10^5, i.e., something like this in Sage: v = [Integers(n) for n in range(1,10^5)] I do not think it is possible to concisely create a hundred thousand separate Python classes like that. See Python MetaClasses. E.g. http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html sage: X = type('X', (object,), dict(a=1)) sage: x=X() sage: x.a 1 Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 12:23 PM, Gonzalo Tornaria wrote: On Thu, Jun 5, 2008 at 1:47 AM, William Stein wrote: ... How are you going to make, at runtime, new classes for each of Z/nZ say, for 1 = n 10^5, i.e., something like this in Sage: v = [Integers(n) for n in range(1,10^5)] I do not think it is possible to concisely create a hundred thousand separate Python classes like that. ... WRT your example: sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) 3 mod 5 sage: time v = [classinteger(n) for n in range(1,10^5)] CPU time: 3.64 s, Wall time: 4.14 s sage: time w = [Integers(n) for n in range(1,10^5)] CPU time: 15.75 s, Wall time: 16.21 s sage: v[1256](34251235) 499 mod 1257 ... Excellent example. Thank you! I was going to say that using classes built at runtime like this was fine but not a good option for performance reasons, but the example above shows the overhead of python class creation time is not so significant. Agreed. Python can treat types as fully first class objects. I think this strongly supports William's initial decision to choose Python as the basis for a new computer algebra system comparable to Magma and Axiom. Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
Python classes can also take parameters. I didn't know that. I thought the only way to create a Python class is for the Python interpreter to execute Python code that looks like this: class Foo(...): ... That makes a new class called Foo. How are you going to make, at runtime, new classes for each of Z/nZ say, for 1 = n 10^5, i.e., something like this in Sage: v = [Integers(n) for n in range(1,10^5)] I do not think it is possible to concisely create a hundred thousand separate Python classes like that. FWIW, I think classes in python are just instances of class classobj. This latter class classobj (from new import classobj) is what implements the semantics of python's new-style classes. Also classes can be constructed at runtime, as instances of class classobj. Moreover, one can also subclass classobj or type to produce metaclasses with different semantics (or whatever). Search for python metaclass, e.g. http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html WRT your example: sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) 3 mod 5 sage: time v = [classinteger(n) for n in range(1,10^5)] CPU time: 3.64 s, Wall time: 4.14 s sage: time w = [Integers(n) for n in range(1,10^5)] CPU time: 15.75 s, Wall time: 16.21 s sage: v[1256](34251235) 499 mod 1257 sage: w[1256](34251235) 499 Note that classinteger(n) is an instance of class 'classobj' in this simple example. sage: type(classinteger(n)) type 'classobj' sage: classinteger(7) class __main__.classintegers mod 7 at 0x3697770 But one could define a metaclass so this class works fine as a first-class object (e.g. it prints nicely, can define members acting on the class itself, etc): I was going to say that using classes built at runtime like this was fine but not a good option for performance reasons, but the example above shows the overhead of python class creation time is not so significant. I guess the part of creating a class which will take time is the creation of the dictionary; but then one could have the dictionary pre-loaded somehow. If, on the other hand, one doesn't care about parent creation time but worries about element operation time, it might be possible to, at class creation time, compile the class in cython so that e.g. the modulus is a hard-coded compile constant... (don't know if this is of any advantage, it is just for the sake of an example). Best, Gonzalo --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 9:23 AM, Gonzalo Tornaria [EMAIL PROTECTED] wrote: Python classes can also take parameters. I didn't know that. I thought the only way to create a Python class is for the Python interpreter to execute Python code that looks like this: class Foo(...): ... That makes a new class called Foo. How are you going to make, at runtime, new classes for each of Z/nZ say, for 1 = n 10^5, i.e., something like this in Sage: v = [Integers(n) for n in range(1,10^5)] I do not think it is possible to concisely create a hundred thousand separate Python classes like that. FWIW, I think classes in python are just instances of class classobj. This latter class classobj (from new import classobj) is what implements the semantics of python's new-style classes. Also classes can be constructed at runtime, as instances of class classobj. Moreover, one can also subclass classobj or type to produce metaclasses with different semantics (or whatever). Search for python metaclass, e.g. http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html WRT your example: sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) 3 mod 5 sage: time v = [classinteger(n) for n in range(1,10^5)] CPU time: 3.64 s, Wall time: 4.14 s sage: time w = [Integers(n) for n in range(1,10^5)] CPU time: 15.75 s, Wall time: 16.21 s sage: v[1256](34251235) 499 mod 1257 sage: w[1256](34251235) 499 Note that classinteger(n) is an instance of class 'classobj' in this simple example. sage: type(classinteger(n)) type 'classobj' sage: classinteger(7) class __main__.classintegers mod 7 at 0x3697770 But one could define a metaclass so this class works fine as a first-class object (e.g. it prints nicely, can define members acting on the class itself, etc): Cool. I stand corrected. I'm glad this is fully supported in Python, at least for new style classes. OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. I was going to say that using classes built at runtime like this was fine but not a good option for performance reasons, but the example above shows the overhead of python class creation time is not so significant. It is very impressive how fast Python classobj is, but it is still an order of magnitude slower than object instantiation, though your flawed benchmark incorrectly suggests the opposite. Two points: (1) It makes no sense to compare with Integers(n), which is doing all kinds of other things (it could for all we know for now be factoring n), etc. You should compare with a minimal class MyIntegers. Creating Python class instances can be massively optimized by doing the class creation in Cython, like we do in integer.pyx. (2) It is important to consider the performance implications if the class you're constructing has lots of methods.I tried the above benchmark but with 8 trivial methods added to the class, and it took 5 times as long to run! Of course, this could easily be mitigated with inheritance, but is worth pointing out. Also, every single classobj takes *memory* for all methods that are special for it. Again inheritance could mitigate this problem. Here's an example benchmark but using MyIntegers instead of Integer. In it, creating a class takes four times as long as instantiating an instance: {{{id=54| def classinteger(m): class A: def __init__(self, n): self.__n = n % m def __repr__(self): return %d mod %d % (self.__n, m) A.__name__ = classintegers mod %d % m return A /// }}} {{{id=57| class MyIntegers: def __init__(self, m): self.__m = m /// }}} {{{id=55| time v = [classinteger(n) for n in range(1,10^5)] /// CPU time: 2.89 s, Wall time: 2.98 s }}} {{{id=53| time w = [MyIntegers(n) for n in range(1,10^5)] /// CPU time: 0.63 s, Wall time: 0.63 s }}} {{{id=52| 2.89 / 0.63 /// 4.58730158730159 }}} --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 1:18 PM, William Stein wrote: ... On Thu, Jun 5, 2008 at 12:23 PM, Gonzalo Tornaria wrote: ... sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) ... OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. Do you still consider the example code like that given above by Gonzalo unnatural and ugly? It seems like pretty standard Python to me. There of course various ways of packaging the metaclass machinery to provide an even cleaner user interface. The point I am making is that Python already has everything you need to implement the concept of the parent of an element as a type, i.e. directly as an instance of the class that creates it. This could result in considerable simplification compared to the current situation. Right now a Sage user has to deal with three separate type-related concepts: type (Python class), parent (an object in some category) and category. Metaclasses are a good match for Categories. Thus you can have everything in one package and remain closer to conventional Python programming in spirit. Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) ... OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. Do you still consider the example code like that given above by Gonzalo unnatural and ugly? It seems like pretty standard Python to me. There of course various ways of packaging the metaclass machinery to provide an even cleaner user interface. To me, that feels much more unnatural and ugly than the current situation. Perhaps that's just because I'm used to things the way they are currently. The point I am making is that Python already has everything you need to implement the concept of the parent of an element as a type, i.e. directly as an instance of the class that creates it. This could result in considerable simplification compared to the current situation. Right now a Sage user has to deal with three separate type-related concepts: type (Python class), parent (an object in some category) and category. Metaclasses are a good match for Categories. Thus you can have everything in one package and remain closer to conventional Python programming in spirit. For me, a class represents an implementation / model of a mathematical object whether it be a multivariate polynomial or a multivariate polynomial ring. I don't see why one would want to tie the implementation of the parent structure together with that of its elements. In your setup, I'm still not sure where place things like .multiplicative_generators(). Sure, you could make it a class method so that you don't need an instance to access it, but then all of that class's instance have that method which was not the intention. --Mike --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 5, 2008, at 12:37 PM, Bill Page wrote: On Thu, Jun 5, 2008 at 1:18 PM, William Stein wrote: ... On Thu, Jun 5, 2008 at 12:23 PM, Gonzalo Tornaria wrote: ... sage: def classinteger(m): ... class A: ... def __init__(self, n): ... self.__n = n % m ... def __repr__(self): ... return %d mod %d % (self.__n, m) ... A.__name__ = classintegers mod %d % m ... return A sage: classinteger(5)(3) ... OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. Do you still consider the example code like that given above by Gonzalo unnatural and ugly? It seems like pretty standard Python to me. There of course various ways of packaging the metaclass machinery to provide an even cleaner user interface. The point I am making is that Python already has everything you need to implement the concept of the parent of an element as a type, i.e. directly as an instance of the class that creates it. This could result in considerable simplification compared to the current situation. Right now a Sage user has to deal with three separate type-related concepts: type (Python class), parent (an object in some category) and category. Metaclasses are a good match for Categories. Thus you can have everything in one package and remain closer to conventional Python programming in spirit. Parents are much, much more than types, and I see little to gain by trying to unify the two. To me, Python class and object in some category are very different concepts. There are, however, many drawbacks. First, there is far from a one- two-one correspondence between types an parents. Some parents have elements of varying type, and some types are used for a variety of parents. Though metaclasses can be used to mitigate this somewhat, I think it would add much more complexity than it would remove. Also, the __call__ method often does much more than just construct a new object. It would also introduce enormous performance overhead--the cost of calling classinteger above increases linearly with the number of methods the class has. Perhaps this could be limited by pre-creating the methods and adding them to the dict all at once, but but this would be even more unnatural. More importantly, this would mean that cdef'd (Cython) elements/parents are out. (Well, one could generate a cython file at run time, compile it, load the .so and then use that dynamically generated type, but that would be so insanely slow). Is this a deficiency of cdef'd types? Yes. But this is what makes them so fast--members and methods can be statically resolved at compile time. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 4:16 AM, Robert Bradshaw wrote: On Jun 4, 2008, at 7:35 PM, Bill Page wrote: ... Types are all about the implementations of things, they synonymous with the classes of Object Oriented programming, and are insufficient (and the wrong vehicle) to carry deeper mathematical structure. That is precisely the claim that I am trying to dispute. Axiom for example specifically takes the point of view that mathematical structure should be implemented as types in a sufficiently rich programming language, i.e. one where types are first order objects. I think that Axiom (and later the programming language Aldor that was originally implemented as the next generation library compiler for Axiom) has demonstrated that this view is viable. For example, an element of Z/5Z and an element of Z/7Z have the same type (i.e. they're instances of the same class, with the same methods, internal representation, etc), but not the same parent (which is data). I think Gonsalo Tornaria in this thread has demonstrated that this need not be the case. ... SymbolicRing is another thing that worries me a little. Exactly what (mathematically) is a symbolic ring? E.g. Why is it a ring and not a field? Operations like 'sin(sin(sin(x))).parent()' doesn't look much like a ring to me. Probably most other computer algebra systems would just call this an expression tree or AST or something like that. Most symbolic systems (Magma and Axiom excluded) have very little notion of algebras, rings, modules, etc.--virtually everything is an expression or list of expressions. SymbolicRing is a way to fit these abstract expression trees into a larger framework of Sage. It not only keeps engineers and calculus students happy, it keeps me happy when just want to sit down and solve for x or compute a symbolic integral. It's also a statement that rigor should not get in the way of usability (an important component of being a viable alternative to the M's). It seems to me that symbolic computation need not lack rigor. And in a computer algebra system rigor should not compromise usability. These are design challenges that we face. This is one of the things that strongly-typed systems like Axiom and Magma (and now Sage) offer over these other systems. ... To the best of my knowledge, the formal concept of representation in a computer algebra systems is unique to Axiom. Each domain has a specified 'Rep'consisting of some domain expression. E.g. Rep == Integer or Rep == Union(Record(car:%, cdr:%), nil) % stands for this domain, so this definition amounts to some recursive structure. Of course recursively defined classes are also possible in Python but they require much more discipline on the part of the programmer. Now there are two operators 'rep' and 'per' that provide coercion to and from Rep. So we might say for example that some operation * in this domain is implemented by * from Rep: x * y == per( rep(x) * rep(y) ) The trouble is: I don't see anything here that could be called a parent. Or perhaps, they are all parents except for those initial domains for which we never explicitly specify a Rep. Nope, nothing I see here could reasonably be called a Parent. Is there an object that formally represents the ring of integers that one could pass to a function? Sure. For example in OpenAxiom one can write: (1) - Integer has Ring (1) true Type: Boolean (2) - Pick(x,A,B)==if x=0 then A else B Type: Void (3) - i:=1 (3) 1 Type: PositiveInteger (4) - n:Pick(i,Integer,Float):=1 Compiling function Pick with type (PositiveInteger,Domain,Domain) - Domain (4) 1.0 Type: Float And of course even easier in Sage :-) sage: category(IntegerRing()) Category of rings sage: def Pick(x,A,B): if x==0: return A else: return B : sage: i=1 sage: n=Pick(i,IntegerRing(),RealField())(1) sage: n; parent(n) 1.00 Real Field with 53 bits of precision ... One of the changes in this latest coercion push is to allow Parents to belong to several categories. That sounds good. So does this mean that the 'category' method now returns a list? There are two methods, category (returning the first cat in the list) and categories (returning the whole list). The set of categories is an ordered list, and things are attempted in the first category (and its supercategories) before moving on to the next. Most objects, of course, will belong to one category (not including its super categories). Here is something to consider: Instead of having two methods, one that return a list, you could implement some operations on categories that yield new categories. One such operation (because the categories form a lattice) might be 'Join'. Then if a
[sage-devel] Re: coercing of sqrt(2)
On Jun 5, 2008, at 1:36 PM, Bill Page wrote: On Thu, Jun 5, 2008 at 4:16 AM, Robert Bradshaw wrote: On Jun 4, 2008, at 7:35 PM, Bill Page wrote: ... Types are all about the implementations of things, they synonymous with the classes of Object Oriented programming, and are insufficient (and the wrong vehicle) to carry deeper mathematical structure. That is precisely the claim that I am trying to dispute. Axiom for example specifically takes the point of view that mathematical structure should be implemented as types in a sufficiently rich programming language, i.e. one where types are first order objects. I think that Axiom (and later the programming language Aldor that was originally implemented as the next generation library compiler for Axiom) has demonstrated that this view is viable. Perhaps Sage is demonstrating that not taking this view is viable too :-). For example, an element of Z/5Z and an element of Z/7Z have the same type (i.e. they're instances of the same class, with the same methods, internal representation, etc), but not the same parent (which is data). I think Gonsalo Tornaria in this thread has demonstrated that this need not be the case. By making elements of Z/5Z and Z/7Z be instances of different (dynamically generated) classes. This has drawbacks too, also mentioned in this thread. Personally, I find it conceptually easier to think of Z/5Z and Z/7Z as distinct instances of the same class. ... SymbolicRing is another thing that worries me a little. Exactly what (mathematically) is a symbolic ring? E.g. Why is it a ring and not a field? Operations like 'sin(sin(sin(x))).parent()' doesn't look much like a ring to me. Probably most other computer algebra systems would just call this an expression tree or AST or something like that. Most symbolic systems (Magma and Axiom excluded) have very little notion of algebras, rings, modules, etc.--virtually everything is an expression or list of expressions. SymbolicRing is a way to fit these abstract expression trees into a larger framework of Sage. It not only keeps engineers and calculus students happy, it keeps me happy when just want to sit down and solve for x or compute a symbolic integral. It's also a statement that rigor should not get in the way of usability (an important component of being a viable alternative to the M's). It seems to me that symbolic computation need not lack rigor. And in a computer algebra system rigor should not compromise usability. These are design challenges that we face. This is one of the things that strongly-typed systems like Axiom and Magma (and now Sage) offer over these other systems. Yes, I'm not trying to throw away rigor. I'm just saying it's a place where I can write a+b without having to think about what the + really means, it's just formal. Perhaps it could equally be called SetOfUnevaluatedExpressions but that's a bit verbose. ... To the best of my knowledge, the formal concept of representation in a computer algebra systems is unique to Axiom. Each domain has a specified 'Rep'consisting of some domain expression. E.g. Rep == Integer or Rep == Union(Record(car:%, cdr:%), nil) % stands for this domain, so this definition amounts to some recursive structure. Of course recursively defined classes are also possible in Python but they require much more discipline on the part of the programmer. Now there are two operators 'rep' and 'per' that provide coercion to and from Rep. So we might say for example that some operation * in this domain is implemented by * from Rep: x * y == per( rep(x) * rep(y) ) The trouble is: I don't see anything here that could be called a parent. Or perhaps, they are all parents except for those initial domains for which we never explicitly specify a Rep. Nope, nothing I see here could reasonably be called a Parent. Is there an object that formally represents the ring of integers that one could pass to a function? Sure. For example in OpenAxiom one can write: (1) - Integer has Ring (1) true Type: Boolean (2) - Pick(x,A,B)==if x=0 then A else B Type: Void (3) - i:=1 (3) 1 Type: PositiveInteger (4) - n:Pick(i,Integer,Float):=1 Compiling function Pick with type (PositiveInteger,Domain,Domain) - Domain (4) 1.0 Type: Float And of course even easier in Sage :-) sage: category(IntegerRing()) Category of rings sage: def Pick(x,A,B): if x==0: return A else: return B : sage: i=1 sage: n=Pick(i,IntegerRing(),RealField())(1) sage: n; parent(n) 1.00 Real Field with 53 bits of precision Your Integer object also stands for the ring of Integers. So can you do stuff like sage:
[sage-devel] Re: coercing of sqrt(2)
On Thu, Jun 5, 2008 at 5:19 PM, Robert Bradshaw wrote: Your Integer object also stands for the ring of Integers. So can you do stuff like sage: ZZ.is_commutative() True sage: ZZ.krull_dimension() 1 sage: ZZ.is_finite() False (1) - Integer has Finite (1) false Type: Boolean (2) - Integer has CommutativeRing (2) true Type: Boolean (3) - characteristic()$Integer (3) 0 Type: NonNegativeInteger Finite and CommutativeRing are categories. characteristic is a method of Integer. Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 5, 12:37 pm, Bill Page [EMAIL PROTECTED] wrote: The point I am making is that Python already has everything you need to implement the concept of the parent of an element as a type, i.e. directly as an instance of the class that creates it. This could result in considerable simplification compared to the current situation. Right now a Sage user has to deal with three separate type-related concepts: type (Python class), parent (an object in some category) and category. Metaclasses are a good match for Categories. Thus you can have everything in one package and remain closer to conventional Python programming in spirit. OK, I'm convinced that unifying parents and types is elegant and works very well in Aldor, and that it's possible in Python. However, I don't think it's a good idea for Sage, because of pragmatic limitations due to Python/Cython. These points were all made by other people in this thread, but I'm combining them into one convenient list here for debating purposes. 1. Creating classes at run-time in Python is slow and memory-hungry; the more methods you add to the class, the slower and more memory- hungry it gets. 2. Creating classes at run-time in Cython is impossible. If Cython was extended to support creating classes at run-time (which it may be, at some point, since there are Cython developers who want it to compile the entire Python language) there would need to be significant language extensions (and corresponding compiler extensions) to let these run-time be classes be as fast as the former compile-time classes. 3. While it is possible in Python to add methods to types, these methods are inherited by values of that type. Currently, we have methods on parents that are not inherited by methods on the values; we don't want to lose that. Here are some other points that were made, but seem to me less important than the above: 4. Currently, if P is a parent and T is a type, P(...) and T(...) both have meanings which are not the same. If we merged parents and types, we would have to leave the function-call syntax for constructors, and come up with a new syntax for conversion (coercion). This would be annoying and non-backward-compatible, but is not a fatal flaw. 5. People have mentioned that we have cases where values of the same type can have different parents, like IntegerMod_int which is the implementation for both GF(7) and Integers(7). This particular case is not a problem at all... we could just have GF(7) inherit from Integers(7). 6. People have mentioned that we have cases where values of different types share the same parent, such as symbolic constants and symbolic expressions both being in the symbolic ring. This may sometimes not be a problem; for instance, parent(x)==SR could be replaced by isinstance(x, SR), even though type(x)==SR would not work. In summary, I think we could unify parents and types with a large amount of work and a significant performance loss; or with a very large amount of work (including a lot of work on Cython) and a minor performance loss. In either case, we would have a functionality loss (the ability to put methods on parents that are not inherited by values). I don't think it's worth it. Carl --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On 6/5/08, Bill Page [EMAIL PROTECTED] wrote: On Thu, Jun 5, 2008 at 1:18 PM, William Stein wrote: OK, I have to come clean and admit that already actually knew all about metaclasses, but considered using them this way so unnatural and ugly that I would not recommend it. Do you still consider the example code like that given above by Gonzalo unnatural and ugly? It seems like pretty standard Python to me. There of course various ways of packaging the metaclass machinery to provide an even cleaner user interface. I do think my code (as posted) is unnatural and ugly. Just an example, not even a class. I'd really love to figure out a proper model of parent-element relationship using metaclasses, etc. I tried very hard (several times) to find such a model, or at least a cleaner user interface, and I played with some interesting ideas but cooked no cake. Maybe you have some cool ideas on how one can make this work (and appealing to others). category) and category. Metaclasses are a good match for Categories. Also cool. I remember I was hit by the python version of a few of the paradoxes in early days set thery. YMMV. Best, Gonzalo --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
2008/6/4 Robert Bradshaw [EMAIL PROTECTED]: But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) Robert, Can you be more specific about how others can help with this? John --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
Robert, Thanks for the elaboration. I hope that this follow-up is not too far off topic and I don't want to distract you (or any of the Sage developers) from your main tasks. I wrote this mostly as notes and questions to myself - but if you or anyone else have some time or the inclination to correct or comment as time permits, that would be great. On Tue, Jun 3, 2008 at 10:04 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 4:50 PM, Bill Page wrote: How does it [categories in Sage] relate to the concept of parent - which seems equally ill-defined to me? A Parent is an Object in the category of Sets, though in the context of coercion one usually assumes one can some kind of arithmetic (binary operations) on their elements. ... On Jun 3, 2008, at 7:11 PM, David Harvey wrote: ... Don't you mean to say something more like a parent is an object of a concrete category, i.e. a category C with a faithful functor f : C - Set, such that the elements (as understood by Sage) of the parent P are exactly the elements of f(P)? Ok (and thanks also for the clarification, David). There are of course two different uses of object here: 1) object of some category, 2) Python object. All Python objects have a 'type', i.e. belong to some Python class. So in Sage 3.0.2 I observe for example: sage: type(1) type 'sage.rings.integer.Integer' sage: parent(1) Integer Ring sage: type(parent(1)) type 'sage.rings.integer_ring.IntegerRing_class' sage: category(parent(1)) Category of rings sage: type(category(parent(1))) class 'sage.categories.category_types.Rings' and sage: type(1.0) type 'sage.rings.real_mpfr.RealNumber' sage: parent(1.0) Real Field with 53 bits of precision sage: type(parent(1.0)) type 'sage.rings.real_mpfr.RealField' sage: category(parent(1.0)) Category of fields sage: type(category(parent(1.0))) class 'sage.categories.category_types.Fields' These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? What is the relationship to inheritance in Python? Is the intention to give all mathematical objects defined in Sage some categorical structure? What about categories themselves as mathematical structures - e.g. a category is a kind of directed graph with additional structure? A big push of this model is to divorce the relationship between inheritance (which primarily has to do with implementation) and mathematical categorization. At first blush it still seems strange to me to distinguish between the parent of an object and the type of an object. The instances of a type are often considered elements. Is the invention of 'parent' in Sage due to some inherent limitation of Python classes? Do you really want to say more abstractly that a certain type *represents* a certain parent? E.g. Does 'sage.rings.real_mpfr.RealNumber' represent 'RealField()'? Can there be other representations of 'RealField()' in Sage? How can I find out for example if 'sage.rings.integer.Integer' represents 'IntegerRing()'? From my experience with Axiom I am sympathetic to the separation of implementation and specification but in Axiom domains are both parents and types. A domain can inherit it's implementation from another domain (via add). A domain can also serve as the representation for some other domain (via Rep). For example IntegerMod(5) is the representation of PrimeField(5). IntegerMod(5) in turn is represented by SingleInteger, etc. In Axiom, at the deepest level all types are ultimately provided by Lisp. These types are not really Axiom domains and so I suppose the situation is analogous to Python types and Sage parents. Axiom categories on the other hand form a lattice. Domains belong to categories by assertion or by virtue of the subdomain relationship. In Axiom there is an operator named 'has' which provides the same information as 'category' in Sage so that: x has y is just 'y == category(x)'. For example 'Float has Field' is equivalent to: sage: Fields() == category(RealField()) True Although in Axiom a domain may satisfy more than one category. Will this be possible in Sage in the future? What information does Sage actually have about a given category? For example, what does Sage know about the relationship between Rings() and Fields()? E.g. functors? None of this has much to do with category theory as such. Categories in Axiom are only vaguely related to categories in Mathematics. So I suppose from your description that categories in Sage will play a similar role but will be more strongly related to the mathematical concept? This will allow categories to play a larger role (though work in that area can be done after the merge as it is not disruptive). For example, Z/nZ[x] is implemented the same whether or not p is a prime, but the
[sage-devel] Re: coercing of sqrt(2)
On Jun 4, 2008, at 7:07 AM, Bill Page wrote: Ok (and thanks also for the clarification, David). There are of course two different uses of object here: 1) object of some category, 2) Python object. All Python objects have a 'type', i.e. belong to some Python class. So in Sage 3.0.2 I observe for example: sage: type(1) type 'sage.rings.integer.Integer' sage: parent(1) Integer Ring sage: type(parent(1)) type 'sage.rings.integer_ring.IntegerRing_class' sage: category(parent(1)) Category of rings sage: type(category(parent(1))) class 'sage.categories.category_types.Rings' and sage: type(1.0) type 'sage.rings.real_mpfr.RealNumber' sage: parent(1.0) Real Field with 53 bits of precision sage: type(parent(1.0)) type 'sage.rings.real_mpfr.RealField' sage: category(parent(1.0)) Category of fields sage: type(category(parent(1.0))) class 'sage.categories.category_types.Fields' These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? I'm not an expert on these things any more, but I can tell you what happened back in the day (when the sage version number was slightly smaller): Only elements have real parents. Since ZZ = IntegerRing() is not an element, it doesn't have a parent. If X does not have a parent, then parent(X) returns the type of X instead. I'm not sure this is a good idea, but there it is. Of course then you're wondering why ZZ is not an element of the category of the rings. That I do not know. But you can try: sage: IntegerRing().parent() to see that IntegerRing() simply doesn't have a parent() method, which is why the global version parent(IntegerRing()) returns the type of IntegerRing() instead. One difficulty with ZZ being both a parent and an element is that Cython does not support multiple inheritance. BTW I should mention that the whole idea of parents vs types is one of the main conceptual things inherited from Magma. sorry gotta go cannot answer rest of email, hopefully someone else can david --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 4, 2008, at 1:32 AM, John Cremona wrote: 2008/6/4 Robert Bradshaw [EMAIL PROTECTED]: But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) Robert, Can you be more specific about how others can help with this? Sure. Currently we've made all the underlying changes, and we're in the process of fixing doctests (mostly they're things like typos/ unimplemented functionality rather than deep mathematical peculiarities). The way to get started is: - Download and build Sage 2.10.1 http://sagemath.org/dist/src/ sage-2.10.1.tar - Install the latest Cython http://sage.math.washington.edu/home/ robertwb/cython/cython-0.9.6.14.p1.spkg - Pull from the coercion repo and build http://cython.org/coercion/ hgwebdir.cgi/sage-coerce/ - Choose a (set of) file(s) from the todo list at http:// wiki.sagemath.org/days7/coercion/todo and try to get all doctests to pass there. We're using the wiki to keep track of who's doing what. Some hints: - __cmp__ has been changed to _cmp_ in SageObject, and __cmp__ no longer works due to a default __richcmp__ (that's just how Python works). In retrospect, this probably should not have been done on top of everything else, 'cause it's somewhat independent of coercion and the source of seemingly most failures. - A useful command is coercion_traceback(). This will give the traceback of all exceptions caught during the coercion process. Hopefully this is enough to get started, and feel free to ask questions. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 4, 2008, at 4:07 AM, Bill Page wrote: Robert, Thanks for the elaboration. I hope that this follow-up is not too far off topic and I don't want to distract you (or any of the Sage developers) from your main tasks. I wrote this mostly as notes and questions to myself - but if you or anyone else have some time or the inclination to correct or comment as time permits, that would be great. I'm sure a lot of other people have similar questions, and it will be good to put it down in writing. On Tue, Jun 3, 2008 at 10:04 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 4:50 PM, Bill Page wrote: How does it [categories in Sage] relate to the concept of parent - which seems equally ill-defined to me? A Parent is an Object in the category of Sets, though in the context of coercion one usually assumes one can some kind of arithmetic (binary operations) on their elements. ... On Jun 3, 2008, at 7:11 PM, David Harvey wrote: ... Don't you mean to say something more like a parent is an object of a concrete category, i.e. a category C with a faithful functor f : C - Set, such that the elements (as understood by Sage) of the parent P are exactly the elements of f(P)? Ok (and thanks also for the clarification, David). There are of course two different uses of object here: 1) object of some category, 2) Python object. All Python objects have a 'type', i.e. belong to some Python class. So in Sage 3.0.2 I observe for example: sage: type(1) type 'sage.rings.integer.Integer' sage: parent(1) Integer Ring sage: type(parent(1)) type 'sage.rings.integer_ring.IntegerRing_class' sage: category(parent(1)) Category of rings sage: type(category(parent(1))) class 'sage.categories.category_types.Rings' and sage: type(1.0) type 'sage.rings.real_mpfr.RealNumber' sage: parent(1.0) Real Field with 53 bits of precision sage: type(parent(1.0)) type 'sage.rings.real_mpfr.RealField' sage: category(parent(1.0)) Category of fields sage: type(category(parent(1.0))) class 'sage.categories.category_types.Fields' These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. What is the relationship to inheritance in Python? Is the intention to give all mathematical objects defined in Sage some categorical structure? What about categories themselves as mathematical structures - e.g. a category is a kind of directed graph with additional structure? A big push of this model is to divorce the relationship between inheritance (which primarily has to do with implementation) and mathematical categorization. At first blush it still seems strange to me to distinguish between the parent of an object and the type of an object. The instances of a type are often considered elements. Is the invention of 'parent' in Sage due to some inherent limitation of Python classes? Do you really want to say more abstractly that a certain type *represents* a certain parent? E.g. Does 'sage.rings.real_mpfr.RealNumber' represent 'RealField()'? Can there be other representations of 'RealField()' in Sage? How can I find out for example if 'sage.rings.integer.Integer' represents 'IntegerRing()'? One should think of the type of an object as what specifies its implementation (including its internal representation). In this sense it is like a class in Java, C++, or any other programming language. (In Python there is a subtle (and mostly historical) difference between types and classes depending on whether or not it's written in C, but for the most part they can be used interchangeably). Python has multiple inheritance, but Cython does not (the C format of a compiled Python class is a C struct, so this is not so much a Cython limitation as a Python/C API limitation.) Most of the time there is a 1-to-1 correspondence between Parents and the types of its Elements. For example, and element of the Parent RR (= RealField(53) is represented by sage.rings.real_mpfr.RealNumber. If I do RR(3) I get back an object of type sage.rings.real_mpfr.RealNumber representing the floating point number 3 to 53 bits of precision, and it's Parent is RR. RealField (100) is a new Parent, whose elements are again of type sage.rings.real_mpfr.RealNumber but to 100 bits of precision. Sometimes, however, the same type is used for multiple parents. There are several integer mod types (depending on whether or not the modulus fits in a single word) and they are
[sage-devel] Re: coercing of sqrt(2)
On Wed, Jun 4, 2008 at 1:54 PM, Robert Bradshaw wrote: On Jun 4, 2008, at 4:07 AM, Bill Page wrote: ... These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. So is this essentially an admission that the concept of 'parent' is superfluous and could have in fact been implemented just at Python 'type'? I am not sure that I would actually advocate this now, but for argument's sake: Why not do it this way all of the time? Python classes all end up as (potential) parents. I think that this more or less is what at least some Magma developers had in mind. E.g. We read in the preface to the Magma HTML Help Document: http://magma.maths.usyd.edu.au/magma/htmlhelp/preface.htm Every object created during the course of a computation is associated with a unique parent algebraic structure. The type of an object is then simply its parent structure. ... One should think of the type of an object as what specifies its implementation (including its internal representation). In this sense it is like a class in Java, C++, or any other programming language. (In Python there is a subtle (and mostly historical) difference between types and classes depending on whether or not it's written in C, but for the most part they can be used interchangeably). Python has multiple inheritance, but Cython does not (the C format of a compiled Python class is a C struct, so this is not so much a Cython limitation as a Python/C API limitation.) The lack of multiple inheritance in Cython seems to be a major design obstacle. Although a C struct is not a real class, it is not clear to me why this is not adequate in compiled code. Wouldn't it be sufficient to merge (flatten) the components of the multiple ancesters into one struct? If not (e.g. if it is necessary to retain some knowledge of their origins), why not provide nested structs? But I suppose that this is quite off-topic... Most of the time there is a 1-to-1 correspondence between Parents and the types of its Elements. For example, and element of the Parent RR (= RealField(53) is represented by sage.rings.real_mpfr.RealNumber. If I do RR(3) I get back an object of type sage.rings.real_mpfr.RealNumber representing the floating point number 3 to 53 bits of precision, and it's Parent is RR. RealField (100) is a new Parent, whose elements are again of type sage.rings.real_mpfr.RealNumber but to 100 bits of precision. Sometimes, however, the same type is used for multiple parents. There are several integer mod types (depending on whether or not the modulus fits in a single word) and they are used for both generic Z/nZ and prime-order finite fields. Thus we have sage: [type(mod(-1, 100^k)) for k in [2..5]] [type 'sage.rings.integer_mod.IntegerMod_int', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_gmp'] sage: [parent(mod(-1, 100^k)) for k in [2..5]] [Ring of integers modulo 1, Ring of integers modulo 100, Ring of integers modulo 1, Ring of integers modulo 100] Hmmm... what I think I see here is multiple Python types (_int, _int64, _gmp) being used for the *same* parent, i.e. Ring of integers modulo n (for some parameter n). Simple inheritance should make this easy, no? On the other hand, some parents may have elements of several types. The SymbolicRing is one such example. sage: [type(a) for a in v] [class 'sage.calculus.calculus.SymbolicConstant', class 'sage.functions.constants.Pi', class 'sage.calculus.calculus.SymbolicArithmetic', class 'sage.calculus.calculus.SymbolicComposition'] sage: [parent(a) for a in v] [Symbolic Ring, Symbolic Ring, Symbolic Ring, Symbolic Ring] SymbolicRing is another thing that worries me a little. Exactly what (mathematically) is a symbolic ring? E.g. Why is it a ring and not a field? Operations like 'sin(sin(sin(x))).parent()' doesn't look much like a ring to me. Probably most other computer algebra systems would just call this an expression tree or AST or something like that. Why do we need different types (sub-classes)? From my experience with Axiom I am sympathetic to the separation of implementation and specification but in Axiom domains are both parents and types. A domain can inherit it's implementation from another domain (via add). A domain can also serve as the representation for some other domain (via Rep). For example
[sage-devel] Re: coercing of sqrt(2)
On Wed, Jun 4, 2008 at 7:35 PM, Bill Page [EMAIL PROTECTED] wrote: On Wed, Jun 4, 2008 at 1:54 PM, Robert Bradshaw wrote: On Jun 4, 2008, at 4:07 AM, Bill Page wrote: ... These seem consistent to me, albeit rather complex. However I am not sure I understand the following: sage: parent(IntegerRing()) type 'sage.rings.integer_ring.IntegerRing_class' sage: parent(RealField()) type 'sage.rings.real_mpfr.RealField' Could you explain why the parent of an object of some category is a type? David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. So is this essentially an admission that the concept of 'parent' is superfluous and could have in fact been implemented just at Python 'type'? That is not the case, except that of course *anything* that can be implemented, can be implemented in any turing complete language. I am not sure that I would actually advocate this now, but for argument's sake: Why not do it this way all of the time? Python classes all end up as (potential) parents. I think that this more or less is what at least some Magma developers had in mind. E.g. We read in the preface to the Magma HTML Help Document: http://magma.maths.usyd.edu.au/magma/htmlhelp/preface.htm Every object created during the course of a computation is associated with a unique parent algebraic structure. The type of an object is then simply its parent structure. You took that quote out of context. The full quote is: The theoretical basis for the design of Magma is founded on the concepts and methodology of modern algebra. The central notion is that of an algebraic structure. Every object created during the course of a computation is associated with a unique parent algebraic structure. The type of an object is then simply its parent structure. The word type is being used in a formal sense as defined in the excellent paper The Magma Algebra System I: The User Language by Bosma, Cannon, and Playoust. ... One should think of the type of an object as what specifies its implementation (including its internal representation). In this sense it is like a class in Java, C++, or any other programming language. (In Python there is a subtle (and mostly historical) difference between types and classes depending on whether or not it's written in C, but for the most part they can be used interchangeably). Python has multiple inheritance, but Cython does not (the C format of a compiled Python class is a C struct, so this is not so much a Cython limitation as a Python/C API limitation.) The lack of multiple inheritance in Cython seems to be a major design obstacle. Although a C struct is not a real class, it is not clear to me why this is not adequate in compiled code. Wouldn't it be sufficient to merge (flatten) the components of the multiple ancesters into one struct? If not (e.g. if it is necessary to retain some knowledge of their origins), why not provide nested structs? But I suppose that this is quite off-topic... Most of the time there is a 1-to-1 correspondence between Parents and the types of its Elements. For example, and element of the Parent RR (= RealField(53) is represented by sage.rings.real_mpfr.RealNumber. If I do RR(3) I get back an object of type sage.rings.real_mpfr.RealNumber representing the floating point number 3 to 53 bits of precision, and it's Parent is RR. RealField (100) is a new Parent, whose elements are again of type sage.rings.real_mpfr.RealNumber but to 100 bits of precision. Sometimes, however, the same type is used for multiple parents. There are several integer mod types (depending on whether or not the modulus fits in a single word) and they are used for both generic Z/nZ and prime-order finite fields. Thus we have sage: [type(mod(-1, 100^k)) for k in [2..5]] [type 'sage.rings.integer_mod.IntegerMod_int', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_int64', type 'sage.rings.integer_mod.IntegerMod_gmp'] sage: [parent(mod(-1, 100^k)) for k in [2..5]] [Ring of integers modulo 1, Ring of integers modulo 100, Ring of integers modulo 1, Ring of integers modulo 100] Hmmm... what I think I see here is multiple Python types (_int, _int64, _gmp) being used for the *same* parent, i.e. Ring of integers modulo n (for some parameter n). Simple inheritance should make this easy, no? There are infinitely many different parents, one of each value of n. For a given n, the ring Z/nZ is a specific mathematical object, which is itself for many many reasons worth modeling in a computer. If nothing else, it is the place on which to hang functions like multiplicative_generator(). Any computer algebra system that doesn't have first class actual
[sage-devel] Re: coercing of sqrt(2)
On Wed, Jun 4, 2008 at 11:06 PM, William Stein wrote: On Wed, Jun 4, 2008 at 7:35 PM, Bill Page wrote: On Wed, Jun 4, 2008 at 1:54 PM, Robert Bradshaw wrote: David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. So is this essentially an admission that the concept of 'parent' is superfluous and could have in fact been implemented just as Python 'type'? That is not the case, except that of course *anything* that can be implemented, can be implemented in any turing complete language. I did not mean to pose this question in a trivial way. I meant to suggest that the concept of type in the Python programming language, i.e. classes, could directly implement the concept of parent as used in Sage without abusing either concept at all. Can you suggest an example that demonstrates that this is not the case? ... There are infinitely many different parents, one of each value of n. For a given n, the ring Z/nZ is a specific mathematical object, which is itself for many many reasons worth modeling in a computer. If nothing else, it is the place on which to hang functions like multiplicative_generator(). Python classes can also take parameters. Any computer algebra system that doesn't have first class actual objects that represent basic mathematical structures such as rings, fields, etc., feels extremely barren if one has used Magma for a sufficient amount of time. Sure. Rings and fields are categories. Magma was not the first system to represent these mathematical structures in a computer. Specific rings, fields, vector spaces, etc., are all basic objects of mathematics, that are just as important to fully implement and model in a CAS as polynomials, rational numbers, vectors, etc. I firmly believe Magma was the first ever system to really get this right, and Sage merely copies this. I really greatly appreciate what Cannon et al. did... I am sure Magma is an interesting system - everything I have been reading about it confirms that - but I do not think it was the first. I am also not yet convinced that it has implemented these general mathematically concepts in any substantially better way then, for example Axiom. Some things it does seem peculiar and ad hoc to me. These are the things that standout in my mind when I think about in what ways Sage resembles Magma. Of course there are some specific computations that Magma does much more efficiently than any other system. But that is not the point. We are talking here about general design issues. ... SymbolicRing is another thing that worries me a little. Exactly what (mathematically) is a symbolic ring? E.g. Why is it a ring and not a field? Operations like 'sin(sin(sin(x))).parent()' doesn't look much like a ring to me. Probably most other computer algebra systems would just call this an expression tree or AST or something like that. ... To me, the SymbolicRing is the mathematical structure in which calculus teachers, engineers, etc., are kept happy. In Sage that was 100% its purpose. Ask Marshall Hampton, who is teaching calculus right now using Sage, about what he needs to make teaching calculus easy, and the answer is The Symbolic Ring, plus graphics and interact. I don't doubt that doing symbolic mathematics by computer is very useful for teaching calculus - after all that is what is normally meant by the term calculus, i.e. a method of calculation based on the symbolic manipulation of expressions. The name Symbolic Ring however makes it sound more algebraic,i.e. concerned with structure, relation and quantity. So I was looking for a more formal mathematical definition of this sort. I did not expect it was a name intended just to keep certain people happy. :-( ... Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Wed, Jun 4, 2008 at 10:16 PM, Bill Page [EMAIL PROTECTED] wrote: On Wed, Jun 4, 2008 at 11:06 PM, William Stein wrote: On Wed, Jun 4, 2008 at 7:35 PM, Bill Page wrote: On Wed, Jun 4, 2008 at 1:54 PM, Robert Bradshaw wrote: David's explanation of this is right on. We need parent() to work in some sensible way on non-Elements (e.g. Python ints, objects from outside Sage) to be able do some kind of coercion reasoning on them. Python is a dynamically typed language, ever object has a type. So is this essentially an admission that the concept of 'parent' is superfluous and could have in fact been implemented just as Python 'type'? That is not the case, except that of course *anything* that can be implemented, can be implemented in any turing complete language. I did not mean to pose this question in a trivial way. I meant to suggest that the concept of type in the Python programming language, i.e. classes, could directly implement the concept of parent as used in Sage without abusing either concept at all. Can you suggest an example that demonstrates that this is not the case? I think Robert's example of the integers modulo n is an excellent example of precisely this. I'm confused about why you don't see this. ... There are infinitely many different parents, one of each value of n. For a given n, the ring Z/nZ is a specific mathematical object, which is itself for many many reasons worth modeling in a computer. If nothing else, it is the place on which to hang functions like multiplicative_generator(). Python classes can also take parameters. I didn't know that. I thought the only way to create a Python class is for the Python interpreter to execute Python code that looks like this: class Foo(...): ... That makes a new class called Foo. How are you going to make, at runtime, new classes for each of Z/nZ say, for 1 = n 10^5, i.e., something like this in Sage: v = [Integers(n) for n in range(1,10^5)] I do not think it is possible to concisely create a hundred thousand separate Python classes like that. Any computer algebra system that doesn't have first class actual objects that represent basic mathematical structures such as rings, fields, etc., feels extremely barren if one has used Magma for a sufficient amount of time. Sure. Rings and fields are categories. I meant Rings and fields not as categories but specific rings and specified fields as mathematical objects in their own right. In Magma and Sage there is virtually no difference between a polynomial ring over the rational numbers and a specific polynomial over the rationals -- both are first class instances in exactly the same way. Magma was not the first system to represent these mathematical structures in a computer. I believe Magma was the first to very systematically represent the objects of the categories as first class objects systematically throughout the system. I know of no other system that does this (except Sage). Specific rings, fields, vector spaces, etc., are all basic objects of mathematics, that are just as important to fully implement and model in a CAS as polynomials, rational numbers, vectors, etc. I firmly believe Magma was the first ever system to really get this right, and Sage merely copies this. I really greatly appreciate what Cannon et al. did... I am sure Magma is an interesting system - everything I have been reading about it confirms that - but I do not think it was the first. I am also not yet convinced that it has implemented these general mathematically concepts in any substantially better way then, for example Axiom. I think Magma is brilliant. Disclaimer: I used to be one of the biggest Magma zealots on the planet, so take that with a grain of salt! It is also not my intention here to make any negative comments at all about Axiom (say) -- only positive comments about Magma. Some things it does seem peculiar and ad hoc to me. These are the things that standout in my mind when I think about in what ways Sage resembles Magma. Of course there are some specific computations that Magma does much more efficiently than any other system. But that is not the point. We are talking here about general design issues. Yet efficiency and design are closely linked. When I first started using Magma after years and years of C++, I was amazed how they were able to unify so many ideas and bring such a vast amount of quality code together in a way that worked pretty well. I soon started writing, in the Magma interpreter, vastly more efficient code than I could ever write in C++, and code that accomplished a lot more. Much of this was for me directly a result of the excellent design ideas that went into Magma. This was a real eye opener for me. ... SymbolicRing is another thing that worries me a little. Exactly what (mathematically) is a symbolic ring? E.g. Why is it a ring and not a field? Operations like 'sin(sin(sin(x))).parent()'
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 12:09 AM, Gary Furnish wrote: On Mon, Jun 2, 2008 at 11:41 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 2, 2008, at 12:55 PM, William Stein wrote: On Mon, Jun 2, 2008 at 12:53 PM, Gary Furnish [EMAIL PROTECTED] wrote: -1. First, everything cwitty said is correct. More on this below. Second, if we start using ZZ[sqrt(2)] and ZZ[sqrt(3)], then sqrt(2)+sqrt(3) requires going through the coercion system which was designed to be elegant instead of fast, so this becomes insanely slow for any serious use. The coercion system is designed to be elegant *and* fast. Writing something like 1 + sqrt(2) is going to require the coercion system no matter what we do, as is 1 + sqrt(2) + 1/2. Computing QQ(sqrt(2), sqrt (3)) may take a millisecond or two, but after that coercion into it from ether ring will be fast. As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Finally, this is going to require serious code duplication from symbolics, so I'm not sure what the big gain is over just using symbolics to do this in the first place. Number field element work completely differently than symbolics, I see little if any code duplication. Fair enough. Also, cwitty pointed out that sage: sum([sqrt(p) for p in prime_range(1000)]) works fine in Sage now, but with your (and my) proposal, it would be impossible, since it would require constructing a ring of integers of a number field of degree 2^168.. This is the biggest argument against such a proposal, and I'm not quite sure how best to handle this. One would have to implement large number fields over sparse polynomials, and only lazily compute the ring of integers. Or, as John Cremona suggested, train users. None of the above are ideal. I would like to give my motivation for not having sqrt(2) be in SR: 1) Speed. I know you're working very hard to make symbolics much, much faster than they currently are, but I still don't think it'll be able to compete in this very specialized domain. Currently: sage: timeit(((1+sqrt(2))^100).expand()) 5 loops, best of 3: 52.9 ms per loop sage: timeit(((1+sqrt(2)+sqrt(3))^50).expand()) 5 loops, best of 3: 579 ms per loop sage: sym_a = sqrt(2) + sqrt(3) sage: timeit(((1+sym_a)^50).expand()) 5 loops, best of 3: 576 ms per loop Compared to sage: K.a = NumberField(x^2-2) sage: timeit(((1+a)^100)) 625 loops, best of 3: 48.4 µs per loop sage: K.a = NumberField(x^4 - 10*x^2 + 1) sage: timeit(((1+a)^50)) 625 loops, best of 3: 138 µs per loop That's over three orders of magnitude faster (and it's *not* due to pexpect/interface overhead as the actual input and output are relatively small). Making arithmetic involving a couple of radicals fast should probably be the most important, especially as one starts making structures over them. Symbolics isn't going to approach number field speed. I think we can do much better then maxima, but its not going to be that much better (maybe if we encapsulate number fields as a special case in SR) I'd rather have them be a number field elements (with all the methods, etc) over providing a wrapping in SR. Otherwise one ends up with something like pari, where everything just sits in the same parent. 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I); 1/2 - 1/2 I at least. Looking to the M's for ideas is good, but they should not always dictate how we do things--none but Magma has the concept of parents/elements, and Sage uses a very OO model which
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 1:37 AM, John Cremona wrote: MI = Multiple Inheritance? That's the only thing I can think of, but there isn't any of that in the coercion model... - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
MI = Multiple Inheritance? 2008/6/3 Robert Bradshaw [EMAIL PROTECTED]: On Jun 3, 2008, at 12:09 AM, Gary Furnish wrote: On Mon, Jun 2, 2008 at 11:41 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 2, 2008, at 12:55 PM, William Stein wrote: On Mon, Jun 2, 2008 at 12:53 PM, Gary Furnish [EMAIL PROTECTED] wrote: -1. First, everything cwitty said is correct. More on this below. Second, if we start using ZZ[sqrt(2)] and ZZ[sqrt(3)], then sqrt(2)+sqrt(3) requires going through the coercion system which was designed to be elegant instead of fast, so this becomes insanely slow for any serious use. The coercion system is designed to be elegant *and* fast. Writing something like 1 + sqrt(2) is going to require the coercion system no matter what we do, as is 1 + sqrt(2) + 1/2. Computing QQ(sqrt(2), sqrt (3)) may take a millisecond or two, but after that coercion into it from ether ring will be fast. As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Finally, this is going to require serious code duplication from symbolics, so I'm not sure what the big gain is over just using symbolics to do this in the first place. Number field element work completely differently than symbolics, I see little if any code duplication. Fair enough. Also, cwitty pointed out that sage: sum([sqrt(p) for p in prime_range(1000)]) works fine in Sage now, but with your (and my) proposal, it would be impossible, since it would require constructing a ring of integers of a number field of degree 2^168.. This is the biggest argument against such a proposal, and I'm not quite sure how best to handle this. One would have to implement large number fields over sparse polynomials, and only lazily compute the ring of integers. Or, as John Cremona suggested, train users. None of the above are ideal. I would like to give my motivation for not having sqrt(2) be in SR: 1) Speed. I know you're working very hard to make symbolics much, much faster than they currently are, but I still don't think it'll be able to compete in this very specialized domain. Currently: sage: timeit(((1+sqrt(2))^100).expand()) 5 loops, best of 3: 52.9 ms per loop sage: timeit(((1+sqrt(2)+sqrt(3))^50).expand()) 5 loops, best of 3: 579 ms per loop sage: sym_a = sqrt(2) + sqrt(3) sage: timeit(((1+sym_a)^50).expand()) 5 loops, best of 3: 576 ms per loop Compared to sage: K.a = NumberField(x^2-2) sage: timeit(((1+a)^100)) 625 loops, best of 3: 48.4 µs per loop sage: K.a = NumberField(x^4 - 10*x^2 + 1) sage: timeit(((1+a)^50)) 625 loops, best of 3: 138 µs per loop That's over three orders of magnitude faster (and it's *not* due to pexpect/interface overhead as the actual input and output are relatively small). Making arithmetic involving a couple of radicals fast should probably be the most important, especially as one starts making structures over them. Symbolics isn't going to approach number field speed. I think we can do much better then maxima, but its not going to be that much better (maybe if we encapsulate number fields as a special case in SR) I'd rather have them be a number field elements (with all the methods, etc) over providing a wrapping in SR. Otherwise one ends up with something like pari, where everything just sits in the same parent. 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I); 1/2 - 1/2 I at least. Looking to the M's for ideas is good, but they should not always dictate how we do things--none but Magma has the
[sage-devel] Re: coercing of sqrt(2)
Maple does 1/(1+I); 1/2 - 1/2 I Axiom does 1/(1+%i) 1 -- 1 + %i which is of type Fraction Complex Integer, that is a fraction whose numerator and denominator are of type Complex(Integer). You can ask Axiom to place the result in a different type: 1/(1+%i)::Complex Fraction Integer 1 1 - - - %i 2 2 and the type is Complex Fraction Integer, that is a Complex number whose real and imaginary components are Fraction(Integer). The simple form depends on what is canonical for the type. Tim --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 2:34 AM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 12:09 AM, Gary Furnish wrote: On Mon, Jun 2, 2008 at 11:41 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 2, 2008, at 12:55 PM, William Stein wrote: On Mon, Jun 2, 2008 at 12:53 PM, Gary Furnish [EMAIL PROTECTED] wrote: -1. First, everything cwitty said is correct. More on this below. Second, if we start using ZZ[sqrt(2)] and ZZ[sqrt(3)], then sqrt(2)+sqrt(3) requires going through the coercion system which was designed to be elegant instead of fast, so this becomes insanely slow for any serious use. The coercion system is designed to be elegant *and* fast. Writing something like 1 + sqrt(2) is going to require the coercion system no matter what we do, as is 1 + sqrt(2) + 1/2. Computing QQ(sqrt(2), sqrt (3)) may take a millisecond or two, but after that coercion into it from ether ring will be fast. As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Sets, and in particular a bunch of the category functionality (homset) get used in coercion, and use MI, making them impossible to cythonize. Finally, this is going to require serious code duplication from symbolics, so I'm not sure what the big gain is over just using symbolics to do this in the first place. Number field element work completely differently than symbolics, I see little if any code duplication. Fair enough. Also, cwitty pointed out that sage: sum([sqrt(p) for p in prime_range(1000)]) works fine in Sage now, but with your (and my) proposal, it would be impossible, since it would require constructing a ring of integers of a number field of degree 2^168.. This is the biggest argument against such a proposal, and I'm not quite sure how best to handle this. One would have to implement large number fields over sparse polynomials, and only lazily compute the ring of integers. Or, as John Cremona suggested, train users. None of the above are ideal. I would like to give my motivation for not having sqrt(2) be in SR: 1) Speed. I know you're working very hard to make symbolics much, much faster than they currently are, but I still don't think it'll be able to compete in this very specialized domain. Currently: sage: timeit(((1+sqrt(2))^100).expand()) 5 loops, best of 3: 52.9 ms per loop sage: timeit(((1+sqrt(2)+sqrt(3))^50).expand()) 5 loops, best of 3: 579 ms per loop sage: sym_a = sqrt(2) + sqrt(3) sage: timeit(((1+sym_a)^50).expand()) 5 loops, best of 3: 576 ms per loop Compared to sage: K.a = NumberField(x^2-2) sage: timeit(((1+a)^100)) 625 loops, best of 3: 48.4 µs per loop sage: K.a = NumberField(x^4 - 10*x^2 + 1) sage: timeit(((1+a)^50)) 625 loops, best of 3: 138 µs per loop That's over three orders of magnitude faster (and it's *not* due to pexpect/interface overhead as the actual input and output are relatively small). Making arithmetic involving a couple of radicals fast should probably be the most important, especially as one starts making structures over them. Symbolics isn't going to approach number field speed. I think we can do much better then maxima, but its not going to be that much better (maybe if we encapsulate number fields as a special case in SR) I'd rather have them be a number field elements (with all the methods, etc) over providing a wrapping in SR. Otherwise one ends up with something like pari, where everything just sits in the same parent. 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I);
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 7:13 AM, Gary Furnish [EMAIL PROTECTED] wrote: The average calculus student coming from maple is not going to understand why he can't perform a sum of the sqrt of some primes. If we are to be a viable alternative for non-research mathematicians we can't run off and implement things that drastically change the complexity of simple operations. Let me take a moment to totally hijack this thread and say that I think we should drastically change the complexity of simple operations... for the better :-) There's just a *shocking* number of simple operations out there in Maple/Mathematica, etc., which we can and should do much faster in Sage. OK, back to the thread... -- William --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 7:13 AM, Gary Furnish wrote: As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Sets, and in particular a bunch of the category functionality (homset) get used in coercion, and use MI, making them impossible to cythonize. Ah, yes. Homsets. They're not used anywhere in the critical path though. (If so, that should be fixed.) 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I); 1/2 - 1/2 I I somewhat ignored (1/1+i) (I agree there is an obvious simplification), but (x+1)^2 shouldn't get simplified under any circumstances. This has (little) do with speed (for this small of exponent) and everything to do with being consistent with the high degree cases and keeping expressions uncluttered. I agree that (x+1)^2 shouldn't get simplified, but for me this has a very different feel than (1+I)^2 or (1+sqrt(2))^2. at least. Looking to the M's for ideas is good, but they should not always dictate how we do things--none but Magma has the concept of parents/elements, and Sage uses a very OO model which differs from all of them. Why doesn't it make sense for Mathematica/Maple? I think it's because they view simplification (or even deciding to simplify) as expensive. 3) The coercion system works best when things start as high up the tree as they can, and the Symbolic Ring is like the big black hole at the bottom that sucks everything in (and makes it slow). There is a coercion from ZZ[sqrt(2)] (with embedding) to SR, but not the other way around, and even trying to cast the other way is problematic. I'd rather that matrix([1, 1/2, 0, sqrt(2)]) land in a matrix space over the a number field (rather than over SR), and ZZ['x'].gen() + sqrt(2) be an actual polynomial in x. Also, the SR, though very useful, somehow seems less rigorous (I'm sure that this is improving). When coercion is faster we can consider changing this. Coercion speed is irrelevant to the issues I mentioned here... and as coercion+number fields is *currently* faster than what you could hope to get with SR (the examples above all involve coercion) it wouldn't help your case either. Only for the sqrt case, and I'm willing to work with that (provided that for endusers, sum(sqrt(p)) behaves as expected. n-th root would have a similar speed increase, but other than those two cases I don't see one wanting algebraic extensions (short of explicitly making a number field). My definition of fast is 10 cycles if the parents are the same, Python semantics tie our hands a bit here, but I think we're about as close as we can get. no dictionary lookups if one parent is in the other for all common cases, Would this mean hard-coding all common paths? Currently there is a single dictionary lookup for common cases (and not a Python dict). Common cases should be no more then a virtual call and a few if statements away (and not a bunch of virtual calls either. They cost performance too. No more then one should be necessary for the common case (the code to handle this can probably go in the addition/multiplication handlers)). Then if that fails we can take the cached dict lookup route. Make the common case fast at the expense of the uncommon case. I am -1 for hard-coding knowledge and logic about ZZ, QQ, RR, RDF, CC, CDF, ... into the coercion model. otherwise reasonablely quick pure Cython code. Yes, it should be fast, but only has to be done once and then it's cached. Of course the code specific to the
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 12:11 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 11:06 AM, Gary Furnish wrote: I think we had a discussion on irc about how homsets still got used for determining the result of something in parent1 op something in parent2 (maybe it was with someone else?) I sure hope not. If so, that needs to change (but I'm pretty sure it isn't). Well allegedly there is some function that computes what parent something is in if you have parent1 op parentt2 that is new in this system (but I can't find said function). Allegedly said function has to use Homsets, so performance is going to be horrible(and this makes sense, because its what I have to use now). I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. Sure, its kindof ugly, but it will give us the performance we need, and I don't see a better way to allow us to use coercions all over the place without having performance drop to 0. On Tue, Jun 3, 2008 at 11:48 AM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 7:13 AM, Gary Furnish wrote: As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Sets, and in particular a bunch of the category functionality (homset) get used in coercion, and use MI, making them impossible to cythonize. Ah, yes. Homsets. They're not used anywhere in the critical path though. (If so, that should be fixed.) 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I); 1/2 - 1/2 I I somewhat ignored (1/1+i) (I agree there is an obvious simplification), but (x+1)^2 shouldn't get simplified under any circumstances. This has (little) do with speed (for this small of exponent) and everything to do with being consistent with the high degree cases and keeping expressions uncluttered. I agree that (x+1)^2 shouldn't get simplified, but for me this has a very different feel than (1+I)^2 or (1+sqrt(2))^2. at least. Looking to the M's for ideas is good, but they should not always dictate how we do things--none but Magma has the concept of parents/elements, and Sage uses a very OO model which differs from all of them. Why doesn't it make sense for Mathematica/Maple? I think it's because they view simplification (or even deciding to simplify) as expensive. 3) The coercion system works best when things start as high up the tree as they can, and the Symbolic Ring is like the big black hole at the bottom that sucks everything in (and makes it slow). There is a coercion from ZZ[sqrt(2)] (with embedding) to SR, but not the other way around, and even trying to cast the other way is problematic. I'd rather that matrix([1, 1/2, 0, sqrt(2)]) land in a matrix space over the a number field (rather than over SR), and ZZ['x'].gen() + sqrt(2) be an actual polynomial in x. Also, the SR, though very useful, somehow seems less rigorous (I'm sure that this is improving). When coercion is faster we can consider changing this. Coercion speed is irrelevant to the issues I mentioned here... and as coercion+number fields is *currently* faster than what you could hope to get with SR (the examples above
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 11:06 AM, Gary Furnish wrote: I think we had a discussion on irc about how homsets still got used for determining the result of something in parent1 op something in parent2 (maybe it was with someone else?) I sure hope not. If so, that needs to change (but I'm pretty sure it isn't). I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. On Tue, Jun 3, 2008 at 11:48 AM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 7:13 AM, Gary Furnish wrote: As long as there are classes in pure python that use MI on the critical path that symbolics has to use, the argument that coercion was written to be fast makes no sense to me. Not sure what you mean by MI here, could you explain. In any case, just because coercion isn't as fast as it could be doesn't mean that it's not written for speed and much faster than it used to be. Of course there's room for improvement, but right now the focus is trying to finish the new system (which isn't really that new compared to the change made a year ago) in place. Sets, and in particular a bunch of the category functionality (homset) get used in coercion, and use MI, making them impossible to cythonize. Ah, yes. Homsets. They're not used anywhere in the critical path though. (If so, that should be fixed.) 2) I personally don't like having to sprinkle the expand and and/or simplify all over the place. Now I don't think symbolics should be expanded automatically, but stuff like (1+sqrt(2))^2 should be or 1/(1 +i). It's like just getting the question back. (I guess I'm revealing my bias that I don't think of it as living in SR, but rather a number field...) On that note, I can't even figure out how to do simplify (sqrt(2)-3)/(sqrt(2)-1) in the symbolics...as opposed to sage: K.sqrt2 = NumberField(x^2-2) sage: (sqrt2-3)/(sqrt2-1) -2*sqrt2 - 1 sage: 1/(sqrt2-1) sqrt2 + 1 Your going to have a hard time convincing me that the default behavior in Mathematica and Maple is wrong. This makes sense for number theory but not for people using calculus. OK, this is a valid point, though the non-calculus portions (and emphasis) of Sage are (relatively) more significant. Sage is not a CAS, that is just one (important) piece of it. Maple does 1/(1+I); 1/2 - 1/2 I I somewhat ignored (1/1+i) (I agree there is an obvious simplification), but (x+1)^2 shouldn't get simplified under any circumstances. This has (little) do with speed (for this small of exponent) and everything to do with being consistent with the high degree cases and keeping expressions uncluttered. I agree that (x+1)^2 shouldn't get simplified, but for me this has a very different feel than (1+I)^2 or (1+sqrt(2))^2. at least. Looking to the M's for ideas is good, but they should not always dictate how we do things--none but Magma has the concept of parents/elements, and Sage uses a very OO model which differs from all of them. Why doesn't it make sense for Mathematica/Maple? I think it's because they view simplification (or even deciding to simplify) as expensive. 3) The coercion system works best when things start as high up the tree as they can, and the Symbolic Ring is like the big black hole at the bottom that sucks everything in (and makes it slow). There is a coercion from ZZ[sqrt(2)] (with embedding) to SR, but not the other way around, and even trying to cast the other way is problematic. I'd rather that matrix([1, 1/2, 0, sqrt(2)]) land in a matrix space over the a number field (rather than over SR), and ZZ['x'].gen() + sqrt(2) be an actual polynomial in x. Also, the SR, though very useful, somehow seems less rigorous (I'm sure that this is improving). When coercion is faster we can consider changing this. Coercion speed is irrelevant to the issues I mentioned here... and as coercion+number fields is *currently* faster than what you could hope to get with SR (the examples above all involve coercion) it wouldn't help your case either. Only for the sqrt case, and I'm willing to work with that (provided that for endusers, sum(sqrt(p)) behaves as expected. n-th root would have a similar speed increase, but other than those two cases I don't see one wanting algebraic extensions (short of explicitly making a number field). My definition of fast is 10 cycles if the parents are the same, Python semantics tie our hands a bit here, but I think we're about as close as we can get. no dictionary lookups if one parent is in the other for all common cases, Would this mean hard-coding all common paths? Currently there is a single dictionary lookup for common
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: On Tue, Jun 3, 2008 at 12:11 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 11:06 AM, Gary Furnish wrote: I think we had a discussion on irc about how homsets still got used for determining the result of something in parent1 op something in parent2 (maybe it was with someone else?) I sure hope not. If so, that needs to change (but I'm pretty sure it isn't). Well allegedly there is some function that computes what parent something is in if you have parent1 op parentt2 that is new in this system (but I can't find said function). Allegedly said function has to use Homsets, so performance is going to be horrible(and this makes sense, because its what I have to use now). When a new morphism is created it needs a parent, which is a Homset that may be looked up/created at that time. This is probably what you are talking about. However, this is a single (tiny) constant overhead over the entire runtime of Sage. I'm sure this could be further optimized, but creating all the homsets ZZ - QQ - RR - CC, etc. will be done long before any symbolic code gets hit. I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. Sure, its kindof ugly, but it will give us the performance we need, and I don't see a better way to allow us to use coercions all over the place without having performance drop to 0. One may be able to eek out a bit more performance by doing this, but it's not as if performance is awful in the current model. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 4:48 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: ... I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. Absolutely! :-) BTW, where can I read more about these categorical concepts that are currently built-in or planned for Sage? Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 2:45 PM, Bill Page [EMAIL PROTECTED] wrote: On Tue, Jun 3, 2008 at 4:48 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: ... I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. Absolutely! :-) BTW, where can I read more about these categorical concepts that are currently built-in or planned for Sage? This is very relevant: http://wiki.sagemath.org/days7/coercion William --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 2:48 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: On Tue, Jun 3, 2008 at 12:11 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 11:06 AM, Gary Furnish wrote: I think we had a discussion on irc about how homsets still got used for determining the result of something in parent1 op something in parent2 (maybe it was with someone else?) I sure hope not. If so, that needs to change (but I'm pretty sure it isn't). Well allegedly there is some function that computes what parent something is in if you have parent1 op parentt2 that is new in this system (but I can't find said function). Allegedly said function has to use Homsets, so performance is going to be horrible(and this makes sense, because its what I have to use now). When a new morphism is created it needs a parent, which is a Homset that may be looked up/created at that time. This is probably what you are talking about. However, this is a single (tiny) constant overhead over the entire runtime of Sage. I'm sure this could be further optimized, but creating all the homsets ZZ - QQ - RR - CC, etc. will be done long before any symbolic code gets hit. This is not what I'm talking about. What I'm talking about is you can't access members of homset without leaving cython and using python. I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. No, I consider categories to be good. I consider bad implementations of categories to be bad. Implementations that make extensive use of MI and are thus impossible to cythonize or access without py dict lookups are not good implementations of categories. If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), I would be significantly less upset with it then I am now where people tell me that if I need more speed I'm out of luck. I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. Sure, its kindof ugly, but it will give us the performance we need, and I don't see a better way to allow us to use coercions all over the place without having performance drop to 0. One may be able to eek out a bit more performance by doing this, but it's not as if performance is awful in the current model. For the things you do. There is no code that pushes the coercion system anywhere near as much as symbolics in Sage does. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 3:08 PM, Gary Furnish wrote: On Tue, Jun 3, 2008 at 2:48 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: When a new morphism is created it needs a parent, which is a Homset that may be looked up/created at that time. This is probably what you are talking about. However, this is a single (tiny) constant overhead over the entire runtime of Sage. I'm sure this could be further optimized, but creating all the homsets ZZ - QQ - RR - CC, etc. will be done long before any symbolic code gets hit. This is not what I'm talking about. What I'm talking about is you can't access members of homset without leaving cython and using python. Of course homsets could be optimized, but once created they aren't used in the coercion itself. I don't know why you'd need to access the members of homset unless you were doing some very high-level programming. The domain and codomain are cdef attributes of Morphisms, which are in Cython (and that took a fair amount of work as they was a lot of MI going on with them until a year ago). I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. No, I consider categories to be good. I consider bad implementations of categories to be bad. Implementations that make extensive use of MI and are thus impossible to cythonize or access without py dict lookups are not good implementations of categories. That depends on what they are being used for, but categories lend themselves very naturally to multiple inheritance because of what they are mathematically. I understand wanting, .e.g., arithmetic to be super fast, but I don't see the gain in hacks/code duplication to strip out multiple inheritance from and cythonize categories. Python is a beautiful language, but it comes with a cost (e.g. dict lookups). Other than initial homset creation, what would be faster (for you) if homsets and categories were written in Cython? If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), The critical path for doing arithmetic between elements is 100% pure Cython code. The path for discovering coercions has Python in it, but until (if ever) all Parents are re-written in Cython this isn't going to be fully optimal anyways. And it only happens once (compared to the old model where it happened every single time a coercion was needed). Of course, much of the discover part could and should be optimized. But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) I would be significantly less upset with it then I am now where people tell me that if I need more speed I'm out of luck. That's not the message I'm trying to send--I'm sure there's room for improvement (though I have a strong distaste for hard-coding special cases in all over the place). I don't think make everything Cython is going to solve the problem... I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. Sure, its kindof ugly, but it will give us the performance we need, and I don't see a better way to allow us to use coercions all over the place without having performance drop to 0. One may be able to eek out a bit more performance by doing this, but it's not as if performance is awful in the current model. For the things you do. There is no code that pushes the coercion system anywhere near as much as symbolics in Sage does. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
One may be able to eek out a bit more performance by doing this, but it's not as if performance is awful in the current model. For the things you do. There is no code that pushes the coercion system anywhere near as much as symbolics in Sage does. Please explain why the symbolics code is any more taxing on the coercion system than the existing code. Nick --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 4:39 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 3:08 PM, Gary Furnish wrote: On Tue, Jun 3, 2008 at 2:48 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: When a new morphism is created it needs a parent, which is a Homset that may be looked up/created at that time. This is probably what you are talking about. However, this is a single (tiny) constant overhead over the entire runtime of Sage. I'm sure this could be further optimized, but creating all the homsets ZZ - QQ - RR - CC, etc. will be done long before any symbolic code gets hit. This is not what I'm talking about. What I'm talking about is you can't access members of homset without leaving cython and using python. Of course homsets could be optimized, but once created they aren't used in the coercion itself. I don't know why you'd need to access the members of homset unless you were doing some very high-level programming. The domain and codomain are cdef attributes of Morphisms, which are in Cython (and that took a fair amount of work as they was a lot of MI going on with them until a year ago). I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. No, I consider categories to be good. I consider bad implementations of categories to be bad. Implementations that make extensive use of MI and are thus impossible to cythonize or access without py dict lookups are not good implementations of categories. That depends on what they are being used for, but categories lend themselves very naturally to multiple inheritance because of what they are mathematically. I understand wanting, .e.g., arithmetic to be super fast, but I don't see the gain in hacks/code duplication to strip out multiple inheritance from and cythonize categories. Python is a beautiful language, but it comes with a cost (e.g. dict lookups). Other than initial homset creation, what would be faster (for you) if homsets and categories were written in Cython? If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), The critical path for doing arithmetic between elements is 100% pure Cython code. The path for discovering coercions has Python in it, but until (if ever) all Parents are re-written in Cython this isn't going to be fully optimal anyways. And it only happens once (compared to the old model where it happened every single time a coercion was needed). But I don't have elements, I have variables that represent elements. Maybe the solution here is to run an_element on each parent and then multiply them (and in fact I do this as a last case resort) and then get the parent of the result, but this is a pretty bad way to do things as it requires construction of elements during coercion. Furthermore, this isn't even implemented in some classes, the default is written in python, etc. Even if those issues were dealt with, having to multiply two elements to figure out where the result is a bad design. Of course, much of the discover part could and should be optimized. But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) I would be significantly less upset with it then I am now where people tell me that if I need more speed I'm out of luck. That's not the message I'm trying to send--I'm sure there's room for improvement (though I have a strong distaste for hard-coding special cases in all over the place). I don't think make everything Cython is going to solve the problem... No but special cases/writing my own fast coercion code seems to work significantly better then trying to use your system. This is definitely a bad situation, because we shouldn't need another set of coercion codes that deal with the cases where the main coercion code is too slow. Either coercion has to be designed to be fast, or symbolics is going to have to reach into the innards of the coercion framework to make it possible to deal with quickly. It would be even better if we could have symbolicring over RR or symbolicring over ZZ or what not, but this is 100% impossible unless the coercion framework is done 100% in cython, with special cases, with speed as a top priority instead of beauty. I'm also -1 for hard-coding knowledge and logic about ZZ,QQ, etc into the coercion model. I am +1 for hardcoding it into the elements of say, ZZ,QQ,RR and then having them call the coercion model only if those hardcodes can't figure the situation out. That sounds much better, though I'm still not a fan. Sure, its kindof ugly, but it will give us the performance we need, and I don't see a better way to allow us to use coercions all over the place without having
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 5:48 PM, William Stein wrote: On Tue, Jun 3, 2008 at 2:45 PM, Bill Page wrote: On Tue, Jun 3, 2008 at 4:48 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: ... I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. Absolutely! :-) BTW, where can I read more about these categorical concepts that are currently built-in or planned for Sage? This is very relevant: http://wiki.sagemath.org/days7/coercion Thanks for the reference. No mention of homsets here. :-( Only one mention in /days7/coercion/todo ... But reading this makes me feel a little, well ah, light-headed. At best it seems like something very hastily grafted-on to the design. Is this part of Sage about which you would like comments and more discussion? Or is there more information somewhere that I am missing? I am afraid that there is not much here that category theorists are likely to find interesting. I have many many questions, but mostly I wonder what the overall intention of this construction really is in Sage? Is it only relevant to coercion? How does it related to the concept of parent - which seems equally ill-defined to me? What is the relationship to inheritance in Python? Is the intention to give all mathematical objects defined in Sage some categorical structure? What about categories themselves as mathematical structures - e.g. a category is a kind of directed graph with additional structure? Regards, Bill Page. --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 4, 12:39 am, Robert Bradshaw [EMAIL PROTECTED] wrote: SNIP Hi, If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), The critical path for doing arithmetic between elements is 100% pure Cython code. The path for discovering coercions has Python in it, but until (if ever) all Parents are re-written in Cython this isn't going to be fully optimal anyways. And it only happens once (compared to the old model where it happened every single time a coercion was needed). Of course, much of the discover part could and should be optimized. But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) I have to side with Robert here. Symbolics is not going to get merged before the coercion rewrite since the coercion rewrite has been going on much longer and there is substantial effort in there that is also highly desired by the sage-combinat people for example. Once coercion is in [hopefully around Dev1] it is desired to improve the existing code [I am not qualified to speculate here what can and will be done in that regard] and I am sure that Robert, Gary and everybody else interested will find some time during Dev1 to sit down and look at the code together to come up with a workable solution. Sage is about incremental improvements and we should remember: The perfect is the enemy of the good ;) I know very, very well that Gary is very serious about performance and that what he considers fast is way beyond the normal expectation. His effort to achieve this is beyond what most people would consider reasonable and I am very glad he is working on Symbolics ;) So let's not get into an intense discussion here and now since that will not resolve any problem. SNIP Cheers, Michael --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 4:36 PM, Gary Furnish wrote: That depends on what they are being used for, but categories lend themselves very naturally to multiple inheritance because of what they are mathematically. I understand wanting, .e.g., arithmetic to be super fast, but I don't see the gain in hacks/code duplication to strip out multiple inheritance from and cythonize categories. Python is a beautiful language, but it comes with a cost (e.g. dict lookups). Other than initial homset creation, what would be faster (for you) if homsets and categories were written in Cython? If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), The critical path for doing arithmetic between elements is 100% pure Cython code. The path for discovering coercions has Python in it, but until (if ever) all Parents are re-written in Cython this isn't going to be fully optimal anyways. And it only happens once (compared to the old model where it happened every single time a coercion was needed). But I don't have elements, I have variables that represent elements. Maybe the solution here is to run an_element on each parent and then multiply them (and in fact I do this as a last case resort) and then get the parent of the result, but this is a pretty bad way to do things as it requires construction of elements during coercion. Furthermore, this isn't even implemented in some classes, the default is written in python, etc. Even if those issues were dealt with, having to multiply two elements to figure out where the result is a bad design. Ah, yes. We talked about this before, and I implemented the analyse and explain functions which carefully avoid all Python: http://cython.org/coercion/hgwebdir.cgi/sage-coerce/rev/1a5c8ccfd0df Of course, much of the discover part could and should be optimized. But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) I would be significantly less upset with it then I am now where people tell me that if I need more speed I'm out of luck. That's not the message I'm trying to send--I'm sure there's room for improvement (though I have a strong distaste for hard-coding special cases in all over the place). I don't think make everything Cython is going to solve the problem... No but special cases/writing my own fast coercion code seems to work significantly better then trying to use your system. Writing a huge number of special cases is almost always going to be faster, not doubt about it. The Sage coercion code needs to be extremely generic as it handles all kinds of objects (and I'm excited to have symbolics that respect this). This is definitely a bad situation, because we shouldn't need another set of coercion codes that deal with the cases where the main coercion code is too slow. Yes. Either coercion has to be designed to be fast, or symbolics is going to have to reach into the innards of the coercion framework to make it possible to deal with quickly. It would be even better if we could have symbolicring over RR or symbolicring over ZZ or what not, but this is 100% impossible unless the coercion framework is done 100% in cython, with special cases, with speed as a top priority instead of beauty. Would it be 95% possible if it's 95% written in Cython, with only a 5% performance hit :-). The best balance I see is you can hard code ZZ/RR/... for speed if you want (you're worried about virtual function calls anyways), and then call off to coercion in the generic cases. You're going to have to do this a bit anyways, as the coercion model doesn't handle stuff like where is the sin(x) if x is in R? which is handled via the normal OO sense based on the type of x (and may depend on x). To help with collaboration, what you want out of the coercion model is, given R and S (and an operation op), what will be the result of op between elements of R and S, and you want this to be as fast as possible (e.g. 100% Cython, no homsets, ...). - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Tue, Jun 3, 2008 at 7:21 PM, Robert Bradshaw [EMAIL PROTECTED] wrote: On Jun 3, 2008, at 4:36 PM, Gary Furnish wrote: That depends on what they are being used for, but categories lend themselves very naturally to multiple inheritance because of what they are mathematically. I understand wanting, .e.g., arithmetic to be super fast, but I don't see the gain in hacks/code duplication to strip out multiple inheritance from and cythonize categories. Python is a beautiful language, but it comes with a cost (e.g. dict lookups). Other than initial homset creation, what would be faster (for you) if homsets and categories were written in Cython? If coercion was implemented with 100% pure Cython code (with an eye for speed where it is needed), The critical path for doing arithmetic between elements is 100% pure Cython code. The path for discovering coercions has Python in it, but until (if ever) all Parents are re-written in Cython this isn't going to be fully optimal anyways. And it only happens once (compared to the old model where it happened every single time a coercion was needed). But I don't have elements, I have variables that represent elements. Maybe the solution here is to run an_element on each parent and then multiply them (and in fact I do this as a last case resort) and then get the parent of the result, but this is a pretty bad way to do things as it requires construction of elements during coercion. Furthermore, this isn't even implemented in some classes, the default is written in python, etc. Even if those issues were dealt with, having to multiply two elements to figure out where the result is a bad design. Ah, yes. We talked about this before, and I implemented the analyse and explain functions which carefully avoid all Python: http://cython.org/coercion/hgwebdir.cgi/sage-coerce/rev/1a5c8ccfd0df Of course, much of the discover part could and should be optimized. But right now we've already got enough on our plate trying to get the changes we have pushed through. (Any help on this front would be greatly appreciated.) I would be significantly less upset with it then I am now where people tell me that if I need more speed I'm out of luck. That's not the message I'm trying to send--I'm sure there's room for improvement (though I have a strong distaste for hard-coding special cases in all over the place). I don't think make everything Cython is going to solve the problem... No but special cases/writing my own fast coercion code seems to work significantly better then trying to use your system. Writing a huge number of special cases is almost always going to be faster, not doubt about it. The Sage coercion code needs to be extremely generic as it handles all kinds of objects (and I'm excited to have symbolics that respect this). This is definitely a bad situation, because we shouldn't need another set of coercion codes that deal with the cases where the main coercion code is too slow. Yes. Either coercion has to be designed to be fast, or symbolics is going to have to reach into the innards of the coercion framework to make it possible to deal with quickly. It would be even better if we could have symbolicring over RR or symbolicring over ZZ or what not, but this is 100% impossible unless the coercion framework is done 100% in cython, with special cases, with speed as a top priority instead of beauty. Would it be 95% possible if it's 95% written in Cython, with only a 5% performance hit :-). The best balance I see is you can hard code ZZ/RR/... for speed if you want (you're worried about virtual function calls anyways), and then call off to coercion in the generic cases. You're going to have to do this a bit anyways, as the coercion model doesn't handle stuff like where is the sin(x) if x is in R? which is handled via the normal OO sense based on the type of x (and may depend on x). To help with collaboration, what you want out of the coercion model is, given R and S (and an operation op), what will be the result of op between elements of R and S, and you want this to be as fast as possible (e.g. 100% Cython, no homsets, ...). Correct - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 4:50 PM, Bill Page wrote: On Tue, Jun 3, 2008 at 5:48 PM, William Stein wrote: On Tue, Jun 3, 2008 at 2:45 PM, Bill Page wrote: On Tue, Jun 3, 2008 at 4:48 PM, Robert Bradshaw wrote: On Jun 3, 2008, at 11:17 AM, Gary Furnish wrote: ... I consider homsets to be a gigantic flaw in coercion that absolutely have to be fixed for me to consider using more of the coercion system in symbolics. Ironically, other people see it as a plus that coercion has been given a more categorical founding. Absolutely! :-) BTW, where can I read more about these categorical concepts that are currently built-in or planned for Sage? This is very relevant: http://wiki.sagemath.org/days7/coercion Thanks for the reference. No mention of homsets here. :-( Only one mention in /days7/coercion/todo ... But reading this makes me feel a little, well ah, light-headed. At best it seems like something very hastily grafted-on to the design. Is this part of Sage about which you would like comments and more discussion? Or is there more information somewhere that I am missing? The discussion on that page is (unfortunately) best understood by someone who already is fairly familiar with Sage. It will also probably be re-written/cleaned up now that it has been implemented... I am afraid that there is not much here that category theorists are likely to find interesting. I have many many questions, but mostly I wonder what the overall intention of this construction really is in Sage? Is it only relevant to coercion? The interesting coercion stuff (in my opinion) was all done last June, and much of the work outlined here is trying to unify the API and make things more consistent across all of Sage (though there is more than just that). How does it related to the concept of parent - which seems equally ill-defined to me? A Parent is an Object in the category of Sets, though in the context of coercion one usually assumes one can some kind of arithmetic (binary operations) on their elements. What is the relationship to inheritance in Python? Is the intention to give all mathematical objects defined in Sage some categorical structure? What about categories themselves as mathematical structures - e.g. a category is a kind of directed graph with additional structure? A big push of this model is to divorce the relationship between inheritance (which primarily has to do with implementation) and mathematical categorization. This will allow categories to play a larger role (though work in that area can be done after the merge as it is not disruptive). For example, Z/nZ[x] is implemented the same whether or not p is a prime, but the category it lives in (and hence the methods one can do on it) vary. As another example, matrix spaces are algebras iff they are square, but one doesn't want to have a special class for square matrices over insert optimized type here. Generic algorithms can be put on the categories such that if g is in category C, and C has a method x, then g.x() will work. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 10:04 PM, Robert Bradshaw wrote: How does it related to the concept of parent - which seems equally ill-defined to me? A Parent is an Object in the category of Sets, huh? Don't you mean to say something more like a parent is an object of a concrete category, i.e. a category C with a faithful functor f : C - Set, such that the elements (as understood by Sage) of the parent P are exactly the elements of f(P)? though in the context of coercion one usually assumes one can some kind of arithmetic (binary operations) on their elements. david --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---
[sage-devel] Re: coercing of sqrt(2)
On Jun 3, 2008, at 7:11 PM, David Harvey wrote: On Jun 3, 2008, at 10:04 PM, Robert Bradshaw wrote: How does it related to the concept of parent - which seems equally ill-defined to me? A Parent is an Object in the category of Sets, huh? Don't you mean to say something more like a parent is an object of a concrete category, i.e. a category C with a faithful functor f : C - Set, such that the elements (as understood by Sage) of the parent P are exactly the elements of f(P)? Yes, that is a much more precise (and correct) explanation of what I meant. - Robert --~--~-~--~~~---~--~~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~--~~~~--~~--~--~---