Hej Johan, It indeed seems to be at the core of a wider problem. The core of the problem seems that sometimes you can represent various objects in different ways.
- So in the coding theory example you can represent a general linear code by a generator matrix. While you can represent a cyclic linear code by a generator polynomial. - In real_lazy you represent sqrt(2) as an algebraic element. But you want to execute functions on it's binary representation (1.011010100 etc.). - In linear algebra you can represent a matrix as a sparse or a dense matrix. - In commutative algebra you can represent a polynomial in a sparse or a dense way. - More suggestions are welcome :) In all these cases you might sometimes want to execute functions as implemented for the other representation. The big question of this topic was how to nicely make these functions available as attributes without breaking class inheritance and docstrings. I guess the best solution suggested is Robert Bradshaw's solution. It would be nice to have a working example of it's suggestion to be able to test it. And maybe also add a section to the "structuring code in Sage" part in the sage developers guide. @Johan, is the problem I describe here the only one that was mentioned in the other google thread or are there more? Kind Regards Maarten Derickx On Aug 11, 10:31 am, "Johan S. R. Nielsen" <[email protected]> wrote: > I actually think that the part of the discussion relating to > inheritance and scalability is quite fundamental for the structuring > of Sage. The problem is -- at its core -- that we have an object > which, in object-oriented eyes, _is_ a RingElement but we want to call > the computationally efficient implementation on the real numbers. > Thus, in a way, clean object-oriented structuring clashes with the > need for efficiency. From another perspective, the object is both a > RingElement and a Real number, but we want to choose the > implementation to use. I am new to sage, but I am absolutely certain > that this happens all the time. I guess that some of these issues were > discussed and decided upon when choosing the aforementioned category > framework. It reminds me of many of the concerns in the discussion for > a framework for error-correcting codes in this > threadhttp://groups.google.com/group/sage-devel/browse_thread/thread/4cd3ec.... > > I like Robert's solution on populating the attributes at class load > time. I don't yet understand enough Python to see the exact details, > but if it can be done, it can most likely be done flexibly. The > result should be exactly the same as when writing out all the > attributes with copy-paste but much less cluttered. There retains the > need for updating in the class whenever new, relevant functionality is > added to the real numbers, but I don't see any way around this > problem; at least in this case, the update will not be more than > adding a new attribute name in some array (like in the current code). > And, as with the current code, when new attributes are added to > RingElement or FieldElement, it is via inheritance added to > LazyFieldElement, except if it is one of those implemented over the > reals. > > Cheers, > Johan > > On Aug 10, 12:40 pm, koffie <[email protected]> wrote: > > > > > Hej Robert, > > > Your other implementation sounds interesting to. I would really love > > to see a lazy way which does work well together with class > > inheretance. I don't really know enough of the detailed working of > > python/cython to implement what you suggest. Are you willing to write > > a patch for this? > > If not I will just submit the way I solved it (i.e. by handcoding all > > the methods) because that is at least a better working version then > > the current implementation (i.e. it does work well together with class > > inheretance, it has docstrings, and it also makes the functions > > visible for tab completion). > > > thanks in advance, > > Maarten Derickx > > > ps. I do think every single function which is implemented in the lazy > > way should be tested. It was only by chance that I discovered that I > > broke the sqrt function because that was one of the couple things > > which was tested in the __getattr__ docstring. Also the misspelled > > ceil/ciel thing would have been found when adding tests. > > > On Aug 6, 6:21 am, Robert Bradshaw <[email protected]> > > wrote: > > > > On Wed, Aug 4, 2010 at 5:19 AM, Marco Streng <[email protected]> > > > wrote: > > > > Robert Bradshaw schreef: > > > > >> What should be done is either fixing LazyNamedUnop to preserve > > > >> documentation, or populating these methods at class creation time > > > >> (rather than attribute lookup time, perhaps dynamically creating a > > > >> docstring for them). I don't think it's a good idea to hard code every > > > >> one of these methods, and the set of methods on RealNumbers will > > > >> grow/change over time, and that's a lot of redundant code. If you need > > > >> to do one or two (like sqrt) than that makes sense, but probably not a > > > >> good idea to do all of them. Verbose code takes resources (both human > > > >> and computer) to keep around. At least that's my $0.02. > > > > > Hi Robert, > > > > > Interesting solutions, but I see some problems with them. Possibly > > > > because > > > > of my own lack of experience, so maybe you can explain. > > > > > I don't understand how "fixing LazyNamedUnop to preserve documentation" > > > > helps. If sqrt gets defined in RingElement, then __getattr__ of > > > > LazyWrapper > > > > doesn't get called. Where does LazyNamedUnops appear in this story? > > > > This is orthogonal to the sqrt issue, I'm just pointing out something > > > that's broken. > > > > > Populating sqrt of LazyWrapper at class creation time is interesting. I > > > > assume you do that via its __init__ method. But how do you get around > > > > the > > > > following problems? > > > > Not __init__, at class creation (or perhaps module load) time. I > > > haven't looked into the details, this may be harder to do with a cdef > > > class but should be easy to do for a Python class. > > > > > * If a class HypotheticalObject extends LazyWrapper and has its own > > > > actual > > > > sqrt attribute, then that sqrt attribute gets overwritten at creation > > > > time > > > > as well, doesn't it? Preventing stuff like this from happening and (even > > > > worse) debugging whenever this happens is also a lot of work, isn't it? > > > > Is > > > > there a way to do what you suggest in a stable and not-too-complicated > > > > way? > > > > Not if it's part of the LazyWrapper class, rather than an instance > > > attribute. > > > > > * The methods created at class creation time must have documentation > > > > including examples. This documentation doesn't appear in the reference > > > > manual and these examples aren't doctested. How do you get this > > > > documentation in the reference manual and how to doctest these examples? > > > > Here I don't mean by copying them, because copies can be changed without > > > > changing the original. > > > > The reference manual is created via introspection, which would work > > > fine for such methods. A couple examples could be doctested in the > > > method creator function (if sin works, you don't really need to test > > > all the rest of the trig functions). The documentation would probably > > > be a sentence about the wrapper followed by the original function's > > > documentation. I haven't fleshed out the details, but I think it could > > > be done well. > > > > - Robert -- To post to this group, send an email to [email protected] To unsubscribe from this group, send an email to [email protected] For more options, visit this group at http://groups.google.com/group/sage-devel URL: http://www.sagemath.org
