@@ -237,6 +237,35 @@ function deflated_gcd(p1::APL{T}, p2::APL{S}, algo) where {T, S}
237
237
end
238
238
end
239
239
240
+ function Base. gcdx (p1:: APL{T} , p2:: APL{S} , algo:: AbstractUnivariateGCDAlgorithm = GeneralizedEuclideanAlgorithm ()) where {T, S}
241
+ i1, i2, num_common = _extracted_variable (p1, p2)
242
+ R = MA. promote_operation (gcd, typeof (p1), typeof (p2))
243
+ if iszero (i1)
244
+ if iszero (i2)
245
+ return univariate_gcdx (p1, p2, algo)
246
+ else
247
+ if isapproxzero (p1)
248
+ return zero (R), one (R), convert (R, p2)
249
+ end
250
+ error (" Not implemented yet" )
251
+ end
252
+ else
253
+ if iszero (i2)
254
+ if isapproxzero (p2)
255
+ return one (R), zero (R), convert (R, p1)
256
+ end
257
+ error (" Not implemented yet" )
258
+ else
259
+ if num_common > 1
260
+ @assert i1 == i2
261
+ error (" Not implemented yet" )
262
+ else
263
+ return univariate_gcdx (p1, p2, algo)
264
+ end
265
+ end
266
+ end
267
+ end
268
+
240
269
# Returns first element in the union of two decreasing vectors
241
270
function _extracted_variable (p1, p2)
242
271
v1 = variables (p1)
@@ -324,6 +353,18 @@ which is a subtype of [`AbstractUnivariateGCDAlgorithm`](@ref).
324
353
"""
325
354
function primitive_univariate_gcd end
326
355
356
+ function not_divided_error (u, v)
357
+ error (
358
+ " Polynomial `$v ` of degree `$(maxdegree (v)) ` and effective" ,
359
+ " variables `$(effective_variables (v)) ` does not divide" ,
360
+ " polynomial `$u ` of degree `$(maxdegree (u)) ` and effective" ,
361
+ " variables `$(effective_variables (u)) `. Did you call" ,
362
+ " `univariate_gcd` with polynomials with more than one" ,
363
+ " variable in common ? If yes, call `gcd` instead, otherwise," ,
364
+ " please report this." ,
365
+ )
366
+ end
367
+
327
368
# If `p` and `q` do not have the same time then the local variables `p` and `q`
328
369
# won't be type stable.
329
370
function primitive_univariate_gcd (p:: APL , q:: APL , algo:: GeneralizedEuclideanAlgorithm )
@@ -343,15 +384,7 @@ function primitive_univariate_gcd(p::APL, q::APL, algo::GeneralizedEuclideanAlgo
343
384
end
344
385
divided, r = pseudo_rem (u, v, algo)
345
386
if ! divided
346
- error (
347
- " Polynomial `$v ` of degree `$(maxdegree (v)) ` and effective" ,
348
- " variables `$(effective_variables (v)) ` does not divide" ,
349
- " polynomial `$u ` of degree `$(maxdegree (u)) ` and effective" ,
350
- " variables `$(effective_variables (u)) `. Did you call" ,
351
- " `univariate_gcd` with polynomials with more than one" ,
352
- " variable in common ? If yes, call `gcd` instead, otherwise," ,
353
- " please report this." ,
354
- )
387
+ not_divided_error (u, v)
355
388
end
356
389
if ! algo. primitive_rem
357
390
r = primitive_part (r, algo):: R
@@ -360,6 +393,42 @@ function primitive_univariate_gcd(p::APL, q::APL, algo::GeneralizedEuclideanAlgo
360
393
end
361
394
end
362
395
396
+ function primitive_univariate_gcdx (u0:: APL , v0:: APL , algo:: GeneralizedEuclideanAlgorithm )
397
+ if maxdegree (u0) < maxdegree (v0)
398
+ a, b, g = primitive_univariate_gcdx (v0, u0, algo)
399
+ return b, a, g
400
+ end
401
+ R = MA. promote_operation (gcd, typeof (u0), typeof (v0))
402
+ u = convert (R, u0)
403
+ v = convert (R, v0)
404
+ if isapproxzero (v)
405
+ return one (R), zero (R), u
406
+ elseif isconstant (v)
407
+ # `p` and `q` are primitive so if one of them is constant, it cannot
408
+ # divide the content of the other one.
409
+ return zero (R), one (R), v
410
+ end
411
+ # p * u = q * v + r
412
+ p, q, r = pseudo_divrem (u, v, algo)
413
+ if iszero (q)
414
+ not_divided_error (u, v)
415
+ end
416
+ if iszero (r)
417
+ # Shortcut, does not change the output
418
+ return zero (R), one (R), v
419
+ end
420
+ # TODO
421
+ # if !algo.primitive_rem
422
+ # r = primitive_part(r, algo)::R
423
+ # end
424
+ # a * v + b * r = g
425
+ # a * v + b * (p * u - q * v) = g
426
+ # b * p * u + (a - b * q) * v = g
427
+ a, b, g = primitive_univariate_gcdx (v, r, algo)
428
+ return p * b, (a - b * q), g
429
+ end
430
+
431
+
363
432
function primitive_univariate_gcd (p:: APL , q:: APL , :: SubresultantAlgorithm )
364
433
error (" Not implemented yet" )
365
434
end
@@ -403,6 +472,21 @@ function univariate_gcd(::Field, p1::APL, p2::APL, algo::AbstractUnivariateGCDAl
403
472
return primitive_univariate_gcd (p1, p2, algo)
404
473
end
405
474
475
+ function univariate_gcdx (p1:: APL{S} , p2:: APL{T} , algo:: AbstractUnivariateGCDAlgorithm ) where {S,T}
476
+ return univariate_gcdx (algebraic_structure (S, T), p1, p2, algo)
477
+ end
478
+ function univariate_gcdx (:: UFD , p1:: APL , p2:: APL , algo:: AbstractUnivariateGCDAlgorithm )
479
+ f1, g1 = primitive_part_content (p1, algo)
480
+ f2, g2 = primitive_part_content (p2, algo)
481
+ a, b, pp = primitive_univariate_gcdx (f1, f2, algo)
482
+ gg = _gcd (g1, g2, algo)# ::MA.promote_operation(gcd, typeof(g1), typeof(g2))
483
+ # Multiply each coefficient by the gcd of the contents.
484
+ return g2 * a, g1 * b, g1 * g2 * mapcoefficientsnz (Base. Fix1 (* , gg), pp)
485
+ end
486
+ function univariate_gcdx (:: Field , p1:: APL , p2:: APL , algo:: AbstractUnivariateGCDAlgorithm )
487
+ return primitive_univariate_gcdx (p1, p2, algo)
488
+ end
489
+
406
490
_gcd (a:: APL , b:: APL , algo) = gcd (a, b, algo)
407
491
_gcd (a, b:: APL , algo) = gcd (a, b, algo)
408
492
_gcd (a:: APL , b, algo) = gcd (a, b, algo)
0 commit comments