@@ -1381,6 +1381,71 @@ cdef class SkewPolynomial(AlgebraElement):
1381
1381
A = A.left_monic()
1382
1382
return A
1383
1383
1384
+ def _left_lcm_cofactor (self , other ):
1385
+ R = self ._parent
1386
+ U = R.one()
1387
+ G = self
1388
+ V1 = R.zero()
1389
+ V3 = other
1390
+ while not V3.is_zero():
1391
+ Q, R = G.right_quo_rem(V3)
1392
+ T = U - Q* V1
1393
+ U = V1
1394
+ G = V3
1395
+ V1 = T
1396
+ V3 = R
1397
+ return V1
1398
+
1399
+ @coerce_binop
1400
+ def left_xlcm (self , other , monic = True ):
1401
+ r """
1402
+ Return the left lcm of ``self`` and ``other`` together
1403
+ with two skew polynomials `u` and `v` such that
1404
+ `u \c dot \t ext{self} = v \c dot \t ext{other} = \t ext{llcm``
1405
+ """
1406
+ if self .base_ring() not in Fields:
1407
+ raise TypeError (" the base ring must be a field" )
1408
+ if self .is_zero() or other.is_zero():
1409
+ raise ZeroDivisionError (" division by zero is not valid" )
1410
+ V1 = self ._left_lcm_cofactor(other)
1411
+ L = V1 * self
1412
+ if monic:
1413
+ s = ~ (L.leading_coefficient())
1414
+ L = s * L
1415
+ V1 = s * V1
1416
+ return L, V1, L // other
1417
+
1418
+ def _right_lcm_cofactor (self , other ):
1419
+ R = self ._parent
1420
+ U = R.one()
1421
+ G = self
1422
+ V1 = R.zero()
1423
+ V3 = other
1424
+ while not V3.is_zero():
1425
+ Q, R = G.left_quo_rem(V3)
1426
+ T = U - V1* Q
1427
+ U = V1
1428
+ G = V3
1429
+ V1 = T
1430
+ V3 = R
1431
+ return V1
1432
+
1433
+ @coerce_binop
1434
+ def right_xlcm (self , other , monic = True ):
1435
+ if self .base_ring() not in Fields:
1436
+ raise TypeError (" the base ring must be a field" )
1437
+ if self .is_zero() or other.is_zero():
1438
+ raise ZeroDivisionError (" division by zero is not valid" )
1439
+ V1 = self ._right_lcm_cofactor(other)
1440
+ L = self * V1
1441
+ if monic:
1442
+ s = self ._parent.twist_map(- self .degree())(~ (L.leading_coefficient()))
1443
+ L = L * s
1444
+ V1 = V1 * s
1445
+ W1, _ = L.left_quo_rem(other)
1446
+ return L, V1, W1
1447
+
1448
+
1384
1449
@coerce_binop
1385
1450
def left_lcm (self , other , monic = True ):
1386
1451
r """
@@ -1444,21 +1509,10 @@ cdef class SkewPolynomial(AlgebraElement):
1444
1509
raise TypeError (" the base ring must be a field" )
1445
1510
if self .is_zero() or other.is_zero():
1446
1511
raise ZeroDivisionError (" division by zero is not valid" )
1447
- U = self ._parent.one()
1448
- G = self
1449
- V1 = self ._parent.zero()
1450
- V3 = other
1451
- while not V3.is_zero():
1452
- Q, R = G.right_quo_rem(V3)
1453
- T = U - Q* V1
1454
- U = V1
1455
- G = V3
1456
- V1 = T
1457
- V3 = R
1458
- V1 = V1 * self
1512
+ L = self ._left_lcm_cofactor(other) * self
1459
1513
if monic:
1460
- V1 = V1 .right_monic()
1461
- return V1
1514
+ L = L .right_monic()
1515
+ return L
1462
1516
1463
1517
@coerce_binop
1464
1518
def right_lcm (self , other , monic = True ):
@@ -1539,22 +1593,10 @@ cdef class SkewPolynomial(AlgebraElement):
1539
1593
raise TypeError (" the base ring must be a field" )
1540
1594
if self .is_zero() or other.is_zero():
1541
1595
raise ZeroDivisionError (" division by zero is not valid" )
1542
- R = self .parent()
1543
- U = R.one()
1544
- G = self
1545
- V1 = R.zero()
1546
- V3 = other
1547
- while not V3.is_zero():
1548
- Q, R = G.left_quo_rem(V3)
1549
- T = U - V1* Q
1550
- U = V1
1551
- G = V3
1552
- V1 = T
1553
- V3 = R
1554
- V1 = self * V1
1596
+ L = self * self ._right_lcm_cofactor(other)
1555
1597
if monic:
1556
- V1 = V1 .left_monic()
1557
- return V1
1598
+ L = L .left_monic()
1599
+ return L
1558
1600
1559
1601
def _repr_ (self , name = None ):
1560
1602
r """
0 commit comments