Re: [sage-combinat-devel] Re: Inversion of matrix...

2013-09-05 Thread Nicolas Borie

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...

2013-09-04 Thread Vincent Delecroix
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...

2013-09-04 Thread Nicolas Borie

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...

2013-09-03 Thread Simon King
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...

2013-09-03 Thread Nicolas Borie

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...

2013-09-03 Thread Simon King
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.