Re: [sage-combinat-devel] Re: Inversion of matrix...
Hi all, Thanks you Simon for the time you spent to give answers. Thanks you also Vincent for the suggestion. I have now a trac number : http://trac.sagemath.org/ticket/15160 Feel free to rephrase the ticket description or modify anything (still my English...). This is far from final but partial results may interest some people in the combinat community. The suggestion and advises can now go to the trac ticket. I am still motivated to do the job but alone, It will remains too hard for me so thanks you Simon for having describe how attack this problem. I just uploaded a drafty patch with some tests but no documentation. Before this small patch, once cannot multiply a scalar and a matrix if the coefficient didn't inherit from RingElement. Now, here is a small log of what can be done : * sage: from sage.matrix.matrix_space import test_special_ring sage: test_special_ring(verbose=True) Test with : An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field Let M be an invertible matrix: [ B[word: ] B[word: b] B[word: a]] [ 0 B[word: ] B[word: ab]] [ 0 0 B[word: ]] Here is the invert computed: [ B[word: ]-B[word: b] -B[word: a] + B[word: bab]] [ 0 B[word: ] -B[word: ab]] [ 0 0 B[word: ]] inversion OK Test with : Symmetric Functions over Rational Field in the Schur basis Let M be an invertible matrix: [ s[] s[2] s[]] [ 0 s[] s[1]] [ 00 s[]] Here is the invert computed: [ s[] -s[2] -s[] + s[2, 1] + s[3]] [0 s[] -s[1]] [0 0 s[]] inversion OK Test with : An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field Let M be an invertible matrix: [ B[()] B[(1,2,3)] B[(1,3,2)]] [ 0 B[()] B[(1,3)]] [ 0 0 B[()]] Here is the invert computed: [B[()] -B[(1,2,3)] B[(1,2)] - B[(1,3,2)]] [0 B[()] -B[(1,3)]] [0 0 B[()]] inversion OK Test with : Group algebra of Symmetric group of order 4! as a permutation group over Rational Field Let M be an invertible matrix: [ B[()] 0 0] [B[(2,3,4)] B[()] 0] [B[(2,4,3)] B[(2,4)] B[()]] Here is the invert computed: [B[()] 0 0] [ -B[(2,3,4)] B[()] 0] [B[(3,4)] - B[(2,4,3)] -B[(2,4)] B[()]] inversion OK Test with : Non-Commutative Symmetric Functions over the Rational Field in the Phi basis Let M be an invertible matrix: [ Phi[] Phi[2, 1, 2] Phi[3]] [ 0Phi[] Phi[1, 0, 1]] [ 00Phi[]] Here is the invert computed: [ Phi[] -Phi[2, 1, 2] Phi[2, 1, 2, 1, 0, 1] - Phi[3]] [ 0 Phi[] -Phi[1, 0, 1]] [ 0 0 Phi[]] inversion OK * Inversion OK means that the result was the right answer. Note also that the first and last example are in the non-commutative world. Feel free to comments (ok on the trac or on this list if you prefer) what I already done to allows me to continue in a good way. Cheers, Nicolas B. -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-combinat-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-combinat-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-combinat-devel. For more options, visit https://groups.google.com/groups/opt_out.
Re: [sage-combinat-devel] Re: Inversion of matrix...
Hi Nicolas B., T. Monteil get the same problem in #10063 when he fixes the determinant. He used something like {{{ try: test = my_ring.is_field() except AttributeError: test = False }}} Vincent 2013/9/4 Nicolas Borie nicolas.bo...@univ-mlv.fr: On 03/09/2013 22:48, Simon King wrote: PS: - I recommend to *try* (no guarantee it will work) to create a new type of action A (inherit from sage.categories.action.Action). You need to implement its _call_ and _repr_name_, and I think that's all what is to do (but perhaps you'll find other examples of Action in Sage, so, try to learn from existing code). Typically, the _call_ method of the action A._call_(a,b) will rely on methods of a and b (in our application, a is element of the base ring and b is a matrix). And then, let MatrixSpace._get_action_ return A. Hello Simon et al, This way works ! But it overwrite the scalar multiplication for the other usuals ring. I just did a drafty implementation to check the coercion catch it... I also learn a lot about action, thanks for all your pointers Simon. For information, my drafty way to did it was exactly how Simon suggested but not in a very efficient way and using a new diagonal_matrix (should be homothétie in French but I doesn't know in English) : *** +def _get_action_(self, S, op=operator.mul, self_on_left=True): +r + +if self.has_coerce_map_from(self.base_ring()): +return None +if S == self.base_ring(): +return ActionFromBaseRing(self.base_ring(), self) +return None + +from sage.categories.action import Action + +class ActionFromBaseRing(Action): +r + +def _call_(self, elem, mat): +r + +P = mat.parent() +return P.diagonal_matrix(elem)*mat + *** I have now a scalar multiplication which is *really more* generic ( but ok, I should multiply each entries by the right scalar after having generated a copy ). However, I really think that polish Sage matrix spaces and matrices is a very hard job. I already fix two small problems, here is a status of Sage with this new action concerning some rings coming from Combinat: *** sage: C = AlgebrasWithBasis(QQ).example(); C An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: SF = SymmetricFunctions(QQ).schur(); SF Symmetric Functions over Rational Field in the Schur basis sage: SFx.y = PolynomialRing(SF, 'y') sage: Cz.z = PolynomialRing(C, 'z') sage: Id = identity_matrix(C, 2); C.an_element()*Id [B[word: ] + 2*B[word: a] + 3*B[word: b] 0] [ 0 B[word: ] + 2*B[word: a] + 3*B[word: b]] sage: Id = identity_matrix(SF, 2); SF.an_element()*Id [2*s[] + 2*s[1] + 3*s[2] 0] [ 0 2*s[] + 2*s[1] + 3*s[2]] sage: Id = identity_matrix(SFx, 2); SFx.an_element()*Id [s[]*y 0] [0 s[]*y] sage: Id = identity_matrix(Cz, 2); Cz.an_element()*Id [B[word: ]*z 0] [ 0 B[word: ]*z] *** Let us try to call the adjoint of the identity matrix : Free algebra with 3 generators : *** sage: Id = identity_matrix(C, 2); sage: Id.adjoint() --- AttributeErrorTraceback (most recent call last) ipython-input-39-8ec4e1fe1f2c in module() 1 Id.adjoint() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix.adjoint (sage/matrix/matrix2.c:40809)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix._adjoint (sage/matrix/matrix2.c:40996)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix.charpoly (sage/matrix/matrix2.c:11016)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/structure/parent.so in sage.structure.parent.Parent.__getattr__ (sage/structure/parent.c:6888)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/structure/misc.so in sage.structure.misc.getattr_from_other_class (sage/structure/misc.c:1606)() AttributeError: 'FreeAlgebra_with_category' object has no attribute 'is_field' *** Schur functions : *** sage: Id = identity_matrix(SF, 2); sage: Id.adjoint() --- TypeError Traceback (most recent call last)
Re: [sage-combinat-devel] Re: Inversion of matrix...
On 03/09/2013 22:48, Simon King wrote: PS: - I recommend to *try* (no guarantee it will work) to create a new type of action A (inherit from sage.categories.action.Action). You need to implement its _call_ and _repr_name_, and I think that's all what is to do (but perhaps you'll find other examples of Action in Sage, so, try to learn from existing code). Typically, the _call_ method of the action A._call_(a,b) will rely on methods of a and b (in our application, a is element of the base ring and b is a matrix). And then, let MatrixSpace._get_action_ return A. Hello Simon et al, This way works ! But it overwrite the scalar multiplication for the other usuals ring. I just did a drafty implementation to check the coercion catch it... I also learn a lot about action, thanks for all your pointers Simon. For information, my drafty way to did it was exactly how Simon suggested but not in a very efficient way and using a new diagonal_matrix (should be homothétie in French but I doesn't know in English) : *** +def _get_action_(self, S, op=operator.mul, self_on_left=True): +r + +if self.has_coerce_map_from(self.base_ring()): +return None +if S == self.base_ring(): +return ActionFromBaseRing(self.base_ring(), self) +return None + +from sage.categories.action import Action + +class ActionFromBaseRing(Action): +r + +def _call_(self, elem, mat): +r + +P = mat.parent() +return P.diagonal_matrix(elem)*mat + *** I have now a scalar multiplication which is *really more* generic ( but ok, I should multiply each entries by the right scalar after having generated a copy ). However, I really think that polish Sage matrix spaces and matrices is a very hard job. I already fix two small problems, here is a status of Sage with this new action concerning some rings coming from Combinat: *** sage: C = AlgebrasWithBasis(QQ).example(); C An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: SF = SymmetricFunctions(QQ).schur(); SF Symmetric Functions over Rational Field in the Schur basis sage: SFx.y = PolynomialRing(SF, 'y') sage: Cz.z = PolynomialRing(C, 'z') sage: Id = identity_matrix(C, 2); C.an_element()*Id [B[word: ] + 2*B[word: a] + 3*B[word: b] 0] [ 0 B[word: ] + 2*B[word: a] + 3*B[word: b]] sage: Id = identity_matrix(SF, 2); SF.an_element()*Id [2*s[] + 2*s[1] + 3*s[2] 0] [ 0 2*s[] + 2*s[1] + 3*s[2]] sage: Id = identity_matrix(SFx, 2); SFx.an_element()*Id [s[]*y 0] [0 s[]*y] sage: Id = identity_matrix(Cz, 2); Cz.an_element()*Id [B[word: ]*z 0] [ 0 B[word: ]*z] *** Let us try to call the adjoint of the identity matrix : Free algebra with 3 generators : *** sage: Id = identity_matrix(C, 2); sage: Id.adjoint() --- AttributeErrorTraceback (most recent call last) ipython-input-39-8ec4e1fe1f2c in module() 1 Id.adjoint() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix.adjoint (sage/matrix/matrix2.c:40809)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix._adjoint (sage/matrix/matrix2.c:40996)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix.charpoly (sage/matrix/matrix2.c:11016)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/structure/parent.so in sage.structure.parent.Parent.__getattr__ (sage/structure/parent.c:6888)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/structure/misc.so in sage.structure.misc.getattr_from_other_class (sage/structure/misc.c:1606)() AttributeError: 'FreeAlgebra_with_category' object has no attribute 'is_field' *** Schur functions : *** sage: Id = identity_matrix(SF, 2); sage: Id.adjoint() --- TypeError Traceback (most recent call last) ipython-input-41-8ec4e1fe1f2c in module() 1 Id.adjoint() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so in sage.matrix.matrix2.Matrix.adjoint (sage/matrix/matrix2.c:40809)() /home/nborie/sage/local/lib/python2.7/site-packages/sage/matrix/matrix2.so
[sage-combinat-devel] Re: Inversion of matrix...
Hi Nicolas, On 2013-09-03, Nicolas Borie nicolas.bo...@univ-mlv.fr wrote: For now : *** sage: SF = SymmetricFunctions(QQ).schur() sage: Id = identity_matrix(SF, 2); Id [s[] 0] [ 0 s[]] sage: Id.inverse() Traceback (most recent call last): ... AttributeError: 'SymmetricFunctionAlgebra_schur_with_category' object has no attribute 'fraction_field' Why does it not have it? I see that there is a general definition in sage.rings.ring.Ring (from which SymmetricFunctions do not inherit). But why did nobody think of providing a parent method for IntegralDomains() ?? Aha! I just notice that matrix spaces don't know whether they are integral domains... So, one approach would be to be more careful in choosing the category in __init__. Perhaps due to the fact that : *** sage: Id [s[] 0] [ 0 s[]] sage: P = Id.parent(); P Full MatrixSpace of 2 by 2 dense matrices over Symmetric Functions over Rational Field in the Schur basis sage: P.has_coerce_map_from(SF) False *** Whow. This sounds like a serious bug to me. sage: MS = MatrixSpace(SymmetricFunctions(QQ),3) sage: MS.has_coerce_map_from(MS.base_ring()) False sage: MS in Algebras(MS.base_ring()) True Shouldn't there always be a coercion from the base ring into a unital algebra? It seems to me that the underlying problem is that matrix spaces do not properly use the new coercion model (in particular, they define their own __call__, how nasty!). Let's fix some compatibility bug with Combinatorial free module (because SF['x'] doesn't means polynomial in x over SF in combinat world but return a ValueError explaining that ['x'] is not a valid partition) What? Why should it *not* return a polynomial ring? Is it perhaps misused to return an element (which would be the job of SF('x') rather than of SF['x'])? And why should __getitem__ expect a valid partition? Moreover, I get a different error: sage: SF = SymmetricFunctions(QQ) sage: SF['x'] Traceback (most recent call last): ... AttributeError: 'SymmetricFunctions_with_category' object has no attribute 'list' and had a nice coercion, I still have the same error. But the sage matrix spaces use some category (the some is very important I guess but that already go further than my knowledge... Why do you say some? If a matrix space over a ring R is quadaratic, then it is an R-Algebra, otherwise just an R-Module. What else would you expect? [edit: Perhaps it should also be IntegralDomains() in some cases...] I do not know anything with old category framework...): Is there an old category framework? There only is an old coercion framework, as far as I know... *** sage: SF = SymmetricFunctions(QQ).schur() sage: Id = identity_matrix(SF, 2); Id [s[] 0] [ 0 s[]] sage: P = Id.parent() sage: P.category() Category of algebras over Symmetric Functions over Rational Field in the Schur basis sage: P.__class__.mro() [sage.matrix.matrix_space.MatrixSpace, sage.structure.unique_representation.UniqueRepresentation, sage.structure.unique_representation.CachedRepresentation, sage.misc.fast_methods.WithEqualityById, sage.structure.parent_gens.ParentWithGens, sage.structure.parent_base.ParentWithBase, sage.structure.parent_old.Parent, sage.structure.parent.Parent, sage.structure.category_object.CategoryObject, sage.structure.sage_object.SageObject, object] That's because category initialisation of matrix spaces is lazy. There are applications in which it really matters to not inititialise the category during initialisation of the matrix space: Only CategoryObject._init_category_ is executed, but not Parent._init_category_. See the method MS.full_category_initialisation(). So, I need some advises to fix that... And currently, I find very hard to evaluate the difficulty to do it without an horrible hack since : - the class sage/matric/matrix_space.MatrixSpace seems to present problem with inheritance... - this code seems to not be new category framework compatible It is, as soon as you call full_category_initialisation() in those cases that really make use of the category. I also didn't find where was implemented usual coercions between rings and their corresponding matrix_space (ZZ, QQ, ...) There *should* be no __call__ in MatrixSpace, and instead there *should* be the usual things (an _element_constructor_, and _coerce_map_from_). In this way, one would have a coercion. Another consequence of postponed category initialisation: There is a parent method __init_extra__ of Algebras(...), which establishes the creation of a coercion from the base ring to the algebra, but which isn't called because of postponing category initialisation. Since there are applications in which category
Re: [sage-combinat-devel] Re: Inversion of matrix...
On 03/09/2013 22:48, Simon King wrote: PS: On 2013-09-03, Simon King simon.k...@uni-jena.de wrote: Shouldn't there always be a coercion from the base ring into a unital algebra? It seems to me that the underlying problem is that matrix spaces do not properly use the new coercion model (in particular, they define their own __call__, how nasty!). Looking at what I wrote later in my previous post, I think this is *not* the problem. Since the previous post was so long, here is a summary: - For efficience reasons, we do not want full category initialisation during __init__ (please don't change this, unless you want to mess with the number theorists...) = __init_extra__ of Algebras.ParentMethods is not called = one needs to establish an action from the base ring manually - The category *is* initialised for CategoryObject, but just not for Parent. It would be a good idea to check whether IntegralDomains() could be used in the category, since this is needed for FractionField to be defined. - The usual framework for actions of a base ring on a module relies on cpdef methods _rmul_ and _lmul_. Problem: These expect their input of a particular type, that is often *not* used in sage.combinat. - I recommend to *try* (no guarantee it will work) to create a new type of action A (inherit from sage.categories.action.Action). You need to implement its _call_ and _repr_name_, and I think that's all what is to do (but perhaps you'll find other examples of Action in Sage, so, try to learn from existing code). Typically, the _call_ method of the action A._call_(a,b) will rely on methods of a and b (in our application, a is element of the base ring and b is a matrix). And then, let MatrixSpace._get_action_ return A. Hope the short version of my post was helpful :) Best regards, Simon Thanks you very much for these two long and detailed posts... I will try to reread them carefully tomorrow and propose some patch shortly... I will post a patch number on this thread when I will have something interesting. Thanks you Simon. Cheers, Nicolas B. -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-combinat-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-combinat-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-combinat-devel. For more options, visit https://groups.google.com/groups/opt_out.
[sage-combinat-devel] Re: Inversion of matrix...
PS: On 2013-09-03, Simon King simon.k...@uni-jena.de wrote: Shouldn't there always be a coercion from the base ring into a unital algebra? It seems to me that the underlying problem is that matrix spaces do not properly use the new coercion model (in particular, they define their own __call__, how nasty!). Looking at what I wrote later in my previous post, I think this is *not* the problem. Since the previous post was so long, here is a summary: - For efficience reasons, we do not want full category initialisation during __init__ (please don't change this, unless you want to mess with the number theorists...) = __init_extra__ of Algebras.ParentMethods is not called = one needs to establish an action from the base ring manually - The category *is* initialised for CategoryObject, but just not for Parent. It would be a good idea to check whether IntegralDomains() could be used in the category, since this is needed for FractionField to be defined. - The usual framework for actions of a base ring on a module relies on cpdef methods _rmul_ and _lmul_. Problem: These expect their input of a particular type, that is often *not* used in sage.combinat. - I recommend to *try* (no guarantee it will work) to create a new type of action A (inherit from sage.categories.action.Action). You need to implement its _call_ and _repr_name_, and I think that's all what is to do (but perhaps you'll find other examples of Action in Sage, so, try to learn from existing code). Typically, the _call_ method of the action A._call_(a,b) will rely on methods of a and b (in our application, a is element of the base ring and b is a matrix). And then, let MatrixSpace._get_action_ return A. Hope the short version of my post was helpful :) Best regards, Simon -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-combinat-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-combinat-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-combinat-devel. For more options, visit https://groups.google.com/groups/opt_out.