sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.44k stars 481 forks source link

Squares not working in completion of free algebra #37625

Closed fchapoton closed 7 months ago

fchapoton commented 7 months ago

Steps To Reproduce

sage: R=algebras.Free(QQ,('A','B'),degrees=(1,2))
sage: Rc=R.completion()
sage: A,B=R.gens()
sage: Rc(A)+1
1 + A
sage: Rc(A)**2
...
TypeError: unable to convert (A,) to a rational

Expected Behavior

This should return A^2

Actual Behavior

raise TypeError

Additional Information

No response

Environment

- **OS**:ubuntu 22.04
- **Sage Version**:10.3.rc4

Checklist

fchapoton commented 7 months ago

@mantepse (for the record)

mantepse commented 7 months ago

The problem is as follows. We describe terminating elements (i.e., elements that have finite degree, and all coefficients are known) of the completion of a non-commutative algebra as elements of self._internal_poly_ring = FreeAlgebra(self._laurent_poly_ring, 1, "DUMMY_VARIABLE"), whereas in the commutative case we use self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE", sparse=sparse).

The latter supports the construction of an element from a tuple. For example:

sage: QQ["DUMMMY"]((1,2,3,4))
4*DUMMMY^3 + 3*DUMMMY^2 + 2*DUMMMY + 1

The former doesn't:

sage: FreeAlgebra(QQ, 1, "DUMMY")((1,2,3))
...
TypeError: unable to convert (1, 2, 3) to a rational
mantepse commented 7 months ago

I actually don't see the reason why we did this:

e7bf85306d1e src/sage/rings/lazy_series_ring.py         (Martin Rubey      2022-07-27 18:50:34 +0530 2740)         self._laurent_poly_ring = basis
dff4fc4b7ecd src/sage/rings/lazy_series_ring.py         (Travis Scrimshaw  2022-08-22 18:44:28 +0900 2741)         if self._laurent_poly_ring not in Rings().Commutative():
dff4fc4b7ecd src/sage/rings/lazy_series_ring.py         (Travis Scrimshaw  2022-08-22 18:44:28 +0900 2742)             from sage.algebras.free_algebra import FreeAlgebra
dff4fc4b7ecd src/sage/rings/lazy_series_ring.py         (Travis Scrimshaw  2022-08-22 18:44:28 +0900 2743)             self._internal_poly_ring = FreeAlgebra(self._laurent_poly_ring, 1, "DUMMY_VARIABLE")
dff4fc4b7ecd src/sage/rings/lazy_series_ring.py         (Travis Scrimshaw  2022-08-22 18:44:28 +0900 2744)         else:
de424bd78aab src/sage/rings/lazy_series_ring.py         (Martin Rubey      2022-10-13 08:50:39 +0200 2745)             self._internal_poly_ring = PolynomialRing(self._laurent_poly_ring, "DUMMY_VARIABLE", sparse=sparse)

@tscrim, might this be a thinko?

tscrim commented 7 months ago

No, this is because we need to care about the order of the coefficient multiplication and the free algebra should make sure of that (or at least it doesn’t require the base ring to be commutative in contrast to the polynomial ring).

To fix this, we might want to have our own special class for univariate free algebras. This could be useful to speed up some things for general completions…

mantepse commented 7 months ago

Doesn't the polynomial ring support non-commutative base rings? I would have thought it does:

age: M = MatrixSpace(QQ, 2)                                                                                                                                 
sage: R.<x> = M[]                                                                                                                                            
sage: R                                                                                                                                                      
Univariate Polynomial Ring in x over Full MatrixSpace of 2 by 2 dense matrices over Rational Field                                                           
sage: m1 = matrix([[1,0],[1,1]])                                                                                                                             
sage: m2 = matrix([[1,1],[0,1]])                                                                                                                             
sage: m1*m2 - m2*m1                                                                                                                                          
[-1  0]                                                                                                                                                      
[ 0  1]                                                                                                                                                      
sage: p = m1*x + m2                                                                                                                                          
sage: q = m2*x + m1                                                                                                                                          
sage: list(p*q - q*p)
[
[ 1  0]  [0 0]  [-1  0]
[ 0 -1], [0 0], [ 0  1]
]
tscrim commented 7 months ago

The univariate polynomial ring says it supports noncommutative base rings, but I vaguely remember having issues with it when I tried it previously. Perhaps everything is fine, and I am just misremembering.