@@ -2228,6 +2228,68 @@ cdef class Field(PrincipalIdealDomain):
2228
2228
a = a.monic()
2229
2229
return a
2230
2230
2231
+ def _xgcd_univariate_polynomial (self , a , b ):
2232
+ """
2233
+ Return an extended gcd of ``a`` and ``b``.
2234
+
2235
+ INPUT:
2236
+
2237
+ - ``a``, ``b`` -- two univariate polynomials
2238
+
2239
+ OUTPUT:
2240
+
2241
+ A tuple ``(d, u, v)`` of polynomials such that ``d`` is the
2242
+ greatest common divisor (monic or zero) of ``a`` and ``b``,
2243
+ and ``u``, ``v`` satisfy ``d = u*a + v*b``.
2244
+
2245
+ .. WARNING:
2246
+
2247
+ If the base ring is inexact, the results may not be
2248
+ entirely stable.
2249
+
2250
+ ALGORITHM:
2251
+
2252
+ This uses the extended Euclidean algorithm; see for example
2253
+ [Cohen]_, Algorithm 3.2.2.
2254
+
2255
+ REFERENCES:
2256
+
2257
+ .. [Cohen] H. Cohen, A Course in Computational Algebraic
2258
+ Number Theory. Graduate Texts in Mathematics 138.
2259
+ Springer-Verlag, 1996.
2260
+
2261
+ TESTS::
2262
+
2263
+ sage: for A in (RR, CC, QQbar):
2264
+ ....: g = A._xgcd_univariate_polynomial
2265
+ ....: R.<x> = A[]
2266
+ ....: z, h = R(0), R(1/2)
2267
+ ....: assert(g(2*x, 2*x^2) == (x, h, z) and
2268
+ ....: g(z, 2*x) == (x, z, h) and
2269
+ ....: g(2*x, z) == (x, h, z) and
2270
+ ....: g(z, z) == (z, z, z))
2271
+
2272
+ """
2273
+ R = a.parent()
2274
+ zero = R.zero()
2275
+ if not b:
2276
+ if not a:
2277
+ return (zero, zero, zero)
2278
+ c = ~ a.leading_coefficient()
2279
+ return (c* a, R(c), zero)
2280
+ elif not a:
2281
+ c = ~ b.leading_coefficient()
2282
+ return (c* b, zero, R(c))
2283
+ (u, d, v1, v3) = (R.one(), a, zero, b)
2284
+ while v3:
2285
+ q, r = d.quo_rem(v3)
2286
+ (u, d, v1, v3) = (v1, v3, u - v1* q, r)
2287
+ v = (d - a* u) // b
2288
+ if d:
2289
+ c = ~ d.leading_coefficient()
2290
+ d, u, v = c* d, c* u, c* v
2291
+ return d, u, v
2292
+
2231
2293
2232
2294
cdef class Algebra(Ring):
2233
2295
"""
0 commit comments