@@ -237,6 +237,35 @@ function deflated_gcd(p1::APL{T}, p2::APL{S}, algo) where {T, S}
237237 end
238238end
239239
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+
240269# Returns first element in the union of two decreasing vectors
241270function _extracted_variable (p1, p2)
242271 v1 = variables (p1)
@@ -324,6 +353,18 @@ which is a subtype of [`AbstractUnivariateGCDAlgorithm`](@ref).
324353"""
325354function primitive_univariate_gcd end
326355
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+
327368# If `p` and `q` do not have the same time then the local variables `p` and `q`
328369# won't be type stable.
329370function primitive_univariate_gcd (p:: APL , q:: APL , algo:: GeneralizedEuclideanAlgorithm )
@@ -343,15 +384,7 @@ function primitive_univariate_gcd(p::APL, q::APL, algo::GeneralizedEuclideanAlgo
343384 end
344385 divided, r = pseudo_rem (u, v, algo)
345386 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)
355388 end
356389 if ! algo. primitive_rem
357390 r = primitive_part (r, algo):: R
@@ -360,6 +393,42 @@ function primitive_univariate_gcd(p::APL, q::APL, algo::GeneralizedEuclideanAlgo
360393 end
361394end
362395
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+
363432function primitive_univariate_gcd (p:: APL , q:: APL , :: SubresultantAlgorithm )
364433 error (" Not implemented yet" )
365434end
@@ -403,6 +472,21 @@ function univariate_gcd(::Field, p1::APL, p2::APL, algo::AbstractUnivariateGCDAl
403472 return primitive_univariate_gcd (p1, p2, algo)
404473end
405474
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+
406490_gcd (a:: APL , b:: APL , algo) = gcd (a, b, algo)
407491_gcd (a, b:: APL , algo) = gcd (a, b, algo)
408492_gcd (a:: APL , b, algo) = gcd (a, b, algo)
0 commit comments