On Wed, Sep 18, 2013 at 3:19 PM, Peter Bruin <pjbr...@gmail.com> wrote: > Hi Robert, > > >> This dates back to before the category framework, when (normal) >> inheritance was the only way to get things like this. Yes, it should >> be fixed! > > > I'll open a ticket for it. > >> > Shouldn't there be a class >> > SquareMatrix for methods like is_invertible() and determinant()? >> >> Currently there are many different matrix implementations specialized >> on the basering for efficiency (e.g. finite fields of various sizes, >> ZZ, QQ, number fields, etc.) Would you suggest that we create >> SquareIntegerMatrix, SquareRationalMatrix, etc? > > Good question. Given that we have, for example, a specific function for > computing the determinant of a square dense matrix over the integers, and > there is no specific class for such matrices, either such a class has to be > made (split off from the class of such matrices that are not necessarily > square) or we have to accept that this specific function cannot be applied > to all elements that it is a method of.
One convention is to have a level of redirection, e.g. integer matrices provide a determinant() method, and the category element provides determinant() which calls _determinant() which has an actual generic implementation. > And maybe it is actually more > user-friendly in this case: it is nicer to get an error message telling you > that you are trying to take the determinant of a non-square matrix than the > AttributeError that would arise if non-square matrices didn't have a > determinant method at all. Perhaps. But on the other hand it'd be nice for it not to show up in tab completion. >> Of course to spare >> some work one would want a common SquareMatrix that all of these >> (multiply) inherit from. (One technicality is that SquareMatrix could >> not inherit from RingElement if the base IntegerMatrix class does not >> as they would have incompatible C layouts.) > > That is also a good point, and one that seems hard to solve. > >> Also, this seems like a >> lot of busywork--we should be able to automatically generate these >> classes for any matrix type when nrows == ncols. But this is exactly >> what the category framework gives you (though it could have done so >> with a more sophisticated getattr rather than dynamically-constructed >> types). > > But how would the category framework automatically construct a class for > square integer dense matrices, for example? It would still have to know > where to get the specialised determinant function from. That's what it does now, by multiple inheritance. It does not provide specialized implementations, only generic ones. >> Another good example of this is polynomials. There are various >> sparse/dense representations implemented over various representations >> of rings. Whether this is a UDF or PID depends on the category of the >> basering, trying to (manually) bake this into the inheritance of >> elements is painful. But there are some methods that can be >> *automatically* provided if the category is right (e.g. gcd). > > I don't understand this. Whether the polynomial ring is a UFD or PID > depends on the base ring, and that is it. I don't see why it matters in > which category you put it. In practice, I think the following rules are > often enough: for a ring A, one has > A is a field => A is Euclidean => A is a PID => A is a UFD > A is a field => A[x] is Euclidean > A is a UFD => A[x] is a UFD > You seem to be saying one of two things, and I'm not sure which: > - either your phrase "depends on the category of the basering" has the same > meaning as "depends on whether the basering is a UFD, PID, etc."; Yes, exactly. Basering is a UFD is a statement about its category. > - or you mean that for the same ring A, elements of A[x] should use a > different gcd implementation depending on whether the user has put A into a > larger category (so that the gcd of two polynomials is computed by factoring > them instead of via the Euclidean algorithm). The user "putting A into a category" is how one determines if A is a PID (see above). Of course most rings would just "know" this information. As a concrete example, we have special implementations for elements of Z/nZ[x] for word-size n and non-word-sized n. It doesn't make as much sense to have a special subclass (of each) for when n is prime. Double-inheriting from EuclideanDomainElement (ignoring any technical difficulties). Essentially EuclideanDomainElement becomes EuclideanDomain.Element instead. >> The primary advantage of RingElement vs Rings().ElementMethods is that >> one can place cdef methods on the former, in particular to provide >> fast paths for arithmetic and the coercion system (including its >> special relationship to ModuleElement). Ideally nothing >> category-specific should go here (though there should be a big comment >> at the top that Rings().ElementMethods is a common parent for all >> RingElements) and actual ring element implementations could descend >> from RingElement or not as needed/as the implementation allows. In >> fact, there is very little in RingElement that's not about arithmetic >> and the coercion model, it could probably be all moved out (with a >> clear reference in the docstring about Rings().ElementMethods, and in >> the Element class as well). In particular, the mostly-vacuous >> hierarchy and deceptive is_X methods starting at >> >> https://github.com/sagemath/sage/blob/8118b2b39e3a129a5a6186fdc9917940f92b87a6/src/sage/structure/element.pyx#L2767 >> should probably be stripped out. > > > At least for the is_X methods that just use isinstance, I agree that they > should go away; I am not so sure about the XElement hierarchy. What value does it provide? -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/groups/opt_out.